Skip to Content
GuidesAuthorizationCustom JWT Claims

Custom JWT Claims

Custom claims allow you to embed additional data directly in the JWT access token issued by Auris. Instead of making a separate API call to fetch user data after authentication, your backend can read the claim directly from the verified token.

Custom claims are configured per application in the Console and resolved at token issuance time.


When to Use Custom Claims

Custom claims are useful when:

  • Your backend needs user metadata (department, plan, tenant ID) on every request without an extra lookup
  • A third-party API expects specific claims in the JWT (e.g., a payment gateway expecting a subscription_tier claim)
  • You want to encode permission or role information into the token for stateless authorization
  • Different applications in your tenant need different user data in their tokens

Claims in access tokens are readable by anyone who holds the token. Do not embed sensitive data (passwords, secrets, financial data) in JWT claims. Claims are also included in the token size — large payloads increase the size of every HTTP Authorization header.


Claim Types

Auris supports four claim value types:

STATIC

A fixed string, number, or boolean value — the same for every user who receives a token from this application.

{ "environment": "production" } { "app_version": "2.1.0" } { "feature_flag_x": true }

Use when: You need to identify which application issued the token, or embed configuration values that do not change per user.

USER_ATTRIBUTE

A value drawn from the authenticated user’s profile. The available attributes are:

Attribute KeyDescription
emailUser’s primary email address
firstNameUser’s first name
lastNameUser’s last name
usernameUser’s username (Keycloak username)
phoneNumberUser’s verified phone number
metadataThe entire user metadata JSON object
metadata.{key}A specific key from the user metadata JSON
{ "user_email": "[email protected]" } { "department": "engineering" } // via metadata.department { "phone": "+15551234567" }

Use when: Your backend or downstream service needs user identity data available in the token without additional API calls.

ROLE_BASED

A different value returned depending on which roles the user holds. The first matching role wins. A fallback value is returned if no role matches.

// Configuration: { "plan": { "Administrator": "enterprise", "Pro User": "pro", "default": "free" } } // Resulting claim for a Pro User: { "plan": "pro" } // Resulting claim for an Administrator: { "plan": "enterprise" } // Resulting claim for a user with no matching role: { "plan": "free" }

Use when: Different roles in your system correspond to feature tiers, access levels, or pricing plans that downstream services need to act on.

EXPRESSION

A computed value using a simple expression evaluated against the user context. Expressions have access to user, roles, and metadata variables.

// Expressions are JavaScript-like (evaluated in a sandboxed context) user.email.split('@')[1] // => "acme.com" (email domain) roles.includes('Administrator') // => true | false metadata.orgId ?? 'default' // => orgId from metadata or "default" user.firstName + ' ' + user.lastName // => "Alice Smith"

Expressions are evaluated in a sandboxed context. They have no access to require, import, process, eval, network calls, or file system operations.

Use when: You need a derived or computed value that is not directly available as a user attribute.


Reserved Claims

The following claim keys are reserved by Auris and the OAuth2/OIDC specification. They cannot be overridden by custom claims:

Reserved ClaimDescription
issToken issuer (your Auris domain)
subSubject — the user’s ID
audAudience — your client ID
expExpiry timestamp
iatIssued-at timestamp
jtiJWT ID (unique token identifier)
typeToken type (user or m2m)
scopeGranted OAuth scopes
rolesArray of the user’s role names
emailUser’s email (from standard OIDC claims)
nameUser’s display name

Attempting to create a custom claim with a reserved key returns a validation error.


Console Setup

Open Custom Claims configuration

In the Auris Console, navigate to Applications → select your application → Custom Claims tab.

Add a claim

Click Add Claim and configure:

  • Claim Key: The JSON key in the token (e.g., department, plan, tenant_id)
  • Claim Type: STATIC, USER_ATTRIBUTE, ROLE_BASED, or EXPRESSION
  • Value: Type-specific value configuration

Preview the claim

Use the Preview button to resolve the claim for a specific user before saving. This calls the preview API endpoint with the user’s actual data.

Activate the claim

Toggle Active on the claim. Deactivated claims are skipped during token issuance (useful for testing without deleting the configuration).


Examples

Example 1: Embedding User Department

Requirement: Your backend needs to know the user’s department on every request.

Setup:

  • Claim Key: department
  • Type: USER_ATTRIBUTE
  • Attribute: metadata.department

Resulting token:

{ "sub": "user-id-123", "email": "[email protected]", "roles": ["Employee"], "department": "Engineering", ...standard claims... }

Backend usage:

// No additional API call needed — department is in the token const { department } = verifyToken(req.headers.authorization.slice(7)) console.log(department) // "Engineering"

Example 2: Subscription Plan Badge

Requirement: A third-party analytics tool expects a subscription_plan claim indicating the user’s tier.

Setup:

  • Claim Key: subscription_plan
  • Type: ROLE_BASED
  • Mapping:
    • Enterprise Customerenterprise
    • Pro Customerpro
    • Free Tierfree
    • Default → free

Resulting token for an Enterprise Customer:

{ "sub": "user-id-456", "roles": ["Enterprise Customer", "Invoice Viewer"], "subscription_plan": "enterprise", ... }

Example 3: Email Domain Extraction

Requirement: A multi-tenant backend routes requests based on the user’s email domain (company).

Setup:

  • Claim Key: email_domain
  • Type: EXPRESSION
  • Expression: user.email.split('@')[1]

Resulting token:

{ "sub": "user-id-789", "email": "[email protected]", "email_domain": "contoso.com", ... }

Example 4: Static Application Environment

Requirement: Distinguish tokens from production vs. staging application registrations.

Setup (on the production app):

  • Claim Key: env
  • Type: STATIC
  • Value: production

Setup (on the staging app):

  • Claim Key: env
  • Type: STATIC
  • Value: staging

API Endpoints

GET/api/applications/:id/custom-claimsRequires: view:applications

List all custom claims configured for an application, including their type, value configuration, and active status.

POST/api/applications/:id/custom-claimsRequires: manage:applications

Create a new custom claim. Body: { claimKey: string, valueType: 'STATIC' | 'USER_ATTRIBUTE' | 'ROLE_BASED' | 'EXPRESSION', staticValue?: string, userAttribute?: string, roleMapping?: Record<string, string>, expression?: string, isActive?: boolean }.

PATCH/api/applications/:id/custom-claims/:claimIdRequires: manage:applications

Update a custom claim’s configuration or active status.

DELETE/api/applications/:id/custom-claims/:claimIdRequires: manage:applications

Delete a custom claim. Tokens issued after deletion will not contain the claim. Tokens issued before deletion remain unchanged until they expire.

POST/api/applications/:id/custom-claims/previewRequires: view:applications

Preview claim resolution for a specific user. Body: { userId: string }. Returns the resolved claim values as they would appear in a token for that user.


Token Size Considerations

Each custom claim adds to the size of every JWT access token issued by the application. JWT tokens are sent as HTTP headers on every authenticated request. Keep claims concise:

ConsiderationGuidance
String valuesKeep under 100 characters per claim
Avoid full metadata objectsUse metadata.{key} to extract specific fields, not the entire metadata object
Number of claimsAim for fewer than 10 custom claims per application
Role-based claim valuesUse short identifiers (pro, free) not full descriptions

Oversized tokens can cause 431 Request Header Fields Too Large errors on some proxies and load balancers (typically with headers over 8KB).