Keycloak Integration
This page provides a step-by-step guide for integrating Keycloak as a Single Sign-On (SSO) provider with the Timbr platform. By following this tutorial, you will configure OpenID Connect (OIDC) authentication with secure PKCE (Proof Key for Code Exchange), enable role mapping from Keycloak roles and groups, and allow automatic user registration on first login.
Prerequisites
Before you begin, ensure you have:
- Keycloak server installed and running (version 12.0 or later recommended)
- Supports self-hosted Keycloak or Red Hat Single Sign-On (RH-SSO)
- Administrative access to your Keycloak Admin Console
- Administrative access to the Timbr platform server to configure environment variables
- Keycloak realm created (or use the default
masterrealm) - Your Timbr domain URL (e.g.,
https://timbr.example.com)
Step 1: Create an OIDC Client in Keycloak
1.1 Create or Select a Realm
- Log in to the Keycloak Admin Console (e.g.,
https://keycloak.example.com/auth/adminorhttps://keycloak.example.com/adminfor newer versions) - In the top-left dropdown, select an existing realm or click Add realm to create a new one
- Name:
timbr(or your preferred name) - Click Create
- Name:
1.2 Create a Client for Timbr
- In your realm, navigate to Clients in the left sidebar
- Click Create client (or Create in older versions)
- Configure the client:
| Setting | Value |
|---|---|
| Client type | OpenID Connect |
| Client ID | timbr-platform (or your preferred ID) |
| Name | Timbr Platform |
| Description | Timbr SSO Integration |
- Click Next
1.3 Configure Authentication Flow
On the Capability config page:
| Setting | Value |
|---|---|
| Client authentication | ON (for confidential clients with secret) |
| Authorization | OFF (unless needed) |
| Authentication flow | |
| - Standard flow | ✅ Enabled (Authorization Code flow) |
| - Direct access grants | ❌ Disabled (not needed for web SSO) |
| - Implicit flow | ❌ Disabled |
| - Service accounts roles | ❌ Disabled |
Click Next
1.4 Configure Login Settings
On the Login settings page, configure the URLs:
| Setting | Value |
|---|---|
| Root URL | https://<your-timbr-domain> |
| Home URL | https://<your-timbr-domain> |
| Valid redirect URIs | https://<your-timbr-domain>/oauth-authorized/keycloak |
| Valid post logout redirect URIs | https://<your-timbr-domain>/login/ |
| Web origins | https://<your-timbr-domain> (or + to allow all redirect URI origins) |
Replace <your-timbr-domain> with your actual Timbr domain.
Click Save
The Valid redirect URIs must exactly match the redirect URI sent by Timbr Platform during OAuth login. Common issues:
| Issue | Symptom | Solution |
|---|---|---|
| Scheme mismatch | Invalid parameter: redirect_uri | If Timbr runs on HTTP (e.g., development), use http:// in Keycloak AND set OAUTH_DEFAULT_SCHEME=http |
| Port missing | Invalid parameter: redirect_uri | Include the port if non-standard (e.g., http://localhost:8088/oauth-authorized/keycloak) |
| Trailing slash | Invalid parameter: redirect_uri | Do NOT include trailing slash in redirect URI |
| Wrong path | Invalid parameter: redirect_uri | Path must be exactly /oauth-authorized/keycloak |
Example Valid redirect URIs for different environments:
- Production (HTTPS):
https://timbr.example.com/oauth-authorized/keycloak - Development (HTTP):
http://localhost:8088/oauth-authorized/keycloak - With custom port:
https://timbr.example.com:8443/oauth-authorized/keycloak
Tip: You can add multiple redirect URIs (one per line) to support multiple environments.
1.5 Configure PKCE (Recommended)
PKCE (Proof Key for Code Exchange) provides an additional layer of security for the OAuth flow.
- Go to Clients → Your client → Settings tab
- Scroll to Advanced section (or Advanced settings)
- Find Proof Key for Code Exchange Code Challenge Method
- Set to S256 (SHA-256)
Click Save
Enabling PKCE protects against authorization code interception attacks, especially important for mobile and single-page applications.
1.6 Collect Client Credentials
After creating the client:
- Go to the Credentials tab
- Copy the Client secret – you'll use this as
OAUTH_SECRET - The Client ID from the Settings tab will be used as
OAUTH_CLIENT_ID - Note your Keycloak domain from the browser URL (e.g.,
https://keycloak.example.com) – you'll use this asOAUTH_BASE_URL - Note your Realm name (e.g.,
timbr) – you'll use this asOAUTH_KEYCLOAK_REALM
Store your client secret securely. Never commit it to version control or share it publicly.
Step 2: Configure Timbr Environment Variables
Add the OAuth environment variables to your timbr-platform service configuration. The configuration method depends on your deployment type:
- Docker Compose: Add environment variables to the
timbr-platformservice in yourdocker-compose.ymlfile. See the Docker Compose deployment guide for the base configuration. - Kubernetes: Add environment variables to the
timbr-platformDeployment manifest. See the Kubernetes deployment guide for the base configuration.
2.1 Required Environment Variables
# Provider identifier
OAUTH_PROVIDER=keycloak
# Client credentials from Keycloak Admin Console
OAUTH_CLIENT_ID=<your-keycloak-client-id>
OAUTH_SECRET=<your-keycloak-client-secret>
# Keycloak base URL (without /realms or /auth suffix)
# Keycloak 17+ (Quarkus): https://keycloak.example.com
# Older versions (WildFly): https://keycloak.example.com/auth
# RH-SSO: https://sso.example.com/auth
OAUTH_BASE_URL=https://<your-keycloak-domain>
# Keycloak realm name
OAUTH_KEYCLOAK_REALM=<your-realm-name>
- Keycloak 17+ (Quarkus-based): Uses URLs without
/authprefix (e.g.,https://keycloak.example.com) - Older versions (WildFly-based): Use
/authprefix (e.g.,https://keycloak.example.com/auth) - Red Hat SSO: Typically uses
/authprefix (e.g.,https://sso.example.com/auth)
The integration automatically detects and handles both URL formats.
2.2 Deployment-Specific Configuration
Docker Compose
Add the OAuth environment variables to your timbr-platform service in docker-compose.yml:
services:
timbr-platform:
image: timbr/timbr-platform:latest
environment:
- OAUTH_PROVIDER=keycloak
- OAUTH_CLIENT_ID=timbr-platform
- OAUTH_SECRET=your-client-secret-here
- OAUTH_BASE_URL=https://keycloak.example.com
- OAUTH_KEYCLOAK_REALM=timbr
- AUTH_USER_REGISTRATION=true
- AUTH_USER_REGISTRATION_ROLE=viewer
- OAUTH_USE_PKCE=true
# ... other configurations
After updating your docker-compose.yml, restart the timbr-platform service:
sudo docker-compose up -d timbr-platform
Kubernetes
Add the OAuth environment variables to your timbr-platform Deployment manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: timbr-platform
namespace: default
spec:
template:
spec:
containers:
- name: timbr-platform
image: timbr/timbr-platform:latest
env:
- name: OAUTH_PROVIDER
value: "keycloak"
- name: OAUTH_CLIENT_ID
value: "timbr-platform"
- name: OAUTH_SECRET
value: "your-client-secret-here"
- name: OAUTH_BASE_URL
value: "https://keycloak.example.com"
- name: OAUTH_KEYCLOAK_REALM
value: "timbr"
- name: AUTH_USER_REGISTRATION
value: "true"
- name: AUTH_USER_REGISTRATION_ROLE
value: "viewer"
- name: OAUTH_USE_PKCE
value: "true"
# ... other configurations
Apply the updated manifest:
kubectl apply -f timbr-platform.yaml
For better security in Kubernetes, store sensitive values like OAUTH_CLIENT_ID and OAUTH_SECRET in Kubernetes Secrets instead of plain text in the manifest.
2.3 Optional Environment Variables
# Default scheme for OAuth redirects (default: https)
# ⚠️ IMPORTANT: Set to 'http' if your Timbr Platform runs on HTTP (e.g., development)
OAUTH_DEFAULT_SCHEME=https
# Enable user self-registration on first OAuth login
AUTH_USER_REGISTRATION=true
# Default role for self-registered users (default: viewer)
AUTH_USER_REGISTRATION_ROLE=viewer
# Allow or disable username/password login alongside OAuth
AUTH_WITH_USERPASS=true
# Custom scopes (space-separated, added to default scopes)
OAUTH_SCOPES=
# Enable PKCE (default: true)
OAUTH_USE_PKCE=true
# Enable JWT signature verification (default: true)
OAUTH_KEYCLOAK_VERIFY_SIGNATURE=true
# Enable front-channel single logout (default: false)
OAUTH_FRONT_CHANNEL_SINGLE_LOGOUT=false
# Enable Keycloak roles/groups to Timbr roles mapping (default: false)
OAUTH_ROLE_MAPPING_ENABLED=false
# JSON mapping of Keycloak roles/groups to Timbr roles
OAUTH_ROLE_MAPPING={"keycloak_admin": "admin", "keycloak_editor": "editor", "keycloak_viewer": "viewer"}
# Fallback role if no group matches (defaults to AUTH_USER_REGISTRATION_ROLE)
OAUTH_ROLE_MAPPING_DEFAULT=viewer
# Role assignment strategy: 'highest', 'all', or 'first' (default: highest)
OAUTH_ROLE_MAPPING_STRATEGY=highest
# Role priority for 'highest' strategy (comma-separated, highest first)
OAUTH_ROLE_PRIORITY=admin,editor,analyst,viewer
# Role sources to use (comma-separated): realm_roles, client_roles, groups
OAUTH_KEYCLOAK_ROLE_SOURCES=realm_roles,client_roles,groups
2.4 Example Configurations
Example 1: Basic Configuration (Keycloak 17+)
OAUTH_PROVIDER=keycloak
OAUTH_CLIENT_ID=timbr-platform
OAUTH_SECRET=abc123secret
OAUTH_BASE_URL=https://keycloak.example.com
OAUTH_KEYCLOAK_REALM=timbr
AUTH_USER_REGISTRATION=true
AUTH_USER_REGISTRATION_ROLE=viewer
OAUTH_USE_PKCE=true
Example 2: Older Keycloak / Red Hat SSO
OAUTH_PROVIDER=keycloak
OAUTH_CLIENT_ID=timbr-platform
OAUTH_SECRET=abc123secret
OAUTH_BASE_URL=https://sso.example.com/auth
OAUTH_KEYCLOAK_REALM=production
AUTH_USER_REGISTRATION=true
AUTH_USER_REGISTRATION_ROLE=viewer
OAUTH_USE_PKCE=true
Example 3: With Role Mapping
OAUTH_PROVIDER=keycloak
OAUTH_CLIENT_ID=timbr-platform
OAUTH_SECRET=abc123secret
OAUTH_BASE_URL=https://keycloak.example.com
OAUTH_KEYCLOAK_REALM=timbr
AUTH_USER_REGISTRATION=true
AUTH_USER_REGISTRATION_ROLE=viewer
OAUTH_USE_PKCE=true
OAUTH_ROLE_MAPPING_ENABLED=true
OAUTH_ROLE_MAPPING={"timbr-admin": "admin", "timbr-editor": "editor", "timbr-analyst": "analyst", "timbr-viewer": "viewer"}
OAUTH_ROLE_MAPPING_STRATEGY=highest
OAUTH_ROLE_PRIORITY=admin,editor,analyst,viewer
OAUTH_KEYCLOAK_ROLE_SOURCES=realm_roles,client_roles,groups
Step 3: Configure Keycloak Roles and Groups (Optional)
If you want to automatically assign Timbr roles based on Keycloak roles or group membership, follow these steps to configure role mapping.
3.1 Understanding Keycloak Role Architecture
Keycloak has three sources for roles that can be mapped to Timbr roles:
- Realm Roles (Global): Roles defined at the realm level, available to all clients
- Client Roles (Per-client): Roles specific to your Timbr client
- Groups (Hierarchical): User groups that can contain roles
You can use any combination of these sources for role mapping.
3.2 Create Realm Roles
- In the Keycloak Admin Console, navigate to Realm roles in the left sidebar
- Click Create role
- Configure the role:
- Role name: Use a descriptive name (e.g.,
timbr-admin,timbr-analyst,timbr-viewer) - Description: Optional description of the role's purpose
- Role name: Use a descriptive name (e.g.,
- Click Save
- Repeat for each role you want to map (recommended:
timbr-admin,timbr-editor,timbr-analyst,timbr-viewer)
Use a consistent naming convention like timbr-<role> to make role-to-role mapping easier. The role names you create here will be used in the OAUTH_ROLE_MAPPING environment variable.
3.3 Create Client Roles (Alternative)
If you prefer client-specific roles:
- Navigate to Clients → Your Timbr client → Roles tab
- Click Create role
- Configure the role similar to realm roles
- Click Save
3.4 Create Groups (Alternative)
If you prefer using groups:
- Navigate to Groups in the left sidebar
- Click Create group
- Enter the group details:
- Name: Use a descriptive name (e.g.,
timbr-admins,timbr-analysts,timbr-viewers)
- Name: Use a descriptive name (e.g.,
- Click Create
- Repeat for each group you want to map
3.5 Assign Roles or Groups to Users
Assign Realm Roles:
- Navigate to Users → Select a user
- Go to the Role mapping tab
- Click Assign role
- Select the realm roles you want to assign
- Click Assign
Assign Client Roles:
- Navigate to Users → Select a user
- Go to the Role mapping tab
- Click Assign role
- Filter by client roles and select your Timbr client
- Select the client roles you want to assign
- Click Assign
Assign Groups:
- Navigate to Users → Select a user
- Go to the Groups tab
- Click Join Group
- Select the groups you want to add the user to
- Click Join
3.6 Configure Token Claims for Roles and Groups
To include roles and groups in the authentication token, configure the client scopes:
Add Realm Roles to Tokens:
- Go to Client scopes → roles → Mappers tab
- Find or create the realm roles mapper
- Ensure the following settings:
- Mapper Type: User Realm Role
- Token Claim Name:
realm_access.roles - Add to ID token: ON
- Add to access token: ON
- Add to userinfo: ON
Add Client Roles to Tokens:
- Go to Client scopes → roles → Mappers tab
- Find or create the client roles mapper
- Ensure the following settings:
- Mapper Type: User Client Role
- Token Claim Name:
resource_access.${client_id}.roles - Add to ID token: ON
- Add to access token: ON
- Add to userinfo: ON
Add Groups to Tokens:
- Go to Client scopes → Create new scope named
groups(if it doesn't exist) - Go to Mappers tab → Configure a new mapper
- Select Group Membership
- Configure:
- Name:
groups - Mapper Type: Group Membership
- Token Claim Name:
groups - Full group path: OFF (for simple group names)
- Add to ID token: ON
- Add to access token: ON
- Add to userinfo: ON
- Name:
- Click Save
- Go to Clients → Your Timbr client → Client scopes tab
- Add the
groupsscope as Default
3.7 Configure Role Mapping in Timbr
Now that your roles and groups are configured in Keycloak, map them to Timbr roles using environment variables:
# Enable role mapping
OAUTH_ROLE_MAPPING_ENABLED=true
# Map Keycloak roles/groups to Timbr roles (case-insensitive matching)
# Format: {"keycloak_role_or_group_name": "timbr_role_name", ...}
OAUTH_ROLE_MAPPING={"timbr-admin": "admin", "timbr-editor": "editor", "timbr-analyst": "analyst", "timbr-viewer": "viewer"}
# Fallback role if no mapping matches
OAUTH_ROLE_MAPPING_DEFAULT=viewer
# How to handle multiple matching roles: "first", "highest", "all"
# - first: Use the first matching role found
# - highest: Use the role with highest privileges (based on OAUTH_ROLE_PRIORITY)
# - all: Assign all matching roles to the user (additive)
OAUTH_ROLE_MAPPING_STRATEGY=highest
# Role priority for "highest" strategy (comma-separated, highest first)
OAUTH_ROLE_PRIORITY=admin,editor,analyst,viewer
# Which Keycloak sources to use for role extraction
# Options: realm_roles, client_roles, groups (comma-separated)
OAUTH_KEYCLOAK_ROLE_SOURCES=realm_roles,client_roles,groups
Example mapping strategies:
| Keycloak Role/Group | Timbr Role | Purpose |
|---|---|---|
timbr-admin | admin | Full system access |
timbr-editor | editor | Can edit ontologies and models |
timbr-analyst | analyst | Can query and analyze data |
timbr-viewer | viewer | Read-only access |
3.8 Test Your Role Mapping
After configuring roles/groups and environment variables, test with different users:
Testing Steps:
- Log out of Timbr if currently logged in
- Click "Sign in with Keycloak"
- Log in with a test user who has specific roles or group membership
- After successful login, check the user's role in Timbr
- Verify the role matches your mapping configuration
Test Scenarios:
| Test Scenario | User's Keycloak Roles/Groups | Expected Timbr Role | Notes |
|---|---|---|---|
| Admin user | timbr-admin | admin | User should have full system access |
| Editor user | timbr-editor | editor | Can modify ontologies and models |
| Analyst user | timbr-analyst | analyst | Can query and analyze data |
| Viewer user | timbr-viewer | viewer | Read-only access |
| Multi-role user (highest) | timbr-analyst, timbr-viewer | analyst | Gets higher priority role when strategy is "highest" |
| Multi-role user (all) | timbr-editor, timbr-analyst | editor, analyst | Gets both roles when strategy is "all" |
| User with unmapped roles | other-role | viewer | Falls back to default role |
| User with no roles | (none) | viewer | Falls back to default role |
If roles are not being assigned correctly:
- Verify the roles/groups are included in the ID token (check Keycloak token preview in Admin Console)
- Ensure role/group names in
OAUTH_ROLE_MAPPINGmatch Keycloak names (case-insensitive) - Check the Timbr platform logs for role assignment messages
- Verify users are actually assigned the expected roles or groups in Keycloak
- Confirm
OAUTH_ROLE_MAPPING_ENABLED=trueis set - Check that the appropriate client scopes (roles, groups) are assigned to your client
Step 4: Configure Front-Channel Single Logout (Optional)
Front-channel single logout allows Keycloak to send logout requests to all participating applications when a user logs out.
4.1 Enable Front-Channel Logout in Keycloak
Go to Clients → Your Timbr client → Settings tab
Scroll to Logout settings section
Configure:
- Front channel logout: ON
- Front channel logout URL:
https://<your-timbr-domain>/logout/
Click Save
4.2 Enable in Timbr Configuration
Add to your environment variables:
# Enable front-channel single logout
OAUTH_FRONT_CHANNEL_SINGLE_LOGOUT=true
When enabled, users who log out will be redirected to Keycloak's logout endpoint, which will then redirect back to the Timbr login page after completing the logout process.
Troubleshooting
Login Redirect Issues
Symptoms:
- Error:
Invalid parameter: redirect_uri - User cannot complete login
Solutions:
Verify redirect URI matches exactly: Check that the redirect URI in Keycloak matches what Timbr sends
# Timbr sends: https://timbr.example.com/oauth-authorized/keycloak
# Keycloak must have: https://timbr.example.com/oauth-authorized/keycloakCheck scheme (HTTP vs HTTPS):
- If Timbr runs on HTTP (development), set
OAUTH_DEFAULT_SCHEME=httpand update Keycloak redirect URI to usehttp://
- If Timbr runs on HTTP (development), set
Verify port number: Include the port in both Timbr configuration and Keycloak if using non-standard ports
Check for trailing slashes: Remove trailing slashes from redirect URIs
Token Validation Fails
Symptoms:
- API returns 401 Unauthorized
- Error message: "Invalid token" or "Token validation failed"
Solutions:
Verify realm name: Ensure
OAUTH_KEYCLOAK_REALMmatches the actual realm name in KeycloakCheck base URL format:
- Keycloak 17+: Use
https://keycloak.example.com(no/auth) - Older versions: Use
https://keycloak.example.com/auth
- Keycloak 17+: Use
Verify JWT signature verification: If
OAUTH_KEYCLOAK_VERIFY_SIGNATURE=true, ensure the JWKS endpoint is accessibleCheck token expiration: Verify the token hasn't expired
User Not Found
Symptoms:
- Token validates successfully but user authentication fails
- Error message: "User not found"
Solutions:
Enable user registration: Set
AUTH_USER_REGISTRATION=trueto allow automatic user creation on first loginCheck user email: Verify the Keycloak user has an email address set
Verify userinfo endpoint: Ensure the userinfo endpoint returns the expected user data
Role Mapping Not Working
Symptoms:
- Users assigned wrong roles or default role instead of mapped role
- Roles not being extracted from Keycloak
Solutions:
Verify role mapping is enabled: Set
OAUTH_ROLE_MAPPING_ENABLED=trueCheck role sources: Ensure
OAUTH_KEYCLOAK_ROLE_SOURCESincludes the sources you're using (realm_roles, client_roles, or groups)Verify token claims: Check that roles/groups are included in the ID token:
- Go to Client scopes and verify mappers are configured correctly
- Use Keycloak's token preview feature to see token contents
Check role names: Ensure role names in
OAUTH_ROLE_MAPPINGmatch exactly (case-insensitive)Verify user has roles: Confirm users are assigned the expected roles or groups in Keycloak Admin Console
PKCE Errors
Symptoms:
- Error:
PKCE verification failed - Login fails after entering credentials
Solutions:
Verify PKCE is enabled in Keycloak: Set Proof Key for Code Exchange Code Challenge Method to
S256in client settingsCheck PKCE configuration: Ensure
OAUTH_USE_PKCE=truein Timbr configurationSession issues: Clear browser cookies and session data, then try again
Keycloak Version Compatibility
Symptoms:
- 404 errors when accessing Keycloak endpoints
- Unexpected URL paths
Solutions:
Check Keycloak version:
- Keycloak 17+ (Quarkus): URLs don't include
/authprefix - Older versions (WildFly): URLs include
/authprefix
- Keycloak 17+ (Quarkus): URLs don't include
Verify base URL: Update
OAUTH_BASE_URLto match your Keycloak version:# Keycloak 17+
OAUTH_BASE_URL=https://keycloak.example.com
# Older versions / RH-SSO
OAUTH_BASE_URL=https://keycloak.example.com/auth
Security Considerations
Best Practices
Use HTTPS in production: Always use HTTPS for production deployments
- Set
OAUTH_DEFAULT_SCHEME=https - Configure valid SSL certificates
- Set
Enable PKCE: Keep
OAUTH_USE_PKCE=truefor enhanced securitySecure client secrets:
- Use Kubernetes Secrets or Docker Secrets for storing
OAUTH_SECRET - Never commit secrets to version control
- Rotate secrets periodically
- Use Kubernetes Secrets or Docker Secrets for storing
Enable JWT signature verification: Keep
OAUTH_KEYCLOAK_VERIFY_SIGNATURE=trueto validate token authenticityUse short token lifespans: Configure reasonable token expiration times in Keycloak realm settings
Implement proper logout: Enable front-channel single logout for comprehensive session termination
Review role mappings: Regularly audit role assignments to ensure users have appropriate access levels
Monitor failed logins: Enable Keycloak's built-in security features like brute force detection
Keycloak Security Settings
In your Keycloak realm, consider enabling:
Realm Settings → Security Defenses:
- Brute Force Detection: Protects against password guessing attacks
- X-Frame-Options: Prevents clickjacking
- Content-Security-Policy: Adds additional security headers
Realm Settings → Tokens:
- Set appropriate token lifespans
- Enable token revocation
- Configure refresh token settings
Required Actions:
- Configure user to verify email
- Enforce password updates
- Enable terms and conditions acceptance
Additional Resources
For additional assistance with Keycloak integration, please contact Timbr support or refer to the main Timbr documentation.