Dosu LogoDosu Logo
Ask
Join our Discord
Organization avatar
OAuth2 ProxyPublic
OAuth2 Proxy
Documents
Entra ID Authentication
Envoy and Istio Integration
GitHub Provider Session Enrichment
JWT Issuer Configuration
Nginx OAuth2-Proxy Integration
oauth2-proxy Configuration
OAuth2-Proxy Group Authorization
OAuth2-Proxy Header Injection
OAuth2-Proxy Session Claims
OIDC Refresh Token Implementation
Redis Session Management
Token Refresh Concurrency
Traefik OAuth2-Proxy Integration
DocumentsOAuth2 Proxy
OAuth2-Proxy Session Claims
OAuth2-Proxy Session Claims
Type
Topic
Status
Published
Created
Jul 10, 2026
Updated
Jul 10, 2026

OAuth2-Proxy Session Claims#

OAuth2-Proxy extracts claims from OIDC ID tokens (and optionally a userinfo/profile endpoint) during token redemption, stores them in a SessionState, and makes them available for authorization checks and upstream header injection throughout the request lifecycle.

Session State Structure#

Claims land in SessionState, the central struct serialized to the session store. The claim-bearing fields are:

FieldTypeSession key
Userstringconfigured by UserClaim (default sub)
Emailstringconfigured by EmailClaim
Groups[]stringconfigured by GroupsClaim
PreferredUsernamestringalways populated from preferred_username
AdditionalClaimsmap[string]interface{}arbitrary extra claims

Sessions are serialized with MessagePack and optionally LZ4-compressed before encryption .

Claim Extraction Pipeline#

1. Token redemption → buildSessionFromClaims#

After a successful code exchange, buildSessionFromClaims in providers/provider_data.go drives all claim population:

  1. Creates a ClaimExtractor from the raw ID token JWT payload.
  2. Iterates over UserClaim, EmailClaim, GroupsClaim, and preferred_username, calling GetClaimInto to coerce each claim into the target Go type.
  3. Calls extractAdditionalClaims for any claim names listed in ProviderData.AdditionalClaims, storing results as raw interface{} values in SessionState.AdditionalClaims.
  4. Optionally checks email_verified .

2. ClaimExtractor — ID token + profile URL fallback#

NewClaimExtractor (pkg/providers/util/claim_extractor.go) parses the JWT payload and creates a lazy-loading extractor. GetClaim tries the ID token first; only if the claim is absent does it fetch the profile/userinfo URL. The profile response may be plain JSON or a signed JWT (application/jwt) . JSON path notation (dotted keys) is supported for nested claim lookup .

SkipClaimsFromProfileURL on ProviderData suppresses the profile URL fetch entirely .

3. Type coercion — CoerceClaim#

CoerceClaim in pkg/util/util.go handles the type mismatch between JSON and Go:

  • *string — uses cast.ToStringE; non-string scalars are JSON-marshalled to a string .
  • *[]string — wraps a scalar in a single-element slice before converting, so a plain string "admin" and an array ["admin"] both produce []string{"admin"} . Complex objects (maps, etc.) are JSON-serialised per element.
  • *bool — uses cast.ToBool.

This means GroupsClaim is always []string regardless of whether the IdP sends a string, array of strings, or array of mixed types .

Claim Configuration (ProviderData)#

Key fields on ProviderData:

FieldPurpose
UserClaimClaim mapped to SessionState.User; defaults to "sub"
EmailClaimClaim mapped to SessionState.Email
GroupsClaimClaim mapped to SessionState.Groups; omit to skip group extraction
AdditionalClaimsSlice of extra claim names stored in AdditionalClaims map
SkipClaimsFromProfileURLPrevent any fetch to the profile/userinfo URL

Token Refresh#

During token refresh, redeemRefreshToken calls createSession and selectively overwrites session claim fields only if a new ID token is present — otherwise the previous Email, User, Groups, and PreferredUsername are preserved .

Consuming Claims — GetClaim and Header Injection#

SessionState.GetClaim(claim string) []string is the unified accessor. Named fields (access_token, id_token, email, user, groups, preferred_username, etc.) are handled by a switch; any other name falls through to getAdditionalClaim, which calls CoerceClaim to convert AdditionalClaims[claim] to []string.

The header injector (pkg/header/injector.go) calls session.GetClaim(source.Claim) to retrieve values, then adds one header per element (supporting multi-value claims like groups). Optional Prefix and BasicAuthPassword modes are also supported .

Key Source Files#

FilePurpose
pkg/apis/sessions/session_state.goSessionState struct, serialization, GetClaim
providers/provider_data.gobuildSessionFromClaims, extractAdditionalClaims, ProviderData config
pkg/providers/util/claim_extractor.goClaimExtractor interface, ID token parsing, profile URL fallback
pkg/util/util.goCoerceClaim, toStringSlice array coercion
providers/oidc.goOIDC flow: Redeem, RefreshSession, createSession
pkg/header/injector.goClaim → upstream request header injection
providers/provider_data_test.goTests covering claim coercion edge cases (numeric, complex, missing)