Keycloak Integration Guide
This guide walks you through integrating EUDIPLO with Keycloak using the Chained AS mode. In this setup, EUDIPLO acts as an OAuth Authorization Server facade while Keycloak handles user authentication.
Why Chained AS with Keycloak?
Many organizations already use Keycloak for identity management. The Chained AS mode lets you:
- Reuse existing Keycloak users and authentication flows — no need to duplicate identity infrastructure
- Keep session correlation simple — EUDIPLO automatically includes
issuer_statein tokens - Access full user claims in webhooks — ID token and access token claims from Keycloak are passed to your webhook
- Validate wallet attestations — EUDIPLO validates wallet attestations against configured trust lists (not possible with External AS)
- No Keycloak modifications required — unlike External AS mode, you don't need custom token mappers
Prerequisites
- A running Keycloak instance (tested with Keycloak 22+)
- EUDIPLO deployed and accessible at a public URL
- A tenant configured in EUDIPLO
Step 1: Configure Keycloak
Create a Realm (or use existing)
If you don't have a realm yet:
- Log in to Keycloak Admin Console
- Click Create realm
- Enter a name (e.g.,
eudiplo) and click Create
Create a Client for EUDIPLO
- Go to Clients → Create client
- Configure the client:
| Setting | Value |
|---|---|
| Client type | OpenID Connect |
| Client ID | eudiplo-chained-as |
| Client authentication | On (confidential client) |
| Valid redirect URIs | https://your-eudiplo-url/*/chained-as/callback |
Use * as a wildcard for the tenant name, or specify exact tenant names like https://eudiplo.example.com/prod/chained-as/callback.
- Click Save
- Go to the Credentials tab and copy the Client secret
Configure Scopes
Ensure the following scopes are available (they're defaults in Keycloak):
openid— Required for OIDCprofile— Includes name, preferred_usernameemail— Includes email address
To add custom claims (e.g., employee ID), create a custom scope with a mapper.
Step 2: Configure EUDIPLO
Update Issuance Configuration
Add the authorizationServers section to your issuance configuration:
{
"display": [
{
"name": "My Issuer",
"locale": "en"
}
],
"authorizationServers": [
{
"type": "chained",
"id": "chained-auth",
"enabled": true,
"upstream": {
"issuer": "https://keycloak.example.com/realms/eudiplo",
"clientId": "eudiplo-chained-as",
"clientSecret": "paste-your-client-secret-here",
"scopes": ["openid", "profile", "email"]
},
"requireDPoP": false,
"token": {
"lifetimeSeconds": 3600
}
}
]
}
| Field | Description |
|---|---|
upstream.issuer | Your Keycloak realm URL (must end with /realms/{realm-name}) |
upstream.clientId | The client ID you created in Keycloak |
upstream.clientSecret | The client secret from Keycloak's Credentials tab |
upstream.scopes | Scopes to request from Keycloak |
Configure Claims Webhook
To use the authenticated user's claims, configure a webhook on your credential configuration:
{
"credentialConfigurationId": "EmployeeBadge",
"claimsWebhook": {
"url": "https://your-backend.example.com/claims",
"auth": {
"type": "apiKey",
"config": {
"headerName": "X-API-Key",
"value": "your-secret-key"
}
}
}
}
Your webhook will receive the Keycloak user's claims in the identity object:
{
"session": "abc123",
"credential_configuration_id": "EmployeeBadge",
"identity": {
"iss": "https://keycloak.example.com/realms/eudiplo",
"sub": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"token_claims": {
"email_verified": true,
"preferred_username": "jdoe",
"given_name": "John",
"family_name": "Doe"
}
}
}
Step 3: Create a Credential Offer
Create an offer using the authorization code grant:
curl -X POST https://eudiplo.example.com/api/offers \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: prod" \
-d '{
"credentialConfigurationId": "EmployeeBadge",
"grant": "authorization_code",
"authorization_server": "chained-auth"
}'
The wallet will:
- Receive the credential offer
- Discover the Chained AS metadata from EUDIPLO
- Redirect the user to EUDIPLO's
/authorizeendpoint - EUDIPLO redirects to Keycloak for login
- After login, Keycloak redirects back to EUDIPLO
- EUDIPLO issues an access token to the wallet
- The wallet requests the credential using that token
Step 4: Verify the Integration
Check Chained AS Metadata
curl https://eudiplo.example.com/prod/chained-as/.well-known/oauth-authorization-server
Should return metadata including the authorization and token endpoints.
Check JWKS
curl https://eudiplo.example.com/prod/chained-as/.well-known/jwks.json
Should return the public keys used to sign access tokens.
Test with a Wallet
- Create a credential offer
- Scan or click the offer in a compatible wallet
- You should be redirected to Keycloak's login page
- After login, the credential should be issued
Related Topics
- Authentication — EUDIPLO authentication architecture
- Tenants — Multi-tenant configuration
- Issuance Configuration — Authorization server setup