A custom Keycloak Docker image with the ORCID Identity Provider extension, Magic Link passwordless authenticator, and Automatic Username Generation extension pre-installed, designed for use with InvenioRDM and other research data management platforms.
- Based on Keycloak 26.4
- Pre-installed ORCID Social Identity Provider extension
- ORCID-specific user attribute mappers
- ORCID theme with logo support
- Magic Link passwordless authentication
- Automatic username generation for new users
- Custom theme built with Keycloakify
- Automated builds via GitHub Actions
- Published to GitHub Container Registry
Pull and run the pre-built image:
docker pull ghcr.io/front-matter/keycloak-invenio:latest
docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin ghcr.io/front-matter/keycloak-invenio:latest start-devAccess Keycloak at http://localhost:8080
- Log in to the Keycloak Admin Console
- Select your realm
- Navigate to Identity Providers → Add provider → ORCID
- You'll need to register your application with ORCID:
- Visit ORCID Developer Tools
- Click "Register for the free ORCID public API"
- Configure your application with the Redirect URI from Keycloak
- Format:
https://<keycloak-url>/realms/<realm>/broker/orcid/endpoint
- Enter the Client ID and Client Secret from ORCID into Keycloak
- Save the configuration
To use the ORCID theme with the logo:
- Go to Realm Settings → Themes
- Set Login Theme to
orcid-theme - Save changes
The login theme supports displaying a custom logo in the header. You can configure this via realm attributes.
- Go to Realm Settings → Action (⋮) menu → Partial export
- Enable Export groups and roles
- Click Export
- Open the downloaded JSON file
- Add or modify the
attributessection at the realm level:
{
"realm": "your-realm-name",
"attributes": {
"logoUrl": "https://example.com/logo.svg"
},
...
}- Go back to Realm Settings → Action (⋮) menu → Partial import
- Upload the modified JSON file
- Select Skip for existing resources or Overwrite as needed
- Click Import
Use the Keycloak Admin REST API to set the realm attribute:
# Get admin token
TOKEN=$(curl -X POST "http://localhost:8080/realms/master/protocol/openid-connect/token" \
-d "client_id=admin-cli" \
-d "username=admin" \
-d "password=admin" \
-d "grant_type=password" | jq -r '.access_token')
# Update realm with logoUrl attribute
curl -X PUT "http://localhost:8080/admin/realms/YOUR_REALM" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"attributes": {
"logoUrl": "https://example.com/logo.svg"
}
}'Add the logoUrl attribute to your realm-config.json file before importing:
{
"realm": "invenio",
"attributes": {
"logoUrl": "https://invenio-rdm.example.org/static/logo.svg"
},
...
}Configuration Options:
- If
logoUrlis set, the logo image will be displayed in the login header - If
logoUrlis not set, the realm display name will be shown (default behavior) - Recommended logo size: max-height 60px, will scale automatically
- Supported formats: SVG, PNG, JPG, WebP
- URL must be publicly accessible from users' browsers
Example:
logoUrl = https://invenio-rdm.example.org/static/logo.svg
Note: In Keycloak 26.x, the "Realm attributes" UI section may not be visible in all configurations. Use the JSON import/export method or REST API as alternatives.
This image includes a custom Magic Link authenticator extension for passwordless email-based authentication. Users receive a login link via email that automatically authenticates them when clicked.
The Magic Link extension is built from source during the Docker image build process and is already included in the image.
Before Magic Link authentication works, you need to configure your realm's SMTP settings:
- Log in to Keycloak as admin
- Switch to your realm
- Click Realm settings in the left menu
- Select the Email tab
- Enter your SMTP details:
- Host: SMTP server address
- Port: SMTP port (e.g., 587 for TLS)
- From: Sender email address
- From display name: Display name for sender
- Enable SSL/StartTLS: Based on your SMTP server configuration
- Authentication: Username and password for SMTP authentication
- Go to Authentication → Flows
- Click Create flow
- Enter a name (e.g., "Browser with Magic Link")
- Top level flow type:
basic-flow - Click Create
-
Click Add execution for the new flow
-
Select Cookie → Add
-
Set Cookie to
ALTERNATIVE -
Click Add execution again
-
Select Identity Provider Redirector → Add
-
Set to
ALTERNATIVE -
Click Add execution
-
Select Magic Link Authenticator → Add
-
Set to
ALTERNATIVE
- Go to Authentication → Bindings
- Select your new flow for Browser Flow
- Click Save
Click the ⚙️ (Settings) icon next to Magic Link Authenticator in the authentication flow:
- Link validity: How long the magic link remains valid (default: 900 seconds = 15 minutes)
- Auto-create users: Automatically create users who don't have an account (default: disabled)
- Allowed domains group: Name of a group containing an
allowed-domainsattribute with trusted email domains for auto-creation (see Domain-Based Auto-Creation below)
You can configure automatic user creation for specific email domains (e.g., for your organization's employees). When users are auto-created via magic link, they receive a randomly generated username in the format usr_xxxxxxxx (e.g., usr_k9m2a7p3) instead of using their email address as the username. The email address is stored in the user's email field and is used for magic link delivery.
-
Create a group to hold allowed domains:
- Go to Groups → Create group
- Name:
auto-create-domains(or any name you prefer)
-
Add allowed domains to the group:
- Open the group → Attributes tab
- Add attribute:
allowed-domains - Add each domain as a separate attribute value:
- Click Add → Enter
example.com - Click Add → Enter
company.org - Repeat for each domain
- Click Add → Enter
-
Configure the authenticator:
- Go to your authentication flow
- Click ⚙️ next to Magic Link Authenticator
- Set Allowed domains group to
auto-create-domains - Keep Auto-create users set to
false(domain-based creation works independently)
Now users with email addresses from example.com or company.org will be automatically created when they use magic link login, even if Auto-create users is disabled. This allows controlled auto-creation without opening it to all email addresses.
Example:
- User enters:
john.doe@example.com - System checks: Domain
example.comis in allowed list ✓ - System creates: Username
usr_k9m2a7p3with emailjohn.doe@example.com - Email verified: Automatically set to true (verified via magic link)
- Go to your application's login page
- Enter an email address
- Check your email inbox for the magic link
- Click the link in the email
- You will be automatically logged in
- Verify SMTP configuration in Realm settings → Email
- Test the connection with the Test connection button
- Check Keycloak server logs for any email errors
- Check the Link validity setting (default: 15 minutes)
- Ensure server and client system times are synchronized
- Request a new magic link
Magic Link authentication requires a valid email address. Make sure:
- Email address is entered in the user profile
- Email address format is valid
- Set appropriate Link validity duration (15-30 minutes recommended)
- Enable SMTP Authentication and use TLS/SSL
- Consider combining Magic Link with other authentication methods for sensitive operations
- Monitor authentication logs for suspicious activity
- Ensure users understand not to share magic links
The image is built with --metrics-enabled=true and --health-enabled=true, so two extra endpoints are available on the management port 9000 (not the public port 8080):
| Endpoint | Purpose |
|---|---|
http://<host>:9000/metrics |
Prometheus scrape endpoint |
http://<host>:9000/health/ready |
Readiness probe |
http://<host>:9000/health/live |
Liveness probe |
When running the container, publish port 9000:
docker run -p 8080:8080 -p 9000:9000 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
ghcr.io/front-matter/keycloak-invenio:latest start-devFor production (start instead of start-dev) also set:
-e KC_METRICS_ENABLED=true \
-e KC_HEALTH_ENABLED=true \Build the Docker image locally:
git clone https://github.com/front-matter/keycloak-invenio.git
cd keycloak-invenio
docker build -t keycloak-invenio:local .The repository includes automated builds that:
- Build on every push to
mainbranch (createslatesttag) - Build on version tags (e.g.,
v1.0.0creates versioned tags) - Publish to
ghcr.io/front-matter/keycloak-invenio
To create a new release:
git tag v1.0.0
git push origin v1.0.0This Keycloak image is designed to work seamlessly with InvenioRDM. Configure InvenioRDM to use this Keycloak instance as an OAuth provider with ORCID authentication.
- Version: 1.4.0
- Source: eosc-kc/keycloak-orcid
- Compatibility: Keycloak 25.0+
- Built from: Source (included in this repository)
- Compatibility: Keycloak 26.4+
- Features: Passwordless authentication via email links
- Built from: Source (included in this repository)
- Compatibility: Keycloak 26.4+
- Features: Automatic username generation for new users
This image includes an OIDC protocol mapper that computes a Gravatar URL from the user's email address and exposes it as the standard OIDC claim picture.
picture: A URL likehttps://www.gravatar.com/avatar/<md5>?s=200&d=mp&r=g- Included in: ID Token, Access Token, and UserInfo response for the
invenio-appclient (via realm-config.json).
- From the ID token: read the
picturefield after login. - From UserInfo: call the OIDC userinfo endpoint (e.g.
GET /realms/<realm>/protocol/openid-connect/userinfo) with the access token and readpicture.
If you don't use realm import, configure it via the Admin Console using a Client Scope and attach it as a default scope.
- Admin Console → Client scopes → Create client scope
- Name:
gravatar(or any name you prefer) - Protocol:
openid-connect - Save
- Open the
gravatarclient scope → Protocol mappers - Add mapper → By configuration
- Select Gravatar picture
- Configure:
- Token Claim Name:
picture - Enable inclusion in ID token and UserInfo (Access token optional)
- (Optional) size/default/rating
- Token Claim Name:
- Save
- Admin Console → Clients → select your client (e.g.
invenio-app) - Client scopes tab
- Under Default client scopes → Add client scope → select
gravatar
After this, clients will receive picture by default (no need to request scope=gravatar).
- Keycloak: Apache License 2.0
- ORCID Extension: See extension license
- This repository: MIT License
For issues related to:
- This Docker image: Open an issue in this repository
- ORCID extension: Visit eosc-kc/keycloak-orcid
- Keycloak itself: Visit Keycloak documentation