Keycloak Integration
This guide explains how to integrate SIROS ID credential verification with Keycloak, allowing users to authenticate to your applications using their digital credentials. After reading this guide, you will understand how to:
- Add SIROS ID as an identity provider in Keycloak
- Configure claim mappings for user attributes
- Request specific credential types
- Handle first-time logins and account linking
Overview
Keycloak can use the SIROS ID verifier as an external OpenID Connect identity provider. When users select "Login with SIROS ID", they present credentials from their wallet instead of entering a username and password.
This guide works with both the SIROS ID hosted verifier and self-hosted deployments. Simply replace the verifier URL as needed. See Verifier Deployment Options for more information.
When using the SIROS ID hosted service, verifiers use subdomain-based URLs:
https://<instance>.<tenant>.verifier.id.siros.org
Prerequisites
- Keycloak 22+ installed and running
- Admin access to your Keycloak realm
- A SIROS ID verifier (hosted or self-hosted)
Step 1: Register Your Keycloak Instance
Register Keycloak as an OIDC client with the verifier:
curl -X POST https://verifier.example.org/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "My Keycloak",
"redirect_uris": ["https://keycloak.example.com/realms/myrealm/broker/sirosid/endpoint"],
"token_endpoint_auth_method": "client_secret_post",
"grant_types": ["authorization_code"],
"response_types": ["code"],
"scope": "openid profile"
}'
For the SIROS hosted service with tenant acme and verifier instance main:
curl -X POST https://main.acme.verifier.id.siros.org/register \
-H "Content-Type: application/json" \
-d '{ ... }'
}'
Save the returned `client_id` and `client_secret` for the next step.
:::warning[Redirect URI Format]
The redirect URI must exactly match Keycloak's broker endpoint format:
```text
https://<keycloak-host>/realms/<realm-name>/broker/<alias>/endpoint
:::
Step 2: Add the Identity Provider
- Open Keycloak Admin Console
- Select your realm
- Navigate to Identity Providers → Add provider → OpenID Connect v1.0
Configure the following settings:
General Settings
| Setting | Value | Description |
|---|---|---|
| Alias | sirosid | Internal identifier (used in redirect URI) |
| Display Name | Login with Credential | Shown on login page |
| Enabled | ON | Enable the provider |
| Store Tokens | ON | Required for debugging; optional in production |
| Trust Email | ON | Trust email from verified credentials |
OpenID Connect Settings
| Setting | Value |
|---|---|
| Discovery Endpoint | https://verifier.example.org/.well-known/openid-configuration |
| Client ID | (from Step 1) |
| Client Secret | (from Step 1) |
| Client Authentication | Client secret sent as post |
Security Settings
| Setting | Value | Description |
|---|---|---|
| Validate Signatures | ON | Verify ID token signatures |
| Use PKCE | ON | Proof Key for Code Exchange |
| PKCE Method | S256 | SHA-256 challenge method |
Scopes
| Setting | Value |
|---|---|
| Default Scopes | openid profile |
To request additional credentials, add scopes:
| Scope | Credential Type |
|---|---|
profile | Basic PID (name, birthdate) |
pid | Full Person Identification Data |
ehic | European Health Insurance Card |
diploma | Educational credentials |
Example for health services: openid profile ehic
Step 3: Configure Claim Mappers
Map verified credential claims to Keycloak user attributes.
Navigate to Identity Providers → sirosid → Mappers → Add mapper
Essential Mappers
Username
| Setting | Value |
|---|---|
| Name | username |
| Mapper Type | Username Template Importer |
| Template | ${CLAIM.sub} |
| Sync Mode | inherit |
First Name
| Setting | Value |
|---|---|
| Name | firstName |
| Mapper Type | Attribute Importer |
| Claim | given_name |
| User Attribute Name | firstName |
| Sync Mode | inherit |
Last Name
| Setting | Value |
|---|---|
| Name | lastName |
| Mapper Type | Attribute Importer |
| Claim | family_name |
| User Attribute Name | lastName |
| Sync Mode | inherit |
Email
| Setting | Value |
|---|---|
| Name | email |
| Mapper Type | Attribute Importer |
| Claim | email |
| User Attribute Name | email |
| Sync Mode | inherit |
Optional Mappers
Birth Date
| Setting | Value |
|---|---|
| Name | birthdate |
| Mapper Type | Attribute Importer |
| Claim | birthdate |
| User Attribute Name | birthdate |
| Sync Mode | inherit |
Nationality
| Setting | Value |
|---|---|
| Name | nationality |
| Mapper Type | Attribute Importer |
| Claim | nationality |
| User Attribute Name | nationality |
| Sync Mode | inherit |
Step 4: Configure First Login Behavior
Control what happens when a user logs in with credentials for the first time.
Navigate to Authentication → Flows and configure the first broker login flow:
| Option | Recommended Setting | Description |
|---|---|---|
| Create User If Unique | ON | Auto-create accounts for new users |
| Confirm Link Existing Account | ON | Prompt before linking to existing accounts |
| Verify Existing Account By Email | OFF | Skip if Trust Email is enabled |
Auto-Linking by Email
To automatically link credential logins to existing accounts with matching email:
- Create a new authentication flow
- Add Automatically Link Brokered Account execution
- Set the IdP's First Login Flow to your new flow
Only use auto-linking if you trust the credential issuer to verify email addresses.
Step 5: Test the Integration
- Open your application's login page
- Click Login with Credential (or your configured display name)
- Scan the QR code with your SIROS ID wallet
- Approve the credential sharing request in your wallet
- Verify you're logged in with the correct user attributes
Test with the Demo Wallet
If you don't have credentials yet:
- Go to id.siros.org
- Create a wallet with a passkey
- Add a Demo PID credential
- Use this wallet to test your Keycloak integration
Advanced Configuration
Step-Up Authentication
Require credential verification for sensitive operations:
// In your application, request step-up authentication
KeycloakSecurityContext context = getSecurityContext();
context.getToken().getOtherClaims().get("acr"); // Check authentication level
// Force re-authentication with SIROS ID
redirectToKeycloak("?kc_idp_hint=sirosid&prompt=login");
Conditional Authentication
Create authentication flows that conditionally require credential verification:
- Authentication → Flows → Create flow
- Add a Conditional subflow
- Add Condition - User Role to check if user needs verification
- Add Identity Provider Redirector pointing to
sirosid
Custom Theme
Customize the login button appearance:
<!-- In your Keycloak theme: login.ftl -->
<#list social.providers as p>
<#if p.alias == "sirosid">
<a href="${p.loginUrl}" class="siros-login-btn">
<img src="${url.resourcesPath}/img/siros-logo.svg" alt="SIROS ID" />
<span>Login with Digital Credential</span>
</a>
</#if>
</#list>
Troubleshooting
Invalid Redirect URI
Error: invalid_redirect_uri
Solution: Verify the redirect URI exactly matches:
https://keycloak.example.com/realms/{realm}/broker/sirosid/endpoint
Check for:
- Trailing slashes
- HTTP vs HTTPS
- Correct realm name
- Correct alias (
sirosid)
Token Signature Validation Failed
Error: token_signature_validation_failed
Solutions:
- Ensure Validate Signatures is ON
- Verify Keycloak can reach the verifier's JWKS endpoint
- Clear the key cache:
- Realm Settings → Keys → Providers
- Toggle the provider off and on
Claims Not Appearing in User Profile
Symptoms: User created but attributes are empty
Solutions:
- Verify mapper Sync Mode is
inheritorforce - Check the claim name matches exactly (case-sensitive)
- Enable Store Tokens and inspect the raw ID token in user sessions
- Verify the requested scopes include the needed claims
User Already Exists
Error: User already exists or duplicate user created
Solutions:
- Configure the first login flow to link existing accounts
- Use email as the linking attribute
- Ensure Trust Email is enabled if using email linking
Configuration Reference
Complete Identity Provider JSON
Export this configuration to replicate the setup:
{
"alias": "sirosid",
"displayName": "Login with Credential",
"providerId": "oidc",
"enabled": true,
"trustEmail": true,
"storeToken": false,
"linkOnly": false,
"firstBrokerLoginFlowAlias": "first broker login",
"config": {
"clientId": "${CLIENT_ID}",
"clientSecret": "${CLIENT_SECRET}",
"tokenUrl": "https://verifier.example.org/token",
"authorizationUrl": "https://verifier.example.org/authorize",
"jwksUrl": "https://verifier.example.org/jwks",
"userInfoUrl": "https://verifier.example.org/userinfo",
"issuer": "https://verifier.example.org",
"clientAuthMethod": "client_secret_post",
"syncMode": "INHERIT",
"validateSignature": "true",
"pkceEnabled": "true",
"pkceMethod": "S256",
"defaultScope": "openid profile"
}
}
Environment Variables
For production deployments, use environment variables:
# Keycloak environment
KC_SPI_IDENTITY_PROVIDER_OIDC_SIROSID_CLIENT_ID=your-client-id
KC_SPI_IDENTITY_PROVIDER_OIDC_SIROSID_CLIENT_SECRET=your-client-secret
Next Steps
- Verifier Configuration – Full verifier documentation
- Trust Services – Configure trust framework integration
- Quick Start Guide – Get started in 15 minutes