Header / Gateway Authentication
Framework M supports header-based authentication for enterprise deployments where an upstream API gateway (such as Nginx, Traefik, Envoy, Kong, or an OIDC-aware proxy) authenticates the request and forwards identity metadata via HTTP headers.
This approach is standards-aligned, stateless, and avoids proprietary IAM protocols. It is commonly used together with an external identity provider (e.g. Keycloak, Auth0, Okta) that issues tokens and with a gateway that validates those tokens and sets identity headers.
Authentication Strategy
The HeaderAuth strategy hydrates UserContext from trusted headers. It does not
perform any network calls; the upstream gateway is responsible for token validation
and tenant resolution.
Expected Headers
| Header | Description |
|---|---|
x-user-id | User's primary identity. |
x-service-id | Service identity (used when no user is present). |
x-email | User's email address. |
x-user-roles | Comma-separated list of roles. |
x-scopes | Comma-separated list of service scopes. |
x-tenant-id | Verified primary tenant ID(s). |
x-active-tenant-id | Selector/Hint passed by the user to request a specific tenant context. |
x-user-attributes | Base64-encoded JSON string containing user metadata. |
x-tenant-attributes | Base64-encoded JSON string containing tenant-level metadata. |
Configuration
Header auth is enabled by including it in the authentication chain.
Global Configuration (framework_config.toml)
[auth]
strategies = ["jwt", "header"]
Reverse Proxy / Gateway Example
A typical Nginx configuration that validates a JWT and forwards identity headers:
location /api/ {
auth_jwt "Framework M API";
auth_jwt_key_file /etc/nginx/jwks.json;
proxy_set_header X-User-ID $jwt_claim_sub;
proxy_set_header X-Email $jwt_claim_email;
proxy_set_header X-User-Roles $jwt_claim_roles;
proxy_set_header X-Tenant-ID $jwt_claim_tenant_id;
proxy_pass http://framework-m-backend:8888;
}
Token Introspection Example
When the gateway cannot validate tokens locally, Framework M can introspect opaque
Bearer tokens remotely and optionally call the OIDC UserInfo endpoint if the
introspection response only contains active: true/false.
[auth]
strategies = ["jwt", "remote_introspection", "header"]
[auth.remote_introspection]
enabled = true
endpoint = "https://idp.example.com/oauth/introspect"
# Optional: fetch claims from UserInfo when introspection is sparse
userinfo_endpoint = "https://idp.example.com/oauth/userinfo"
client_id = "framework-m"
client_secret = "..."
timeout_seconds = 2.0
Usage in Code
Authentication Chain
The header strategy is automatically included in the authentication chain when configured.
from framework_m_standard.adapters.auth.strategies import create_auth_chain_from_config
# Factory creates the chain including HeaderAuth if set in config
auth_chain = create_auth_chain_from_config(jwt_secret="...")
# Middleware uses it to hydrate request.state.user
user_context = await auth_chain.authenticate(request.headers)
Context Mapping
The adapter maps headers to the UserContext as follows:
- Identity:
idis taken fromx-user-id(if present) orx-service-id. - Tenants:
tenantsis a list starting withx-active-tenant-id, followed by any additional IDs inx-tenant-id. - Attributes:
x-user-attributesare decoded and merged directly into the root ofUserContext.attributes.x-tenant-attributesare decoded and placed under thetenant_attributeskey inUserContext.attributes.
- Metadata:
is_serviceandscopesare added toattributesif a service identity is used.