Keycloak and Drupal SSO integration

Keycloak becomes the sign-in point for Drupal through the contributed OpenID Connect module, with accounts created on first sign-in and roles mapped from Keycloak. This page covers the build sequence, the mapping decisions and the failure points to plan for.

On this page

How Keycloak SSO integration works for Drupal

Teams that run Drupal and Keycloak and want one login for editors and site users can do this with the contributed OpenID Connect module. The supported route is that module, with Keycloak acting as the OpenID Connect provider and Drupal acting as the relying party. Drupal sends the user to Keycloak, receives the result of the sign-in, and decides what the user may do on the site. Before the build starts, confirm on the OpenID Connect project page which client plugins are available for your Drupal version, because the module ships built-in clients for generic OAuth 2.0 and several named providers. If no dedicated Keycloak client is listed, plan to configure the generic OAuth 2.0 client against Keycloak's OpenID Connect endpoints.

The module authenticates users against the external provider and, by default, creates a Drupal account on first sign-in. Keycloak keeps the credentials, password policy, multi-factor settings, sessions and the realm or client definitions. Drupal keeps the content permissions, roles, user fields and the local account record that its content and revisions point to. That split is the main design decision. Decide early which identities may log in to Drupal at all, whether Keycloak groups or client roles should drive Drupal roles, and what happens to a Drupal account when the matching Keycloak user is disabled. Drupal sites often keep a local administrator account for recovery, so confirm how that account is protected and who can use it.

Treat the account-creation and role-mapping behavior as a verification item, not an assumption. Run a test sign-in for an editor, a site visitor and a disabled Keycloak user in a non-production copy, then check the resulting Drupal roles, the email and name fields, and whether a second sign-in links to the existing account instead of creating a duplicate. Record which Keycloak claims the module reads, since a missing or differently named claim is the most common cause of incorrect roles. Ask your implementation partner to document this mapping in writing so that a Keycloak upgrade or a Drupal major upgrade does not change access silently.

Prerequisites for a Keycloak and Drupal SSO build

Most delays in a Keycloak and Drupal sign-in project come from decisions made before any client is configured. The items below set the Drupal version, the Keycloak baseline, the network identity of both sites and the way modules reach production. Settle them in writing first, because each one changes what the OpenID Connect configuration looks like.

Drupal version and PHP plan

Drupal 11 requires PHP 8.3 or later and Drupal 10 requires PHP 8.1 or later. Drupal 10 reaches end of life on December 9, 2026, so a build started now on Drupal 10 will need an upgrade soon after launch. Confirm the target major version first, then confirm that the hosting platform can run the matching PHP version and that the contributed OpenID Connect module supports it.

Keycloak minor version standard

The current Keycloak release is 26.8.1, published October 13, 2026. Since Keycloak 26.0, minor releases arrive four times a year and breaking changes in minor releases are opt-in. Confirm which Keycloak 26 minor version your organization will standardize on, and record it, before writing client settings, because the admin console labels and some options differ between releases.

Production database for Keycloak

Keycloak's supported production databases include PostgreSQL 14 to 18, MariaDB, MySQL, Microsoft SQL Server, Oracle Database and Azure SQL. The default dev-file database is for development only. Confirm the database engine, its backup and restore process and whether the team will use Keycloak's automatic schema migration at startup or apply schema changes manually for a larger deployment.

DNS, TLS and callback URLs

Both the Keycloak server and the Drupal site need stable DNS names and valid TLS certificates. The Drupal redirect URI registered in Keycloak must match the public Drupal address exactly, including scheme and path, and the Keycloak issuer URL must be reachable from the Drupal server, not only from users' browsers. Plan the callback URLs for each environment, including staging, before the client is created.

Keycloak realm administration

Create or confirm a Keycloak realm that the Drupal site will use, plus at least one named administrator account with rights to create clients, mappers and roles in that realm. Decide who holds this access after launch and whether production changes go through a documented approval step. Avoid sharing the bootstrap administrator account, since it is the path back into the identity provider if other accounts fail.

Composer-based Drupal build pipeline

The OpenID Connect module and its dependencies should be installed with Composer, pinned in composer.lock and deployed through the same pipeline as the rest of the site. Confirm that the team can build, test and promote code across environments without editing files on a production server. Client secrets and the Keycloak URL belong in environment configuration, not in exported configuration files committed to the repository.

Configuring Keycloak and Drupal in the right order

This sequence moves from a clean Keycloak client to a Drupal site that signs users in, maps their claims and creates accounts only after a non-admin sign-in has been proven. Each step closes with a check, so a fault is found at the step that caused it.

  1. Confirm the realm and its ownership

    Decide whether Drupal uses a dedicated realm or an existing one, and record who administers it and who can change clients and users. Keep Drupal's login apart from unrelated applications where possible, so client changes for one system do not affect another. The step is done when the realm name, its administrators and its user population are written down and a test user exists in the realm. Confirm the choice with your Keycloak administrators, since realm structure is hard to unwind once applications depend on it.

  2. Create a confidential client with exact redirect URIs

    In the Keycloak admin console, create an OpenID Connect client with client authentication enabled, so it is confidential and holds a secret. Add one redirect URI per Drupal environment, such as development, staging and production, using the exact callback path the OpenID Connect module shows on its configuration screen. Avoid wildcards for production. The step closes when the client's settings page lists every environment's callback and the client shows a credentials tab with a secret. Ask your Keycloak team to confirm the client's scopes before you move on.

  3. Store the client secret outside the codebase

    Place the client secret in your secrets store or in environment configuration managed by your deployment tooling, not in exported configuration or the Git repository. Give each Drupal environment its own secret, and record who can read and rotate it. Check that the secret does not appear in any file under version control by searching the repository and the exported Drupal configuration. The step is done when the secret is available to the web runtime and a search of the codebase returns nothing. This matters because a leaked secret lets any holder impersonate the client.

  4. Install and enable the OpenID Connect module

    Add the contributed OpenID Connect module to the Drupal project with Composer, so the version is pinned in the lock file and deployed like other code. Enable the module with Drush or the extensions screen on a non-production environment first. Confirm that the module's configuration page loads without errors and that the Drupal status report shows no missing dependencies. The step closes when the module is enabled from version control, and the build reproduces it on a clean environment. Check the module's Drupal.org page for the Drupal core version it supports before you pin it.

  5. Enter the issuer and client settings in Drupal

    Configure a generic OpenID Connect client in Drupal with the Keycloak realm's issuer URL, the client ID and the secret read from your secrets store. Request the standard scopes your mapping depends on, and confirm the endpoints the module discovers match the realm in Keycloak. Test the login button on the login page. The closing check is a successful callback in the Drupal log and a token whose issuer and audience match the expected realm and client, which you can inspect with the developer tools or Keycloak's event log.

  6. Map claims to Drupal user fields

    Decide which token claims populate the Drupal username, email address and any profile fields, and write the mapping in the module's settings. Keep the mapping minimal and document each claim's source in Keycloak. Where a role or group claim drives access, confirm the claim name and format in a real token before mapping it. The step is done when a test sign-in populates the expected fields on the Drupal user record and an unexpected claim does not overwrite an existing value. Verify with an account whose attributes you control.

  7. Test sign-in with a non-admin account

    Sign in with an ordinary Keycloak user who has no administrative role, using an existing Drupal account that you created for the test. Confirm the user reaches the expected page, has only the roles that account should hold, and cannot reach the administration pages. Then sign in with a user from outside the allowed Keycloak group and confirm the login is denied. The step closes when both results match the access policy you wrote down earlier. Keep these test accounts in your test plan so later changes can be retested against the same cases.

  8. Enable account creation on first sign-in

    Only after the earlier tests pass, turn on account creation for first-time sign-ins in the module settings, limited to users who meet the group condition. Sign in once with a new allowed user and confirm the account is created with the mapped fields and no administrative roles. Then check the Drupal user list and the audit or watchdog log for the creation event. The step is done when the new account matches the mapping, and the denied account from the previous step still cannot create an account. Review this setting with your security team before enabling it in production.

Mapping Keycloak claims to Drupal users and fields

This table compares each identity attribute Keycloak can send with the Drupal user field it should populate, whether that value refreshes on every login, and who should own the decision. Exact claim names depend on the client scopes and mappers your team configures in Keycloak, so confirm each mapping against the OpenID Connect module documentation before go-live. The main takeaway is that email and role mappings carry the most risk, so settle those rules first.

Identity attributeKeycloak sourceDrupal targetUpdates on each loginDecision owner
Username or subjectSubject (sub) claim or a mapped username attributeDrupal username plus a stored external identifierNo, set at account creationIdentity team with Drupal lead
Email addressEmail claim from the email scope or a user attribute mapperDrupal mail fieldYes, with a rule for changed emailsSecurity and Drupal lead
Given nameGiven name claim or first name attribute mapperFirst name profile fieldYesDrupal content or site owner
Family nameFamily name claim or last name attribute mapperLast name profile fieldYesDrupal content or site owner
Group or role claimsGroup membership or client role mapperDrupal roles through an explicit mapping tableYes, assigned and removed by ruleSecurity lead with business owners
Locale or languageLocale claim or user language attributeUser preferred language settingYes, unless users change it in DrupalMultilingual site owner
Account statusEnabled flag or disabled user stateDrupal account blocked or activeYes, confirm behavior for disabled usersIdentity team

What changes for role mapping in the 2.x branch

Role mapping is where Keycloak and Drupal SSO projects most often break on upgrade, and the topic brief flags changes in the 2.x branch of the OpenID Connect module as a reason to treat it as its own piece of work. Before you choose a mapping approach, read the 2.x release notes and the issue queue on the OpenID Connect / OAuth client module project page. Look for open issues about role assignment, role removal and claim handling, and note which ones affect the exact version you plan to run. Do not assume that a mapping configured for an earlier release will behave the same way on 2.x. Confirm the behavior against the release you install, not against older blog posts or community examples.

Test two cases before go-live. The first is a role grant: a user added to the relevant Keycloak group should receive the matching Drupal role at the next sign-in. The second is a role removal: when that user leaves the group, the Drupal role should be removed as well. Many teams test only the grant, and the removal case is where stale access builds up unnoticed. Confirm in the module documentation and in your own staging environment whether removal happens at every sign-in, only under certain conditions, or through another path. Run both cases against a staging site that mirrors the production Keycloak realm, and repeat them for each release you upgrade to.

Decide up front which roles Keycloak owns and which Drupal keeps locally. Roles that describe organizational membership, such as a staff or department group, are usually good candidates for Keycloak control. Roles a site administrator assigns for editorial reasons, such as an editor role granted to a content lead, usually belong in Drupal, and the mapping configuration should never remove them during sign-in. Record this split in your design document as a short table of roles, owners and removal behavior, then check that no mapping rule can touch a locally managed role. Review the table again whenever the module or the Keycloak realm changes.

Security controls for Keycloak SSO on Drupal

These controls cover the trust between Drupal and Keycloak, the identity policy that Keycloak enforces, and the patch routine that keeps both systems current. Each one is a decision your team should record before go-live, because a gap in any of them lets a session or credential outlive the access it was meant to grant.

Confidential client with a stored secret

Register the Drupal site in Keycloak as a confidential client, so the client secret is required at the token exchange. Keep the secret out of exported configuration and out of the Drupal database in plain text, and supply it through environment variables or a secrets manager such as OpenBao. Ask who can view and rotate the secret in the Keycloak admin console, and record the rotation procedure so a leaked secret can be replaced without a site outage.

Exact redirect URIs in production

List each callback URL explicitly in the Keycloak client settings, including the scheme and host of the production Drupal site. Wildcards in redirect URIs let an attacker register a lookalike path and receive authorization codes meant for your site. Review the list during every environment change, and remove test hosts and old domains as soon as the migration that needed them is finished.

TLS on both browser and back channel

Serve Keycloak and Drupal over HTTPS, and make sure Drupal validates the Keycloak certificate chain on its server-to-server calls for the token and user-info requests. Disabling verification to clear a certificate error during setup often stays in place. Confirm that the internal CA bundle is installed on the Drupal hosts and that the certificate renewal process covers both endpoints.

MFA and password policy in Keycloak

Enforce multi-factor authentication, password rules and lockout behavior in Keycloak's authentication flows, not in Drupal. Drupal only sees the result of the login, so policies set in Drupal's own forms are bypassed when users sign in through the identity provider. Check that local Drupal password login is disabled for SSO users, or that it is restricted to a documented break-glass account.

Offboarding and the Drupal session

Disabling a user in Keycloak does not automatically end a Drupal session that is already open, and the Drupal account remains until someone blocks it. Decide whether Drupal should block the account at the next sign-in attempt or whether an administrator must act, then test both cases with a departed-user scenario. Ask how long access tokens remain valid after disablement, and set session lifetimes to match your risk tolerance.

Patch routine for both platforms

Schedule Keycloak minor releases and Drupal security releases on a single calendar. Drupal publishes security releases on the third Wednesday of each month, so use that date as the review point. Keycloak recommends manual approval for operator updates, which should be applied in a staging environment first. Track vulnerabilities in contributed modules such as the OpenID Connect client through the Drupal Security Team advisories, and assign an owner to read them each month.

Multilingual login decisions for Keycloak and Drupal

If the Drupal site and its users work in one language, most multilingual decisions drop out. The work is still configuration, because Keycloak chooses the language of the login page, error messages and required action emails from the realm settings and the user's locale. Keep the realm on one default locale and confirm that the messages in that locale match what your users read. Drupal then needs only one language, with no language negotiation to reason about.

  • Realm default locale: Set the realm's default language in the Keycloak admin console so the login page does not change for visitors whose browsers send a different language.
  • Supported locales: Limit the realm to the locale you can review, so users cannot switch to a language your team cannot check.
  • Required action emails: Review the verify email and password reset templates in the realm email settings, since users receive these before they reach Drupal.
  • Drupal language setup: Keep Drupal on a single language, and confirm that any account fields your claim mapping writes do not store a language value that conflicts with the site.

Check the default locale in each realm environment, then run a sign-in and a password reset from a clean browser profile.

Common Keycloak and Drupal SSO failures and fixes

This table pairs common Keycloak and Drupal sign-in failures with their likely causes, the checks that confirm each cause, and the fix to apply. Read it top to bottom during testing, or jump to the symptom that matches the error your users see. Most failures trace back to a mismatch between what Drupal sends and what the Keycloak client expects.

SymptomLikely causeCheckFix
Keycloak shows an invalid redirect URI error after sign-inDrupal's callback path does not match a valid redirect URI on the Keycloak clientCompare the redirect URI in the client settings with the callback path shown in the Drupal OpenID Connect configuration, including scheme, host and trailing slashAdd the exact Drupal callback URL to the client's valid redirect URIs, then retest from a private browser window
Token exchange fails with unauthorized client or invalid secret after rotationThe client secret was regenerated in Keycloak but the Drupal configuration still holds the old valueCheck the Keycloak client credentials tab and the Drupal client secret field, and review the Drupal log for token endpoint errorsEnter the new secret in Drupal, clear caches, and store the value in your secrets manager so future rotations stay in sync
Discovery fails or the login button is missingIssuer or discovery URL points at the wrong realm or a misspelled realm nameOpen the realm's well-known OpenID configuration URL in a browser and confirm the issuer value matches the one in Drupal exactlyCorrect the issuer to the target realm, then confirm endpoints resolve from the Drupal server, not just from your workstation
Tokens are rejected with messages about tokens not yet valid or expiredClock skew between the Keycloak host, the Drupal web servers and the token issuerCompare UTC time on each host and check whether the failures cluster on one nodeSynchronize all hosts with a time service, then confirm the failures stop before changing token lifetime settings
Users are blocked or sign-in creates a duplicate or fails with an email conflictAn existing Drupal account already uses the same email address as the incoming Keycloak userSearch the Drupal people list for the email, and review how the module matches existing accounts (by username, email or subject identifier)Decide the matching rule in the design phase, link or migrate existing accounts deliberately, and resolve duplicates before go-live
Users sign in but lack expected rolesThe claim Drupal reads for roles has a different name or structure than the one Keycloak sendsDecode a sample ID or access token for a test user and compare claim names with the role mapping configured in DrupalAlign the claim name in the mapping, or add a client scope mapper in Keycloak that emits the claim, then retest with a test account
Users are locked out after a Keycloak upgradeA minor or major release changed defaults, endpoints, client settings or the database schema, or an automatic upgrade ran unexpectedlyReview the Keycloak release notes and upgrading guide for the versions crossed, check the server logs for schema or configuration warnings, and confirm the Drupal module version supports the new flowPin the Keycloak version, review the release changes in staging first, and use manual approval for operator updates where the Operator is in use
Login loops back to the sign-in page behind a reverse proxyThe proxy does not forward the original protocol header, so Keycloak or Drupal builds http redirect URLs for an https siteInspect response headers and the redirect chain with a browser developer tool, and confirm the proxy forwards the protocol and host headers to both servicesConfigure the proxy to pass the forwarded protocol and host headers, set Keycloak's proxy mode for your topology, and confirm Drupal's trusted host and reverse proxy settings match

Questions teams ask before building Keycloak SSO for Drupal

What drives the cost of Keycloak SSO for Drupal?

The cost is driven mainly by how many Drupal environments need sign-in, how complex the claim and role model is, how many languages the login pages must support, how many existing accounts must be matched, and whether Keycloak is already running in production. Each of these adds configuration, testing and cutover work. A new Keycloak deployment adds infrastructure and database decisions on top of the Drupal work. Keycloak and the OpenID Connect module are open source, so license fees are not the cost driver. The cost is labor: planning, configuration, testing and handover. Ask any partner for a quote that separates one-time build work from recurring support, and that lists each environment and language in scope.

How long does a Keycloak SSO integration for Drupal take?

The duration depends on the same factors that drive cost: the number of environments, the role model, the languages, the user matching rules and the state of your Keycloak service. A team that already runs Keycloak on a supported database with a tested high availability design has less to build than a team starting from zero. No duration is fixed here. Ask for a timeline in the written scope, and check that it includes time for a staging test with real test accounts, a cutover plan for existing users and a rollback step.

What does our team need to provide before the work starts?

Your team needs to provide a Keycloak instance or a decision to deploy one, administrator access to create a realm and clients, the Drupal environments that will use sign-in, and a list of the roles and groups that should map to Drupal roles. You also need a decision on how existing Drupal accounts will be matched to Keycloak users, and the list of languages for the login pages. Named contacts for Keycloak, Drupal and identity policy should be available for decisions during the build. Confirm the exact access model in your own environment before the scope is signed.

Can our internal team build Keycloak SSO for Drupal alone?

An internal team with Drupal and Keycloak experience can build the integration, and the work is well documented on Drupal.org and keycloak.org. The main risks are in the claim and role model, the account matching rules and the testing of sign-in across environments, languages and existing users. Teams without recent Keycloak administration experience often find the realm, client and token settings take longer than the Drupal module configuration. Compare your team's current skills against the list of tasks in the scope, and decide whether to build in house, bring in a partner for the design and handover, or buy ongoing support.

Do we need to upgrade Keycloak and Drupal together?

No, they are separate systems and you do not have to upgrade them at the same time, but you do need to check compatibility at each step. Keycloak documents that breaking changes in minor releases are opt-in, and it plans four minor releases a year. Drupal has its own release schedule, and the OpenID Connect module must be checked against the Drupal version you run. Plan each upgrade in a staging environment with test sign-ins for every client. Keep Keycloak's upgrade notes and the Drupal module release notes with the change record, and check the Keycloak upgrading guide before each move.

Does Keycloak have to run on Kubernetes for Drupal SSO?

No. Keycloak does not require Kubernetes for this integration, and the Drupal module only needs a reachable OpenID Connect endpoint. Keycloak can run on virtual machines or bare metal you control, provided it uses a supported production database and a high availability design with a synchronously replicated database. The Keycloak Operator is one installation option, installed through Operator Lifecycle Manager, kubectl or an experimental Helm chart. Choose the hosting model based on the platform your operations team already runs and supports.

What should a written quote for Keycloak SSO for Drupal include?

A written quote should list the scope in plain terms, including each Drupal environment, each Keycloak realm and client, the role and group mapping rules, the languages and the existing user matching method. It should name the deliverables, such as configuration documentation, test cases, a cutover runbook and a handover session. It should state what is excluded, such as Keycloak infrastructure, database or high availability work if those are out of scope. Ask for the assumptions the timeline depends on, the client responsibilities, the acceptance steps and the separate cost of any ongoing support. Fixed-scope quotes are agreed in writing before work starts, so make sure the scope is complete before you sign.

Is a Keycloak SSO integration for Drupal ready for a compliance review?

The integration can be documented in a way that supports a compliance review, but DeployOpen does not issue audit reports, attestations or certifications. Independent auditors and certification bodies make those determinations. Useful evidence includes the realm and client configuration, the list of roles and their mapping rules, test results for sign-in and sign-out, access reviews for administrators, and the logs kept from Keycloak and Drupal. Ask your auditor which controls apply to your organization and which evidence they expect, before the build begins.

How DeployOpen scopes and delivers Keycloak SSO for Drupal

DeployOpen plans, builds, documents and supports Keycloak and Drupal SSO integration inside infrastructure you control, whether that is your cloud accounts, data centers or air-gapped network. Engagements are fixed-scope, with the scope, deliverables and timeline agreed in writing before work starts.

How we scope

  • Written scope covering the Keycloak realm, Drupal OpenID Connect client, user field and email sync rules, and role mapping
  • Confirmation of the Keycloak version, Drupal branch and PHP version your environment will run
  • Agreed decisions on multilingual login, account creation on first sign-in, and which users may access the site

How we build

  • Configure the Keycloak client and the Drupal module on a staging site first, with test accounts for each role
  • Test login, logout, account linking, email changes and role changes across every language your site serves
  • Record configuration, secrets handling and exceptions in a runbook your team can review and change

How we hand over

  • Documented configuration with the Keycloak client settings, module settings and mapping tables your team owns
  • Walkthrough with administrators on rotating client secrets, adding roles and reviewing failed sign-ins
  • Test evidence from the verification pass so your team and any assessor can see what was checked

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer after handover
  • Retainer scope can cover reviewing Keycloak and Drupal module release notes before each planned upgrade
  • Ask in your quote which items a retainer covers and how changes to the written scope are priced

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.