¾öA JWT Claim Headers | Pomerium
Skip to main content

JWT Claim Headers

Summary​

The JWT Claims Headers setting allows you to pass specific user session data to upstream applications as HTTP request headers. Claims forwarded with JWT Claims Headers are not signed by the Authorization Service (unlike the X-Pomerium-Jwt-Assertion header).

Forwarding a claim with JWT Claims Headers adds the claim to the X-Pomerium-Jwt-Assertion header if the claim is not already included in the assertion header. Both JWT Claims Headers and the signed assertion header are forwarded with the pass_identity_headers setting.

How to configure​

Config file keysEnvironment variablesTypeUsage
jwt_claims_headersJWT_CLAIMS_HEADERSmap of string (or comma-separated string)optional

Examples​

jwt_claims_headers:
X-Email: email
X-Username: user

Format JWT Claims Headers​

Any claim in Pomerium's session JWT can be placed into a corresponding header and the JWT payload for upstream consumption. Claim information is sourced from your identity provider and Pomerium's own session metadata.

The header will have the following format:

X-Pomerium-Claim-{Name}, where {Name} is the name of the requested claim. Underscores will replace dashes. For example, X-Pomerium-Claim-Given-Name.

Customize header names​

The JWT Claims Headers setting allows you to customize claim headers with a nested object:

jwt_claims_headers:
X-Email: email
X-Username: user

The JSON payload from this example would look similar to the sample data below:

"X-Email": [
"user@example.com"
],
"X-Username": [
"user"
]

Use this option if you previously relied on x-pomerium-authenticated-user-{email|user-id|groups}.

Standard claims​

Every JWT that Pomerium issues carries a fixed set of claims describing the session. These claims are always present in the signed assertion header (X-Pomerium-Jwt-Assertion), whether or not you configure jwt_claims_headers. Naming one of them in jwt_claims_headers also copies its value into an X-Pomerium-Claim-* header.

ClaimDescription
issThe issuer. By default this is the route's hostname. If jwt_issuer_format is set to uri, it is https://HOSTNAME/ instead.
audThe audience: the route's hostname.
jtiA unique identifier for the token (a UUID). A new value is generated for every token.
iatThe time the token was issued, in seconds since the Unix epoch.
expThe time the token expires, in seconds since the Unix epoch. Pomerium sets this to five minutes after iat.
subThe subject: the user's ID. This is the same value as user.
userThe user's ID, as assigned by the identity provider.
emailThe user's email address.
groupsThe user's groups, listing both group IDs and group names. When the user has no groups this is an empty list rather than null.
sidThe session ID.
nameThe user's name.

A standard claim always takes precedence: an identity provider claim of the same name cannot override it.

Additional claims from your identity provider​

Beyond the standard claims, you can forward any claim that your identity provider supplies about the user.

When a user logs in, Pomerium collects claims from two places and stores them on the session:

  • the ID token returned from the identity provider's token endpoint, and
  • the response from the identity provider's UserInfo endpoint.

Any claim found in either is available to jwt_claims_headers by name. The OAuth access token is not read for claims; a claim placed only in the access token has no effect.

To forward an additional claim, first configure your identity provider to include it in the ID token or return it from the UserInfo endpoint, then name the claim in jwt_claims_headers:

jwt_claims_headers:
X-Department: department

Pomerium transforms claim values before forwarding them:

  • Nested claims are flattened to dot-separated names. A claim such as { "resource_access": { "app": { "roles": [...] } } } becomes resource_access.app.roles; refer to it by that name.
  • A multi-valued claim is forwarded as a single comma-separated string. For example, a claim whose value is ["a", "b"] is forwarded as a,b.
  • Only scalar values — strings, numbers, and booleans — are forwarded. Entries whose value is an object are skipped.

To pass static values as request headers to the upstream service, see Set Request Headers.

ÿÿÿÿ