Configure Identity Provider
Before creating external role mappings, your Identity Provider (IdP) must be configured to include roles in the ID token. This page covers configuration for common providers.
Requirements
For external role mapping to work, your IdP must:
- Include roles in the ID token — Not just the access token
- Use a consistent claim path — Enterprise Stack must know where to find the roles
- Issue roles as an array — Even for single roles
Keycloak
Keycloak includes realm roles by default, but you need to ensure they appear in the ID token.
Step 1: Create Realm Roles
- Go to Realm roles in your realm
- Create roles:
tenant-admin,wallet-operator, etc. - Assign roles to users via Users → Role mapping
Step 2: Configure Client Mappers
Keycloak 26.x requires explicit mappers to include roles in tokens:
- Go to Clients → your-client → Client scopes
- Click on the dedicated scope (e.g.,
your-client-dedicated) - Go to Mappers → Add mapper → By configuration
- Select User Realm Role
- Configure:
| Field | Value |
|---|---|
| Name | realm-roles |
| Token Claim Name | realm_access.roles |
| Add to ID token | ON |
| Add to access token | ON |
Step 3: Verify Token
After login, the ID token should contain:
{
"realm_access": {
"roles": ["tenant-admin", "wallet-operator"]
}
}
Microsoft Entra ID (Azure AD)
Option A: App Roles
- Go to App registrations → your-app → App roles
- Create app roles:
TenantAdmin,WalletOperator - Assign roles via Enterprise applications → Users and groups
Roles appear in the roles claim:
{
"roles": ["TenantAdmin", "WalletOperator"]
}
Option B: Security Groups
- Go to App registrations → your-app → Token configuration
- Add groups claim
- Select Security groups
Groups appear in the groups claim (as GUIDs or names depending on configuration):
{
"groups": ["group-guid-1", "group-guid-2"]
}
When using groups, map the group identifier (GUID or name) as the external role in your mappings.
Okta
Step 1: Create Groups
- Go to Directory → Groups
- Create groups:
TenantAdmins,WalletOperators - Add users to groups
Step 2: Configure Groups Claim
- Go to Applications → your-app → Sign On
- Edit OpenID Connect ID Token
- Add Groups claim:
- Claim name:
groups - Filter: Matches regex
.*(or specific pattern) - Include in: ID Token
- Claim name:
Token includes:
{
"groups": ["TenantAdmins", "WalletOperators"]
}
Alternative: Custom Claims
Use Okta Expression Language for custom role claims:
- Go to Security → API → Authorization Servers
- Select your server → Claims
- Add claim:
- Name:
roles - Value:
Arrays.flatten(getFilteredGroups({"TenantAdmins", "WalletOperators"}, "group.name", 10)) - Include in: ID Token
- Name:
Auth0
Auth0 requires a Rule or Action to add roles to tokens.
Using Actions (Recommended)
- Go to Actions → Flows → Login
- Add a custom action:
exports.onExecutePostLogin = async (event, api) => {
const namespace = 'https://your-app.com/';
// Get user's roles from metadata or app_metadata
const roles = event.user.app_metadata?.roles || [];
// Add to ID token
api.idToken.setCustomClaim(namespace + 'roles', roles);
};
- Assign roles in user
app_metadata:
{
"roles": ["tenant-admin", "wallet-operator"]
}
Token includes:
{
"https://your-app.com/roles": ["tenant-admin", "wallet-operator"]
}
Auth0 requires namespaced custom claims. Configure Enterprise Stack to use the full claim path.
Google Workspace
Google Workspace doesn't natively support roles in OIDC tokens. Options:
- Use Google Groups — Map group membership via directory API
- Custom attributes — Use admin-defined custom attributes
- External service — Use a token exchange or enrichment service
Generic OIDC Provider
For any OIDC provider:
- Check documentation for how to include custom claims in ID tokens
- Create roles/groups in the provider
- Configure claim mapping to include roles in ID token
- Note the claim path for Enterprise Stack configuration
Common claim paths:
roles— Simple array at top levelgroups— Group membershiprealm_access.roles— Keycloak styleresource_access.{client}.roles— Keycloak client roleshttps://namespace/roles— Namespaced custom claims
Verify Token Contents
After configuring your IdP, verify the token contains roles:
Method 1: jwt.io
- Complete an OIDC login
- Capture the ID token
- Paste at jwt.io to decode
Method 2: Enterprise Demo App
- Login via OIDC in the Demo App
- Check "Realm Roles (from IdP)" in auth details
Method 3: Token Introspection
# Decode JWT payload
echo $ID_TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | jq
Enterprise Stack Configuration
Enterprise Stack Configuration
Once your IdP is configured, tell Enterprise Stack where to find the roles.
In auth.conf, add externalRoleExtraction to your OIDC config:
authFlows = [
{
method = "oidc"
config = {
openIdConfigurationUrl = "https://your-idp/.well-known/openid-configuration"
clientId = "your-client-id"
clientSecret = "your-client-secret"
callbackUri = "https://your-enterprise-host/auth/account/oidc/callback"
pkceEnabled = true
externalRoleExtraction = {
enabled = true
realmRolesClaimPath = "realm_access.roles" # Adjust for your IdP
clientRolesClaimPath = "resource_access" # Optional
}
}
success = true
}
]
Configuration Fields
| Field | Default | Description |
|---|---|---|
enabled | false | Extract roles from OIDC tokens |
realmRolesClaimPath | "realm_access.roles" | Path to realm/global roles |
clientRolesClaimPath | "resource_access" | Path to client-specific roles |
clientId | (parent clientId) | Which client's roles to extract |
The clientId in externalRoleExtraction defaults to the parent config.clientId, so you don't need to specify it twice.
Next Steps
- Create Mappings — Map external roles to Enterprise roles
