Keycloak SAML integration guide

Configure Keycloak to use ID.me as a SAML 2.0 identity provider.

Overview

This guide provides steps to integrate Keycloak with ID.me using the SAML 2.0 protocol.

Intended audience Developers and IAM administrators responsible for configuring federation between Keycloak and ID.me.

What you will build A federated authentication flow where Keycloak delegates user authentication to ID.me using SAML 2.0 assertions.

Result A federated SAML authentication flow where Keycloak delegates authentication to ID.me, allowing users to sign in to a target application.

Identity proofing behavior Authentication behavior, identity verification settings, and returned attributes are driven by ID.me policy configurations.

Authentication flow

The following steps outline the SAML authentication flow between the user, Keycloak, and ID.me:

1

The user navigates to the application and is redirected to the Keycloak login page

2

The user selects the ID.me option

3

Keycloak generates a SAML AuthnRequest and redirects the user to the ID.me SSO URL

4

The user completes authentication and identity verification at ID.me

5

ID.me returns a SAML Response containing the signed assertion to the Keycloak ACS URL

6

Keycloak validates the assertion, creates a user session, and posts a new SAML assertion to your application’s ACS URL. Your application validates the assertion and grants the user access.

SAML 2.0 flow between the user, target application, Keycloak, and ID.me, showing redirect to ID.me, user authentication and optional verification, a POST SAML response to Keycloak, SAML assertion validation, and a POST of a new SAML assertion from Keycloak to the application

Prerequisites

  • A running instance of Keycloak
  • Administrator access to the Keycloak admin console
  • An ID.me sandbox account for testing your integration
  • Understanding of SAML flows and terminology

Environments

ID.me provides two environments:

Sandbox

https://api.idmelabs.com/

Production

https://api.id.me/

All ID.me OIDC and SAML endpoints are derived from the base URL above. For production, replace the sandbox base URL in every ID.me endpoint you configure.

Examples

  • OIDC issuer (Sandbox): https://api.idmelabs.com/oidc
  • OIDC issuer (Production): https://api.id.me/oidc
  • SAML metadata URL (Sandbox): https://api.idmelabs.com/saml/metadata
  • SAML metadata URL (Production): https://api.id.me/saml/metadata

Configure Keycloak

Create a realm

1

Log in to the Keycloak admin console (default http://localhost:8080)

2

Select the realm dropdown in the top left corner (the default is “Master”)

3

Select Create Realm

4

Enter a Realm name (for example, myrealm)

5

Select Create

Configure ID.me as a SAML identity provider

1

Navigate to Identity Providers in the left menu.

2

Select Add provider > SAML 2.0.

3

Fill in the following fields. When you enter the SAML entity descriptor URL and tab out of the field, Keycloak fetches the ID.me metadata and auto-populates the remaining SAML settings.

FieldValue
Aliasidme-sandbox-saml
Display NameIDMe-Sandbox
Service Provider Entity IDhttp://localhost:8080/realms/<your realm name>
Use entity descriptorOn
SAML entity descriptorhttps://api.idmelabs.com/saml/metadata/provider
4

Select Show metadata to expand and review the values Keycloak auto-populated from the ID.me metadata URL. Most fields are populated correctly from the metadata. Verify or update the following fields:

FieldAuto-populated value / expected value
Identity provider entity IDapi.idmelabs.com
Single Sign-On service URLhttps://api.idmelabs.com/saml/SingleSignOnService
Single logout service URLhttps://api.idmelabs.com/saml/SingleLogoutService
NameID policy formatUnspecified
Allow createOn
HTTP-POST binding responseOn
HTTP-POST binding for AuthnRequestOn
Want AuthnRequests signedOn
Signature algorithmRSA_SHA256
SAML signature key nameKEY_ID
Validate SignaturesOn
Validating X509 CertificatesThe active X.509 certificate from ID.me SAML metadata (without header/footer)
Comparisonexact
AuthNContextClassRefs<your ID.me policy handle value> (e.g., nist_ial2_aal2 in this guide)

By default, Keycloak may auto-populate an inactive certificate from the ID.me metadata URL because ID.me uses an active=true XML element during certificate transitions to avoid downtime. Keycloak ignores that custom XML element, so you must manually verify that the active ID.me signing certificate is entered in the Validating X509 Certificates field.

Screenshot of XML metadata file highlighting active=true XML element
5

Select Add

Map user claims

1

Navigate to Identity Providers > <your IdP Name> > Mappers

2

Select Add mapper

3

Configure the mapper:

  • Name: An identifier for the mapping (for example, firstName)
  • Sync mode override: Select Force (always overwrite from ID.me at login)
  • Mapper type: Select Attribute Importer
  • Attribute Name: Enter the exact SAML attribute name coming from ID.me
  • Name Format: ATTRIBUTE_FORMAT_BASIC
  • User Attribute name: The attribute in Keycloak that will store the imported value (for example, firstName or a custom attribute)
Screenshot showing keycloak add attribute mapper for firstname
4

Select Save

5

Repeat these steps for other claims as necessary (e.g., lname to lastName, email to email, uuid to uuid).

Screenshot of key cloak, Samuel mapper complete with UUID, first name, email, and last name mapped

Configure a target app

This step registers your SAML service provider (SP) application as a client in Keycloak. Use the entity ID and ACS URL from your SP’s metadata.

The examples in this guide use a custom Python SAML SP demo application for illustrative purposes. It runs locally on port 8081. Substitute your own SP’s entity ID, ACS URL, and base URL where indicated.

1

Navigate to Clients > Create Client

2

Set Client type to SAML

3

Enter a Client ID matching your SP’s entity ID (for example, http://localhost:8081/saml/metadata)

4

Select Next, then Save

5

Configure the client settings:

SectionFieldValue
General settingsNameYour application name (for example, SAMLTestApp)
Access settingsRoot URLYour SP’s base URL (for example, http://localhost:8081)
Access settingsValid redirect URIsYour SP’s ACS URL (for example, http://localhost:8081/*). Do NOT use wildcards in production environments.
Access settingsMaster SAML Processing URLYour SP’s ACS URL (for example, http://localhost:8081/saml/acs)
SAML capabilitiesName ID formatusername
SAML capabilitiesForce POST bindingOn
SAML capabilitiesInclude AuthnStatementOn
Signature and EncryptionSign documentsOn
Signature and EncryptionSign assertionsOn
Signature and EncryptionSignature algorithmRSA_SHA256
Signature and EncryptionCanonicalization methodEXCLUSIVE
Screenshot showing a sample Keycloak SAML client configuration based on custom local Python demo app
6

Go to the Keys tab, enable Client signature required, and import your SP’s signing certificate using the Certificate PEM format.

Screenshot showing Keycloak demo SAML client application key configuration page  showing client signature request toggle is on and a certificate is populated from the demo app

Map attributes to the target app

Keycloak does not automatically include user attributes in the assertion it sends to your SP. You must add mappers to the client’s dedicated scope.

1

Navigate to Clients > <your client> > Client scopes tab

2

Select the dedicated scope link (named after your client entity ID with -dedicated appended)

3

Select Configure a new mapper > User Attribute

4

Configure the mapper:

NameUser AttributeSAML Attribute NameNameFormat
firstNamefirstNamefnameBasic
lastNamelastNamelnameBasic
emailemailemailBasic
uuiduuiduuidBasic

The User Attribute column is the field name Keycloak stored the value in from your IdP mappers. The SAML Attribute Name is the attribute name that will appear in the assertion sent to your SP.

5

Select Save and repeat for each attribute you want included in the assertion.

Screenshot showing SAML Client app mapper complete with first name, last name, email, and uuid.keycloak_saml_client_app_mapper_complete

If your SP receives a SAML assertion with a duplicate attribute name error, the role_list default client scope may be conflicting with your custom mappers. Navigate to Clients > <your client> > Client scopes and change role_list from Default to None to remove it from this client.

Configure ID.me

This portion of the configuration is completed by an ID.me Solution Consultant. You will need to provide the following information to complete the setup:

Assertion Consumer Service (ACS) URL

The Keycloak ACS URL follows this pattern:
http://localhost:8080/realms/<your-realm-name>/broker/<your external IDP alias>/endpoint

SP Entity ID

The Keycloak SP Entity ID (Handle) follows this pattern:
http://localhost:8080/realms/<your realm name>

Policy handle name

Confirm the ID.me policy handle with your Solution Consultant. This value determines the identity verification level and attributes returned in the SAML assertion, and is configured in Keycloak as your AuthNContextClassRef.

Keycloak signing certificate

You must provide your Keycloak signing certificate (in PEM format) to your Solution Consultant. You can find this in Keycloak under Realm Settings > Keys (Algorithm: RS256, Type: RSA, Use: SIG).

Test the integration

1

Navigate to your SP’s login initiation URL (for example, http://localhost:8081/initiate?forceAuthn=true in this guide).

2

On the Keycloak login page, select the button for your external IdP (for example, IDMe-Sandbox).

3

Complete authentication and identity verification at ID.me per your policy settings

4

Verify you are redirected back to Keycloak and then from Keycloak to your SP’s ACS URL with a valid assertion from Keycloak. In this guide, the sample Python app displays the ID.me attributes returned in the assertion including fname, lname, email, uuid.

Screenshot of custom, local Python app displaying successful SAML transaction and displaying first name, last name, email, and UUID ingested from SAML assertion from Keycloak
5

In your Keycloak admin console, verify the new user appears under Users.

Screen of Keycloak admin tool user list showing new user created via automatic provisioning from ID.me into Keycloak

Troubleshooting

You do not see your configurations

Always ensure you are in the correct realm. Each time you log in, Keycloak defaults to the master realm.

User not created in Keycloak

This can occur due to missing attribute mappings or a misconfigured login flow. Check your mappers and ensure your “First Login Flow” setting is correct.

Assertion validation failed

This typically happens because of clock skew or an incorrect ACS URL. Check the timestamps and verify the ACS URL in your configuration.

AuthnRequest rejected by ID.me

This often points to a Keycloak signing certificate mismatch. Verify that the certificate uploaded to ID.me matches the active signing certificate in Keycloak under Realm Settings > Keys > RS256.

ID.me assertion not trusted by Keycloak

Keycloak does not evaluate the active=true attribute in ID.me metadata during ingestion of the ID.me metadata and may auto-populate an inactive certificate. In such cases, you must manually enter the ID.me signing certificate labled with the active=true element from the ID.me metadata.

ID.me rejects unsigned request

Keycloak is likely not signing AuthnRequests. Enable Want AuthnRequests Signed on the Identity Provider configuration in Keycloak.

User auto-provisioning on first login

With the default first broker login flow, Keycloak auto-creates users upon their first successful login.

Attribute mappers required for each claim

Keycloak does not automatically map SAML assertion attributes to user fields. You must create a mapper for each attribute you want stored in Keycloak.

Invalid requester error from Keycloak

The Client ID configured in Keycloak does not match the entity ID your SP sends in the AuthnRequest. Verify that the Client ID in Clients > your client > Settings matches your SP’s entity ID exactly (for example, http://localhost:8081/saml/metadata).

Duplicate attribute name error in SP assertion

The role_list default client scope adds a Role attribute that conflicts with custom mappers when attribute names collide. Navigate to Clients > your client > Client scopes and change role_list from Default to None to remove it from this client.

Attributes missing from SP assertion

No mappers are configured on the dedicated client scope, so Keycloak does not include user attributes in the assertion it sends to your SP. Navigate to Clients > your client > Client scopes > the dedicated scope (named after your client entity ID with -dedicated appended) and add a User Attribute mapper for each attribute you want included.