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:
| Field | Type | Session key |
|---|---|---|
User | string | configured by UserClaim (default sub) |
Email | string | configured by EmailClaim |
Groups | []string | configured by GroupsClaim |
PreferredUsername | string | always populated from preferred_username |
AdditionalClaims | map[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:
- Creates a
ClaimExtractorfrom the raw ID token JWT payload. - Iterates over
UserClaim,EmailClaim,GroupsClaim, andpreferred_username, callingGetClaimIntoto coerce each claim into the target Go type. - Calls
extractAdditionalClaimsfor any claim names listed inProviderData.AdditionalClaims, storing results as rawinterface{}values inSessionState.AdditionalClaims. - 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β usescast.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β usescast.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:
| Field | Purpose |
|---|---|
UserClaim | Claim mapped to SessionState.User; defaults to "sub" |
EmailClaim | Claim mapped to SessionState.Email |
GroupsClaim | Claim mapped to SessionState.Groups; omit to skip group extraction |
AdditionalClaims | Slice of extra claim names stored in AdditionalClaims map |
SkipClaimsFromProfileURL | Prevent 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#
| File | Purpose |
|---|---|
pkg/apis/sessions/session_state.go | SessionState struct, serialization, GetClaim |
providers/provider_data.go | buildSessionFromClaims, extractAdditionalClaims, ProviderData config |
pkg/providers/util/claim_extractor.go | ClaimExtractor interface, ID token parsing, profile URL fallback |
pkg/util/util.go | CoerceClaim, toStringSlice array coercion |
providers/oidc.go | OIDC flow: Redeem, RefreshSession, createSession |
pkg/header/injector.go | Claim β upstream request header injection |
providers/provider_data_test.go | Tests covering claim coercion edge cases (numeric, complex, missing) |