Request Authentication and Authorization Flows in INFINI Gateway

INFINI Gateway processes request authentication and authorization through a sequential pipeline of security filters that validate credentials against static user maps, LDAP directories, or API keys, then persist identity metadata in the request context for downstream access control decisions.

The infinilabs/gateway repository handles HTTP request authentication and authorization via configurable filter chains that execute early in the request lifecycle. Each filter can terminate the request with a 401 Unauthorized response or pass control forward while injecting user identity information—such as user ID, username, and role assignments—into the shared fasthttp.RequestCtx for later authorization checks.

Authentication Filter Architecture

INFINI Gateway organizes security logic into discrete filter plugins that operate on the fasthttp.RequestCtx object. When a request enters a configured flow, the gateway executes filters in declaration order, allowing each filter to inspect headers, validate credentials, or modify the request context. Authentication filters typically appear first in the chain, ensuring that only verified requests reach upstream Elasticsearch clusters or other backend services.

Built-in Authentication Methods

Basic Authentication Filter

The basic_auth filter, implemented in proxy/filters/security/auth/basic_auth.go, validates credentials against a static map of usernames and passwords defined in the gateway configuration.

The filter extracts the Authorization header using ctx.Request.Header.PeekAny(fasthttp.AuthHeaderKeys), then parses the "Basic " prefix via an internal parseBasicAuth function that base64-decodes the value and splits it into username and password components. The decoded username serves as a key into the ValidUsers configuration map; if the password matches the configured value, the filter returns silently and the request continues. On failure, the filter sends a 401 Unauthorized response including a WWW-Authenticate header and terminates processing.

flow:
  - name: secure_flow
    filter:
      - basic_auth:
          valid_users:
            admin: secret123
            operator: pass456

LDAP Authentication Filter

For enterprise deployments, the ldap_auth filter in proxy/filters/security/ldap/ldap.go delegates credential validation to external LDAP servers and optionally enforces group membership requirements.

The filter first checks for an ApiKey authorization type when bypass_api_key is enabled, allowing specific clients to skip LDAP validation. For standard authentication, it calls ldapQuery.Authenticate from the underlying LDAP strategy in the infini.sh/framework/lib/guardian/auth/strategies/ldap library. Upon successful authentication, the filter extracts the user's directory groups and stores three critical values in the request context:

ctx.Set("user_id", user.GetID())
ctx.Set("user_name", user.GetUserName())
ctx.Set("user_roles", common.GetLDAPGroupsMappingRoles(user.GetGroups()))

If the configuration specifies require_group: true and the user lacks group memberships, the filter returns 401 with an explanatory error body.

Authorization and Role-Based Access Control

While authentication filters establish identity, authorization logic typically executes in subsequent filters or custom plugins that read the stored context values.

Context Propagation Mechanism

All filters share the same fasthttp.RequestCtx instance throughout the request lifecycle. When an authentication filter writes user_id, user_name, or user_roles using ctx.Set(), downstream filters retrieve these values with ctx.Get() to make authorization decisions. This design enables fine-grained access control based on cluster permissions, index-level restrictions, or custom business rules implemented in common/role_mapping.go.

The current implementation of common.GetLDAPGroupsMappingRoles in common/role_mapping.go provides a placeholder mapping that returns a slice containing "admin" for all authenticated users, though production deployments typically extend this to map specific LDAP groups to gateway roles.

Building Custom Authorization Filters

Developers can implement role-based access control by creating filters that inspect the user_roles context value. The following example demonstrates a custom filter that validates admin privileges before allowing access to sensitive endpoints:

type RoleCheck struct {
    RequiredRole string `config:"required_role"`
}

func (rc *RoleCheck) Name() string { return "role_check" }

func (rc *RoleCheck) Filter(ctx *fasthttp.RequestCtx) {
    roles := ctx.Get("user_roles")
    if roles == nil {
        ctx.Error(fasthttp.StatusMessage(fasthttp.StatusForbidden), fasthttp.StatusForbidden)
        return
    }
    for _, r := range roles.([]string) {
        if r == rc.RequiredRole {
            return // authorized
        }
    }
    ctx.Error(fasthttp.StatusMessage(fasthttp.StatusForbidden), fasthttp.StatusForbidden)
}

Register this filter in gateway.yml after the authentication step:

flow:
  - name: admin_flow
    filter:
      - ldap_auth:
          host: ldap.example.com
          bind_dn: cn=service,dc=example,dc=com
          require_group: true
      - role_check:
          required_role: admin

Configuration Patterns

Protecting System Administration APIs

The gateway's built-in REST API can be secured independently using the api.security configuration block:

api:
  enabled: true
  security:
    enabled: true
    username: admin
    password: $[[keystore.API_PASS]]

Upstream Elasticsearch Authentication

When proxying to Elasticsearch clusters that require authentication, the set_basic_auth filter in proxy/filters/security/auth/set_basic_auth.go injects credentials into outbound requests. This filter removes existing authorization headers and calls ctx.Request.SetBasicAuth(filter.Username, filter.Password) to ensure upstream services receive proper credentials.

elasticsearch:
  - name: prod_cluster
    endpoint: https://es.internal:9200
    basic_auth:
      username: gateway_user
      password: $[[keystore.ES_PASS]]

Key Source Files

File Purpose
proxy/filters/security/auth/basic_auth.go Static username/password validation against configured ValidUsers map
proxy/filters/security/auth/set_basic_auth.go Injects Basic Auth headers for upstream service authentication
proxy/filters/security/ldap/ldap.go LDAP integration with group extraction and role mapping
common/role_mapping.go Maps LDAP groups to gateway-specific roles
proxy/output/logging/logging.go Supports RemoveAuthHeaderKey to sanitize logs

Summary

  • INFINI Gateway implements request authentication and authorization through a sequential filter pipeline executing on the fasthttp.RequestCtx object.
  • The basic_auth filter validates credentials against static ValidUsers maps defined in gateway.yml, returning 401 Unauthorized on failure.
  • The ldap_auth filter delegates authentication to external LDAP servers, extracts user groups, and populates user_id, user_name, and user_roles in the request context.
  • Authorization filters retrieve identity metadata via ctx.Get() to enforce fine-grained access control based on LDAP group mappings or custom role assignments.
  • The set_basic_auth filter enables credential injection for upstream Elasticsearch clusters requiring basic authentication.
  • System APIs can be secured independently using the api.security configuration block with keystore-backed passwords.

Frequently Asked Questions

How does INFINI Gateway persist authenticated user information across filters?

The gateway stores identity metadata in the fasthttp.RequestCtx using the Set() method. Authentication filters write user_id, user_name, and user_roles into this context, and downstream filters retrieve these values using ctx.Get("user_roles") to perform authorization checks. This shared context persists throughout the entire request lifecycle.

Can INFINI Gateway authenticate users against multiple LDAP servers simultaneously?

While the current implementation in proxy/filters/security/ldap/ldap.go supports a single LDAP server per filter configuration, you can create multiple flows with distinct ldap_auth filters targeting different hosts. Each flow can apply different LDAP servers to specific routes or endpoints by configuring separate entry points in gateway.yml.

What authentication methods support API key bypass for service accounts?

The ldap_auth filter provides a bypass_api_key configuration option. When enabled, requests containing an Authorization header with the ApiKey type automatically skip LDAP validation and proceed to downstream filters. This allows service accounts to authenticate via API keys while human users use LDAP credentials.

How do I customize the mapping between LDAP groups and gateway roles?

Modify the common.GetLDAPGroupsMappingRoles function in common/role_mapping.go. The current placeholder implementation returns []string{"admin"} for all users, but production deployments should implement logic that maps specific LDAP group distinguished names (DNs) to role strings like "admin", "operator", or "viewer" based on organizational requirements.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →