EspoCRM single sign-on with Keycloak over OpenID Connect

Connect EspoCRM to Keycloak over OpenID Connect so staff sign in with central credentials, groups map to teams and sessions end together. This page covers the configuration sequence, mapping and failure points.

On this page

How EspoCRM single sign-on with Keycloak over OpenID Connect works

If you run EspoCRM and want staff to sign in through one central Keycloak realm, the supported route is EspoCRM's OpenID Connect sign-in, available since version 7.3. Keycloak acts as the identity provider and EspoCRM acts as the relying party. Users authenticate at Keycloak, which returns an identity token that EspoCRM uses to match or create a local user. The feature set covers optional user creation on first login, mapping identity provider groups to EspoCRM teams, backchannel logout and a fallback login method for when the provider is unavailable. The EspoCRM OIDC documentation is the reference for the exact settings, and you should read it against the EspoCRM version you run before you configure anything.

Two points change how you plan the rollout. First, EspoCRM's own two-factor authentication is not compatible with OIDC, so the second factor has to be enforced in Keycloak, through its required actions or conditional authentication flows. Decide early which users need a second factor, and test that it appears at the Keycloak step and never prompts twice. Second, PKCE support was added in EspoCRM 10.0.0, so confirm which version you are running before you decide whether the client should require PKCE in Keycloak. Note that the client_secret_post method is covered in the client setup section, so it is not repeated here.

Before you build the client, confirm three things with your own team: which Keycloak realm will be the single source of staff identity, which group names in that realm should map to EspoCRM teams, and whether a local fallback administrator account will remain available if the realm is unreachable. The fallback login method matters most for recovery, because an unreachable identity provider otherwise locks out every user, including the people who would fix it. Write these decisions down, since the group mapping and first-login behavior determine how much access each new account receives.

What you need before configuring Keycloak and EspoCRM

Four decisions and checks come before any client is created in Keycloak or any OIDC setting is saved in EspoCRM. Each card below names one of them, so the platform, identity and certificate owners can agree on versions, hostnames and group design before the configuration work starts.

EspoCRM version and server stack

Confirm the EspoCRM version you will run, since OIDC sign-in is available from version 7.3 and PKCE support arrived in 10.0.0. The server documentation lists PHP 8.3 to 8.5, with MySQL 8.0 or newer, MariaDB 10.6 or newer, or PostgreSQL 15. Confirm that cron or a scheduled task runs, because background jobs depend on it and login-related syncs are easier to troubleshoot when those jobs are healthy.

Keycloak release and version pin

Pick the exact Keycloak release your platform team will run and pin it, rather than tracking whatever is newest. The current release listed is 26.8.1, but confirm it against your own upgrade policy. Keycloak plans four minor releases a year, so decide who reviews upgrade notes and how the realm configuration is exported and reapplied after each change.

Production database for Keycloak

Keycloak's dev-file database is for development only. Choose a supported production database such as PostgreSQL 14 to 18, MariaDB, MySQL, or SQL Server, and confirm who owns its backups and restores. Plan whether schema migration runs automatically at startup or is applied manually by your administrators, since large deployments often prefer the manual path.

HTTPS and certificates on both hosts

Both the Keycloak host and the EspoCRM host need valid certificates that browsers and the EspoCRM server trust, because the OIDC redirect and token exchange run over HTTPS. Confirm the public hostnames, the certificate chain, and that the EspoCRM server can reach Keycloak's token and discovery endpoints. Internal certificate authorities must be added to the PHP trust store on the EspoCRM host.

Realm groups and admin accounts

Design the Keycloak groups that will carry team membership, because EspoCRM maps identity provider groups from a configured Group Claim to Espo teams. Name them after the teams EspoCRM already uses. Create a named administrator for Keycloak and a separate named administrator for EspoCRM, and confirm that neither is a shared account used for daily work.

Configure the Keycloak client and EspoCRM OIDC settings in order

This sequence takes you from an empty Keycloak realm to a working EspoCRM sign-in flow, with group claims mapped to teams and a fallback login kept available for recovery. Each step ends with a check you can run before moving on.

  1. Create the realm and confirm the Keycloak issuer

    The identity administrator creates a dedicated realm for EspoCRM users in the Keycloak admin console, separate from the master realm, and sets the realm's login and session options to match your policy. Record the issuer URL, which follows the pattern of your Keycloak base address and the realm name. Open that issuer address in a browser or with a plain HTTP request and confirm the discovery document loads. If it does not, fix the hostname and proxy settings before going further, because EspoCRM will read the same address. Keep the realm name and issuer in your change record for later steps.

  2. Create the OpenID Connect client with client_secret_post

    In the realm, create a client with the OpenID Connect protocol, enable client authentication, and set the client authentication method to client_secret_post. EspoCRM does not support client_secret_jwt or private_key_jwt, so a provider that defaults to a JWT method must be changed before EspoCRM can exchange tokens. Enable the standard authorization code flow and keep the implicit and direct grant options off unless another requirement needs them. Copy the client secret into your secrets store. Check that the client settings show client_secret_post and that the token endpoint accepts that method, which you will confirm during the EspoCRM test in a later step.

  3. Set redirect URIs and web origins

    Add the exact EspoCRM callback URL as a valid redirect URI, using the public HTTPS address users will type into the browser and the callback path from the EspoCRM OIDC documentation. Set web origins to the same EspoCRM origin and avoid wildcards on a production client. Add a post-logout redirect URI if you want users returned to the EspoCRM login page after logout. Confirm each value character by character, since a trailing slash or an HTTP scheme mismatch is a common cause of failed sign-in. Save the client and check that the redirect URI list contains only the environments you intend to use.

  4. Add a groups claim to the ID token and access token

    Create a client scope or protocol mapper that adds a group membership claim to the ID token. Map Keycloak groups to a claim name, such as groups, and choose whether full group paths or short names are sent. The claim name must match the Group Claim value you enter in EspoCRM. Use a test user who belongs to one Keycloak group to confirm the claim appears. Decode the ID token from the test sign-in or view the claim in the user's session details in the admin console. If the claim is missing, check that the mapper is attached to the client and that the user is a direct group member.

  5. Enter the OIDC settings in EspoCRM

    As an EspoCRM administrator, open the OIDC authentication settings in the Administration area and enter the issuer URL, client ID and client secret from the Keycloak client. Enter the groups claim name from the previous step as the Group Claim. Keep the fallback login method enabled so a local administrator can still sign in if the identity provider is unavailable. Save the settings and confirm that the login page shows the OIDC sign-in option alongside the standard form. Clicking the option should redirect you to the Keycloak login screen, which shows that discovery and the redirect were accepted.

  6. Enable user creation and team mapping

    Turn on user creation on first login so Keycloak users receive an EspoCRM account the first time they sign in. Configure the group-to-team mapping so each Keycloak group value maps to the EspoCRM team with the same purpose, and decide whether profile and team membership should be synced on every login or only on first login. Start with a small test group. Sign in as a test user from that group and confirm that the new user record exists, that the user holds the expected team, and that the role assigned by your access model grants only the intended permissions. If the user has no team, check the group value and the mapping spelling.

  7. Test sign-in, token exchange and logout with the fallback login

    Sign in through the OIDC option with the test user and confirm the redirect back to EspoCRM completes, which shows the token exchange succeeded with client_secret_post. Then sign out and confirm that backchannel logout ends the EspoCRM session when the user logs out of Keycloak, using the backchannel logout endpoint described in the EspoCRM OIDC documentation. Finally, sign in with the fallback local administrator account to confirm the recovery path works. Do not use the fallback account for daily work. Record the test results, including the user, teams and logout outcome, so the configuration can be repeated in other environments.

Which Keycloak claims and groups map to EspoCRM users and teams

This table compares each identity element Keycloak sends to EspoCRM with the EspoCRM field or behavior it drives. Read it before configuring the OIDC settings, then confirm each claim name against a real token from your own Keycloak realm. The main takeaway is that group names and claim names must match exactly, and that team changes apply at the next sign-in.

Identity elementWhat EspoCRM uses it forWhat to confirm before go-live
Subject claim (sub)Stable identifier that links a Keycloak account to an EspoCRM user across loginsConfirm the value is present in the ID token and does not change when a username is edited
Username claimSets the EspoCRM login name for the matched or newly created userConfirm the claim name in your token output and that usernames are unique in the realm
Email claimPopulates the user email field and supports matching on existing accountsConfirm the email claim is emitted and that unverified addresses are handled by your policy
Given and family name claimsFill the first name and last name fields on the EspoCRM user recordConfirm the claim names and whether your Keycloak mappers emit them for every user
Group ClaimCarries the Keycloak group list that EspoCRM reads to decide team membershipConfirm the claim name, that it is included in the token, and the format of each group value
Team name matchEach Keycloak group value must match a configured team mapping exactly to assign that teamConfirm spelling, letter case and any path prefix in group names against the EspoCRM team mapping
Team sync on loginWhen enabled, team membership is refreshed at each sign-in, so removals in Keycloak also apply thenConfirm that users removed from a group lose access to that team only after their next login

Hardening the EspoCRM and Keycloak trust relationship

Once EspoCRM delegates sign-in to Keycloak, the security of your CRM depends on how both systems are configured together. The cards below cover the client secret, redirect URIs, the recovery path, identity controls that move to Keycloak, token lifetimes and admin account separation. Each one is a decision to make and check before go-live.

Client secret storage and rotation

The OIDC client secret is the credential EspoCRM presents to Keycloak when it exchanges an authorization code, so anyone holding it can impersonate the client. Keep it out of configuration files in version control, store it in your secrets manager, and restrict who can read the EspoCRM administration screen where it is entered. Agree a rotation procedure with your team that updates the Keycloak client and EspoCRM together, and test it in a non-production realm first. Confirm with your Keycloak administrators who can regenerate the secret.

Exact redirect URI matching

Configure the Keycloak client with the single redirect URI for your EspoCRM host, using the full scheme and path that EspoCRM documents, and avoid wildcards or several hosts. Broad redirect patterns let an attacker who controls another page on a permitted host receive authorization codes. Review the list of valid redirect URIs whenever you change the EspoCRM domain, add a staging instance, or move behind a new reverse proxy. Also check the Web Origins setting so that only your EspoCRM origin is allowed.

Protecting the fallback login

EspoCRM can keep a fallback login method alongside OIDC, which is your recovery path if Keycloak is unavailable or a realm configuration breaks. Keep at least one named administrator on that path, store its credential in a sealed location, and document who may use it and under what approval. Restrict the fallback to trusted network ranges where your security policy allows. Test the recovery procedure before go-live so that the first real outage is not the first test.

Identity controls that now sit in Keycloak

EspoCRM's own two-factor authentication is not compatible with OIDC, so second factors, password rules and lockout behavior have to be enforced in the Keycloak realm. Set the required actions, password policy and brute-force detection there, and require a second factor for every user who reaches EspoCRM. Disable password recovery for EspoCRM administrators, since EspoCRM's security guidance recommends this, and confirm that Keycloak's recovery flow cannot reset an administrator's account for the CRM. Ask your security team to confirm the realm settings against your written policy.

Token lifetime and network restrictions

Shorten access and session lifetimes in the Keycloak realm so that a stolen token has a limited window, and align the idle timeout with the EspoCRM session policy you choose. Use Keycloak's client and realm session settings rather than relying on EspoCRM alone to end sessions. Where your network allows, restrict access to the EspoCRM host and Keycloak administration console by IP address, and keep the admin console off the public internet. Verify logout behavior with backchannel logout in a test session before relying on it.

Keeping admins off daily accounts

Create a separate, named administrator account in EspoCRM and in Keycloak for privileged work, and use an ordinary user account for everyday sales and service tasks. Map only the groups that need administrative rights to EspoCRM roles, and review those group-to-team mappings when staff change roles. Log administrative actions in both systems so that changes to group claims and teams can be traced. Ask your team to confirm how administrator access is requested, approved and removed.

Why EspoCRM sign-in fails after the Keycloak client is set

Why does EspoCRM return an invalid client or token error after I create the Keycloak client?

The most common cause is a mismatch in client authentication method. EspoCRM does not support the client_secret_jwt or private_key_jwt methods, but Keycloak may default to a JWT-based method for the client. Open the client in the Keycloak admin console, check the client authentication setting for the token exchange, and make sure client_secret_post is enabled so that EspoCRM sends the client ID and secret in the request body. Then confirm that the client secret in EspoCRM matches the one shown in Keycloak. Re-save the EspoCRM OIDC settings after any change, because a stale secret produces the same error.

What causes a redirect URI mismatch error when signing in to EspoCRM with Keycloak?

Keycloak only redirects to URIs listed in the client's valid redirect URIs, and the value must match the callback EspoCRM sends exactly, including scheme, host, port and path. A common mistake is registering http when the site runs on https, or registering a bare domain when EspoCRM is reached at a subdirectory or a different hostname. Copy the redirect URI from the EspoCRM OIDC settings page rather than typing it from memory, and keep one entry per public hostname. Avoid wildcards for production clients unless your security review accepts them.

Why are users created in EspoCRM without the teams I expected?

Team mapping depends on the group claim. If the claim is missing from the ID token or access token, or if its name in EspoCRM does not match the claim Keycloak sends, EspoCRM has no groups to map and users land without teams. Add a group membership mapper to the Keycloak client (or a client scope) that emits the groups claim, confirm the claim name in the EspoCRM OIDC settings, and check the exact group paths, since Keycloak can send full paths such as /sales/emea depending on mapper settings. Then sign in as a test user and inspect the claims to confirm the output before relying on the mapping for access control.

Why does backchannel logout not end the EspoCRM session when a user signs out of Keycloak?

The most likely cause is that Keycloak cannot reach the EspoCRM backchannel logout endpoint, which is served at api/v1/backchannelLogout on the EspoCRM host. Keycloak sends the logout request from its own server, so a private hostname, a firewall rule, a proxy that blocks POST requests, or a certificate that Keycloak does not trust will all stop it. Confirm that the client has the backchannel logout URL set and that Keycloak can reach it from the network where it runs. Check the Keycloak event log and the EspoCRM logs for rejected requests. Test with a short-lived session so you can see the result quickly.

Why does EspoCRM loop between the login page and Keycloak behind a reverse proxy?

A sign-in loop usually means EspoCRM builds its URLs with the wrong scheme or host, so the redirect it sends back does not match what the browser used, or the session cookie is not accepted. Behind a TLS-terminating proxy, EspoCRM often sees plain http and an internal host name. Configure the proxy to forward the original Host header and X-Forwarded-Proto set to https, and make sure the site URL in EspoCRM uses the public address. Confirm the proxy configuration against the EspoCRM deployment documentation for your web server, and check that the cookie domain and secure flag match the public hostname.

Can my own administrator fix these issues, or do I need a partner?

Most of these failures are configuration issues that an experienced administrator can diagnose with the Keycloak admin console, the EspoCRM logs and a test account. Your team can work through them if it has access to both systems, can change the reverse proxy and can read the claims a token carries. A partner is more useful when the setup involves multiple hostnames, high availability, several identity brokers or strict change control. Engagements at DeployOpen are fixed-scope, so the scope for troubleshooting and the environment you want covered are agreed in writing before work starts, and the quote follows from that scope.

How long does it take to fix an EspoCRM and Keycloak sign-in problem?

The time depends on which failure you hit and how much access your team has. A redirect URI or client secret error can often be resolved in a short session once the logs are visible. Team mapping and backchannel logout take longer because they require checking claims, network paths and proxy rules across two systems. Ask for the scope, the environments involved and the access needed in the written proposal, because those factors drive the schedule more than the error itself. No duration is given here because none has been established for your environment.

Common Keycloak and EspoCRM OIDC failures, causes and fixes

This table lists the failures teams most often hit when wiring Keycloak to EspoCRM over OpenID Connect, with the likely cause and a check that confirms the fix. Work through it in order during testing, since several failures show the same symptom, a login that bounces back to the sign-in page. Confirm each check in a staging instance before changing production.

FailureLikely causeCheck that confirms the fix
Login fails at token exchangeKeycloak client expects client_secret_jwt or private_key_jwt, which EspoCRM does not supportClient authentication set to client_secret_post in the Keycloak client, then a test sign-in succeeds
Keycloak shows invalid redirect URIRedirect URI in the Keycloak client does not exactly match the EspoCRM site URL, including scheme and pathValid redirect URIs in Keycloak match the URL EspoCRM sends, character for character
User lands with no teamsGroup claim missing from the ID token or not named as configured in EspoCRMToken preview in Keycloak shows the groups claim, and the EspoCRM group claim name matches it
Group claim present but teams unchangedGroup names in Keycloak do not match the Espo team names or identifiers configured for mappingTest user's teams update on next login after names are aligned
Valid user rejected on first loginAutomatic user creation is disabled in EspoCRM, so no account is createdAutomatic user creation enabled for the test user, or the account is created manually and then signs in
Logout does not reach EspoCRM sessionsKeycloak cannot reach the backchannel logout endpoint, often due to internal DNS, TLS trust or firewall rulesKeycloak admin event or log shows a successful backchannel call to the api/v1/backchannelLogout endpoint
Session ends early or tokens expire unexpectedlyClock skew between Keycloak, EspoCRM and the web server, or token lifetime set shorter than the expected sessionAll hosts use time synchronization, and Keycloak token lifetimes match the session policy agreed with the business
Sign-in loops after password changeFallback login disabled while OIDC is required, or EspoCRM 2FA enabled, which is not compatible with OIDCAdmin fallback login path tested, and EspoCRM 2FA confirmed off for OIDC users

What EspoCRM and Keycloak SSO work costs and requires

What drives the cost of an EspoCRM and Keycloak SSO setup?

The main drivers are how many groups must map to EspoCRM teams, whether Keycloak already has a realm you can use or whether a new one must be designed, whether users come from LDAP or an upstream identity provider that Keycloak must broker, and how much testing the rollout requires. Each added group needs a naming decision, a membership rule and a test case. Brokering an upstream provider adds configuration on both sides and more failure modes to verify. A written scope should state which of these apply, because they change the work far more than the EspoCRM settings themselves.

Can an internal team set up Keycloak SSO for EspoCRM without a partner?

Yes, a team with Keycloak and EspoCRM administration skills can follow the documented steps, provided it has time to test them. The EspoCRM OIDC documentation covers the settings, including the client authentication method, group claim, user creation on first login and backchannel logout. The harder part is the surrounding design: deciding the group structure, confirming how the group claim appears in tokens, handling existing local accounts and proving logout behavior. Teams without prior OIDC experience usually spend most of their effort on those checks rather than on configuration.

What do we need to provide before the work starts?

You need administrator access to the Keycloak realm and client settings, administrator access to EspoCRM, and a decision owner for group design. Group design means agreeing which Keycloak groups correspond to which EspoCRM teams and who approves changes. You also need a set of test users covering each role and team, including at least one user who should be denied access. Network paths between the browser, EspoCRM, and Keycloak must be open for the redirect and token exchanges, and you should confirm the hostnames and TLS certificates in advance.

How do Keycloak release updates affect the EspoCRM integration?

Keycloak publishes four minor releases a year and a major release every two to three years, and the project states that breaking changes in a minor release are opt-in. That lowers the risk of a surprise break, but each upgrade still needs a regression check of login, group sync, token lifetime and logout on a staging copy. Your upgrade plan should name who runs the check and which EspoCRM version is paired with which Keycloak version. Read the Keycloak upgrading guide before each planned upgrade.

Which parts of this work recur after go-live?

The one-time work is the initial client setup, group mapping, testing and documentation. Recurring work includes re-testing after Keycloak and EspoCRM upgrades, reviewing group membership rules when the organization changes, rotating the client secret on your schedule, and monitoring failed logins. Because EspoCRM's own two-factor authentication is not compatible with OIDC, multi-factor enforcement must be handled in Keycloak, which adds a recurring policy review. Ask any partner to state which of these items are included in fixed-scope delivery and which fall under a retainer.

What should we ask for in a written quote for this work?

Ask for a scope that lists the Keycloak version and deployment model, the EspoCRM version, the number of groups to map, whether an existing realm or LDAP source is involved, and the number of test users and scenarios. Request a list of deliverables, including the configuration record, a test report and a runbook for user creation and logout. Ask what is excluded, such as upstream identity provider changes, certificate management or Keycloak high availability. Confirm acceptance criteria, the change process for scope additions and how post-launch support is priced.

Does LDAP or an upstream identity provider change the effort?

Yes. If users are stored in Active Directory or another directory, Keycloak may need user federation or identity brokering before EspoCRM sees any group claims, so both the upstream and Keycloak configuration must be tested. Attribute mapping, group name formats and account linking are common sources of rework. EspoCRM also documents its own LDAP authentication, so the team should decide whether OIDC through Keycloak or direct LDAP best fits the directory design. That choice should be settled in the scope, since it determines which configuration and tests are needed.

How DeployOpen scopes and delivers the EspoCRM and Keycloak SSO integration

DeployOpen plans, builds, documents and supports EspoCRM single sign-on with Keycloak inside your own infrastructure, from the Keycloak realm and EspoCRM OIDC settings through to logout behavior. Engagements are fixed-scope, with the scope, deliverables and timelines agreed in writing before work starts.

How we scope

  • We confirm which EspoCRM and Keycloak versions run in your environment and which identity sources staff use.
  • We document the client, group claim, team mapping and first-login user creation decisions in the written scope.
  • We agree which logout, fallback login and admin recovery paths are in or out of the deliverables.

How we build

  • We configure the Keycloak client with client_secret_post and set EspoCRM's OIDC settings to match, then test each login path.
  • We map Keycloak groups to EspoCRM teams and verify that role and team access matches your access model.
  • We configure backchannel logout and test session end behavior across both applications before sign-off.

How we hand over

  • We deliver a runbook covering realm settings, client configuration, claim mappings and the fallback login method.
  • We document the test cases used to verify sign-in, group sync, first-login creation and logout.
  • We walk your administrators through changes they will need to make when secrets rotate or groups change.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after handover.
  • We can review Keycloak and EspoCRM release notes and plan changes to the OIDC configuration before upgrades.
  • We confirm with your team which support scope and response arrangements apply, as set out in the written agreement.

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.