Mutual TLS (mTLS) Client Authentication — Keycloak
A zero-prior-knowledge guide to the strongest way an application can prove its identity to Keycloak — not with a secret it merely knows, but with a certificate no one else can produce.
When you visit a secure website, your browser checks the site’s certificate before trusting it — that is a one-way handshake, the server proving its identity to you. But imagine a much higher-security scenario: a bank’s back-end system connecting to another bank’s payment network, where each side needs to be just as certain about who it is talking to. Neither system is a human clicking through a browser; both are automated services that need to prove their identity to each other, cryptographically, before a single byte of sensitive data flows. This is exactly the problem Mutual TLS, or mTLS, solves, and Keycloak supports using it as a way for an application — a Keycloak client — to authenticate itself, replacing a simple shared secret with something far harder to steal or fake: a certificate.
Foundations
Core Concepts
To understand mTLS client authentication in Keycloak, we first need to understand ordinary TLS, and then see exactly what changes when the trust becomes mutual.
What is TLS, in the form most people already use every day?
TLS, or Transport Layer Security, is the technology behind the padlock icon in a web browser. When you visit a secure website, the server presents a digital certificate proving its identity, your browser verifies that certificate against trusted authorities, and an encrypted connection is established. Critically, in this everyday scenario, only the server proves who it is. The browser — representing you — proves nothing about its own identity to the server at this stage; that is why it is called one-way TLS.
What changes with Mutual TLS?
Mutual TLS extends this same handshake so that both sides prove their identity to each other using certificates, before any application data is exchanged. The server still presents its certificate as usual, but now the client — the connecting application — must also present its own certificate, and the server verifies that certificate just as carefully as a browser would verify a website’s. Only when both sides are satisfied does the connection proceed.
Picture a high-security research facility where, normally, a visitor simply checks the building’s own credentials — a sign, a receptionist, a badge on the wall — and walks in. Mutual TLS is like a much stricter version of that same entrance: the visitor must also present their own government-issued, tamper-proof identity card, which security personally verifies against a list of trusted issuers, before the door will open at all. Both sides prove who they are, using something far harder to fake than a name spoken aloud.
What is Client Authentication, and how does mTLS fit into it?
In Keycloak, every registered client — meaning every application connecting to it — must prove its own identity before Keycloak will trust requests coming from it, a step called Client Authentication. The simplest, most common method is a shared secret, essentially a password known only to the client and to Keycloak. Mutual TLS offers a fundamentally different, stronger method: instead of proving identity by revealing a shared secret, the client proves identity by presenting a certificate during the TLS handshake itself, before the actual authentication request is even processed.
One-Way TLS
Only the server proves its identity. This is what protects your browser session on virtually every secure website.
Mutual TLS
Both sides present certificates. The client proves its identity to the server just as rigorously as the reverse.
Client Secret
A shared password-like value. Simple, but only as safe as how carefully that one secret is kept confidential.
mTLS Client Authentication
Proof by certificate, verified cryptographically, rather than by revealing a shared value that could be copied or leaked.
Structure
Architecture & Components
Several distinct pieces work together to make mTLS client authentication function correctly inside a Keycloak deployment.
The X.509 certificate
At the heart of mTLS sits the X.509 certificate, a widely used, standardized digital document that binds a specific identity — expressed through fields like a Subject and an Issuer — to a cryptographic public key, and is itself digitally signed by a trusted authority. This is the exact same certificate format used for ordinary website TLS certificates, simply issued to a client application instead of to a public-facing server.
Certificate Authorities and the truststore
A Certificate Authority, or CA, is a trusted entity that issues and signs certificates, vouching for the identity of whoever holds them. Keycloak maintains a truststore — a configured collection of CA certificates it is willing to trust — and when a client presents its own certificate during an mTLS handshake, Keycloak checks whether that certificate was genuinely signed by one of the CAs in its truststore, rather than blindly trusting any certificate presented.
The reverse proxy and TLS termination
In many real deployments, Keycloak sits behind a reverse proxy or load balancer that handles the actual TLS connection with incoming clients. In these setups, the proxy performs the mTLS handshake itself, and then passes along information about the verified client certificate to Keycloak through specific request headers, meaning Keycloak’s own configuration must be aligned with exactly how that proxy is set up to forward this certificate information correctly and securely.
The X.509 Client Authenticator
Keycloak implements mTLS client authentication through a specific client authenticator type, commonly referred to as the X.509 Certificate authenticator, configured on a per-client basis. When a client is set to use this authenticator, Keycloak expects and validates a client certificate as part of authenticating that specific client, rather than expecting a traditional client secret.
Certificate-to-identity mapping rules
Beyond simply verifying that a certificate is valid and trusted, Keycloak needs a rule for deciding which specific client a given certificate actually represents. This is handled through configurable mapping rules that examine specific fields inside the certificate — commonly the Subject Distinguished Name, or a Subject Alternative Name entry — and match them against the expected value configured for that client, ensuring the certificate presented genuinely corresponds to the client attempting to authenticate.
flowchart TD
A["Client Application"] --> B["Presents X.509 Certificate during TLS handshake"]
B --> C["Reverse Proxy or Keycloak validates against Truststore"]
C -->|"Signed by trusted CA"| D["Certificate details forwarded to Keycloak's Authenticator"]
C -->|"Not trusted / expired / revoked"| E["Connection rejected"]
D --> F["Keycloak checks Subject/SAN against configured client mapping"]
F -->|"Matches expected client"| G["Client Authentication succeeds"]
F -->|"No match"| H["Client Authentication fails"]
Fig 1 — The verification chain from a presented certificate through to a successful client authentication decision.
Every one of these components — the certificate itself, the truststore that decides who issued it can be trusted, and the mapping rule that decides which specific client it belongs to — has to be correctly configured for mTLS client authentication to work as intended. A weakness in any single link undermines the strength of the whole chain.
This chapter looks closely at what actually happens during the network handshake and the subsequent authentication check.
The TLS handshake, extended
In an ordinary TLS handshake, the server presents its certificate, the client verifies it, and a secure channel is negotiated. In a mutual TLS handshake, the server takes an additional step during this same process: it explicitly requests a certificate from the client. The client responds by presenting its own certificate, and the server verifies it using its configured truststore, entirely as part of establishing the underlying secure connection, before any actual application-level request or authentication attempt even begins.
Proof of possession, not just proof of knowledge
A crucial technical detail separates mTLS from a simple shared secret. Presenting a certificate during the handshake also requires cryptographically proving possession of the matching private key, through a challenge the client must correctly respond to using that key. This means an attacker who somehow obtains a copy of the public certificate alone — which is not even meant to be secret — still cannot successfully authenticate, because they lack the private key needed to complete this proof.
A shared secret is like a password anyone who overhears it can immediately reuse. A certificate-based proof is more like a uniquely shaped key that must actually turn a specific, matching lock correctly on the spot — simply showing someone a photograph of the key does not let them open the door, because the photograph cannot physically turn anything. mTLS requires the real key, not merely a description or copy of what it looks like.
Certificate-Bound Access Tokens
Keycloak’s mTLS support extends beyond just the initial client authentication step. Following the OAuth 2.0 Mutual-TLS specification, Keycloak can issue certificate-bound access tokens — tokens cryptographically tied to the specific client certificate used to obtain them. When such a token is later presented to a protected resource, that resource can verify the same certificate is being used again, meaning even a stolen access token becomes useless to an attacker who does not also possess the original client’s private key.
Revocation checking
Because certificates can be compromised or need to be invalidated before their natural expiry, robust mTLS deployments also check whether a presented certificate has been explicitly revoked, typically through a Certificate Revocation List, or an online status-checking protocol. Without this check, a certificate that should no longer be trusted — because its private key was compromised, for example — could otherwise continue to be accepted right up until its printed expiry date.
Lifecycle
Data Flow & Lifecycle
Following a single machine-to-machine request from start to finish shows exactly where mTLS enters the picture and what it changes along the way.
A backend service needs a token
An automated service, holding its own issued certificate and matching private key, needs to obtain an access token from Keycloak in order to call a protected API.
A mutual TLS connection is established
As the service connects to Keycloak’s token endpoint, the TLS handshake requires the service to present its certificate, which is verified against the trusted certificate authority configured in Keycloak’s truststore.
Keycloak maps the certificate to a client
Keycloak examines the certificate’s relevant fields and matches them against the expected identity configured for a specific registered client, confirming exactly which client is authenticating.
Client authentication succeeds without a shared secret
Because the certificate check itself served as the proof of identity, Keycloak proceeds without ever needing a traditional client secret to be transmitted or checked.
A certificate-bound access token is issued
Keycloak issues an access token cryptographically bound to the specific certificate just used, rather than a token that could be equally valid if copied and presented by any other holder.
The protected API double-checks the binding
When the service presents this token to the protected API it actually needs to call, that API can verify the same certificate is once again being used, confirming the token has not been copied and reused by a different, unauthorized party.
Weighing the Choice
Advantages, Disadvantages & Trade-offs
Choosing mTLS client authentication over a simpler shared secret is a genuine trade-off between meaningfully stronger security and real added operational complexity.
Advantages
- Requires proof of private key possession, not just knowledge of a value that could be copied, logged, or leaked
- Certificate-bound access tokens neutralize the risk of a stolen token being reused by someone without the matching private key
- Provides a well-understood, standardized security model already trusted for the most sensitive server-to-server communications on the internet
- Certificates can carry a built-in expiry and can be explicitly revoked, giving finer-grained lifecycle control than many shared-secret setups
Disadvantages & Trade-offs
- Requires a real certificate management process — issuing, distributing, renewing, and revoking certificates for every client that uses it
- More complex to configure correctly, particularly in deployments involving reverse proxies or load balancers that terminate TLS separately from Keycloak itself
- Not well suited to browser-based, human-facing logins, since managing individual client certificates for ordinary end users is impractical at scale
- Misconfigured truststores or mapping rules can silently allow the wrong certificate to authenticate as a client, or block legitimate ones entirely
Where mTLS genuinely earns its complexity
mTLS is best suited to server-to-server and machine-to-machine scenarios — backend services, partner integrations, high-value APIs — where the operational overhead of proper certificate management is justified by the sensitivity of what is being protected. For simpler, lower-risk client applications, a well-managed client secret, or a JWT-based authentication method, often provides a more practical balance of security and simplicity.
Defense
Security
mTLS is a genuinely strong authentication method, but its strength depends entirely on how carefully every surrounding piece is configured and maintained.
Private key protection is everything
The entire security guarantee of mTLS collapses if a client’s private key is not kept genuinely private. Storing private keys in secure, access-controlled locations — ideally hardware-backed where feasible — is not an optional refinement; it is the single most important operational responsibility in any mTLS deployment, since a leaked private key is functionally equivalent to a leaked shared secret in the older model.
It is tempting to assume that switching to mTLS automatically makes an integration secure, simply because certificates sound inherently more sophisticated than a shared secret. In reality, an mTLS setup with a carelessly stored private key, an overly permissive truststore, or a loosely written certificate-to-client mapping rule can end up no more secure — and sometimes less transparent to reason about — than a well-managed shared secret would have been.
Truststore scope and third-party certificate authorities
A truststore configured to trust an overly broad set of certificate authorities widens the pool of certificates Keycloak might accept as valid, even if those certificates were never intended for use with this specific system. Keeping the truststore scoped tightly to the specific, deliberately chosen certificate authorities relevant to an organization’s actual client population significantly reduces this risk.
Revocation checking cannot be skipped
Without active revocation checking, a certificate whose private key has been compromised remains technically valid, and therefore still accepted by Keycloak, right up until its scheduled expiry date, regardless of how recently the compromise was discovered. Deployments handling sensitive integrations should treat revocation checking as a required, not optional, part of the overall mTLS configuration.
Proxy and TLS termination configuration
When Keycloak sits behind a reverse proxy that terminates TLS and forwards certificate details through headers, that proxy configuration itself becomes a critical trust boundary. If the proxy can be tricked into forwarding forged certificate header values, or if Keycloak is not configured to strictly trust only genuine headers from that specific proxy, the entire mTLS guarantee can be undermined despite every certificate itself being technically valid.
Visibility
Monitoring, Logging & Metrics
Because mTLS shifts a critical part of authentication into the TLS handshake itself, monitoring needs to look slightly earlier in the process than it would for a simple shared-secret setup.
Handshake-level failures versus authentication-level failures
A failed mTLS connection attempt can go wrong at two genuinely different layers: the TLS handshake itself might reject the client’s certificate outright, before Keycloak’s own client authentication logic ever runs, or the handshake might succeed while Keycloak’s certificate-to-client mapping subsequently fails to find a match. Distinguishing between these two failure points, using both proxy or web server logs and Keycloak’s own logs, is essential for accurate diagnosis.
Tracking certificate expiry proactively
Because certificates carry a built-in expiry date, deployments relying on mTLS client authentication benefit significantly from proactive monitoring of upcoming expirations, well before they actually occur, since an expired client certificate will suddenly and completely block that client’s ability to authenticate at all, often with limited advance warning if this is not tracked deliberately.
Watching for unexpected certificate authorities or subjects
Reviewing authentication attempts that present certificates from unexpected or unfamiliar certificate authorities, or with subject fields that do not correspond to any known, registered client, can reveal either a misconfiguration in the truststore or a genuine attempt to probe the system with an invalid or forged certificate.
Auditing certificate-to-client mapping rules periodically
As an organization’s set of mTLS-authenticated clients grows over time, periodically reviewing the mapping rules tying specific certificate fields to specific clients helps ensure these rules remain precise and accurate, rather than drifting into overly broad patterns that could inadvertently accept certificates never intended to represent that particular client.
Shape
Design Patterns & Anti-patterns
Organizations that adopt mTLS client authentication for real, sensitive integrations tend to converge on a handful of recognizable, sound patterns.
Pattern: Reserved for high-sensitivity, machine-to-machine integrations
Mature deployments apply mTLS selectively, to the specific clients handling the most sensitive or highest-value integrations — payment processing, partner APIs, regulated data exchanges — while allowing lower-risk, more ordinary applications to continue using simpler authentication methods where the added complexity of certificate management is not clearly justified.
Pattern: Dedicated internal certificate authority for client certificates
Rather than relying on broad, general-purpose public certificate authorities, organizations frequently operate a dedicated, internal certificate authority specifically for issuing client certificates used in mTLS authentication, giving them full control over issuance, renewal, and revocation without depending on external processes for something this security-critical.
Pattern: Automated certificate rotation
Deployments with a mature mTLS setup typically automate the renewal and rotation of client certificates well ahead of their expiry, rather than relying on manual tracking, ensuring a forgotten renewal date never results in a sudden, unplanned authentication outage for a critical integration.
Anti-pattern: Trusting an overly broad public certificate authority
A risky shortcut is configuring Keycloak’s truststore to accept certificates from a very broad, general-purpose public certificate authority simply because it is convenient, rather than restricting trust specifically to certificates genuinely intended for this integration, unnecessarily widening the pool of certificates that could theoretically be accepted.
Situation
To speed up onboarding a new partner integration, a team configures Keycloak’s truststore to accept any certificate issued by a large, widely used public certificate authority, rather than specifically pinning trust to the particular certificate the partner will actually use.
Consequence
Because that same public certificate authority issues certificates to an enormous number of unrelated organizations, the truststore configuration technically accepts far more certificates than were ever intended, relying entirely on the certificate-to-client mapping rule to catch anything unintended, rather than on the truststore itself providing a meaningful additional layer of restriction.
Better Approach
Restrict trust specifically to the partner’s own dedicated certificate authority, or pin the exact expected certificate details, so that the truststore itself meaningfully narrows what can be accepted, rather than depending on a single downstream mapping rule to do all of the restricting alone.
Getting It Right
Best Practices & Common Mistakes
A short set of disciplined habits consistently separates an mTLS deployment that delivers on its security promise from one that merely looks secure on paper.
Protect private keys as the highest-value secret
Treat private key storage and access control with at least as much care as any other critical credential in the system.
Scope the truststore narrowly
Trust only the specific certificate authorities genuinely relevant to your actual mTLS clients, not broad, general-purpose ones.
Enable and actively use revocation checking
A compromised certificate should stop working the moment it is revoked, not merely once its printed expiry date arrives.
Automate certificate renewal and rotation
Avoid relying on manual tracking for expiry dates that, if missed, can cause a sudden and disruptive authentication outage.
Reserving mTLS only for a single layer of the stack
Securing the connection to Keycloak with mTLS while leaving a proxy-to-Keycloak hop or downstream API call unprotected undermines the end-to-end guarantee.
Writing overly loose certificate-to-client mapping rules
A mapping rule broad enough to match more than the one intended certificate defeats the precision mTLS is meant to provide.
Before enabling mTLS client authentication for a new integration, map out every hop the connection actually travels through — client, load balancer, reverse proxy, Keycloak itself — and confirm exactly where the TLS handshake and certificate verification genuinely occur at each one, rather than assuming it happens uniformly across the entire path.
mTLS client authentication appears most consistently in exactly the industries and integrations where the cost of a compromised credential would be catastrophic.
Open banking and financial services APIs
Regulatory frameworks governing open banking initiatives in several regions specifically mandate mutual TLS for API access between banks and authorized third-party providers, reflecting the extremely high stakes of any credential compromise in a system that can move real customer funds.
Healthcare data exchange networks
Systems that exchange sensitive patient health information between different healthcare organizations frequently rely on mTLS client authentication to ensure that only specifically authorized, verified systems — never merely anyone who obtained a leaked shared secret — can request or submit that information.
Zero-trust internal service architectures
Organizations adopting a zero-trust security model — where no internal network connection is automatically trusted simply because it originates inside the corporate network — frequently use mTLS between internal services as a way to ensure every service-to-service connection, including calls to Keycloak itself, is cryptographically verified rather than implicitly trusted.
Government and critical infrastructure systems
Systems supporting critical national infrastructure or sensitive government functions often require mTLS specifically because the consequences of unauthorized access are severe enough to justify the additional operational overhead of full certificate lifecycle management across every connected system.
Questions Answered
FAQ
Wrapping Up
Summary & Key Takeaways
Mutual TLS Client Authentication takes a form of trust most people already rely on every day — the certificate check behind a browser’s padlock icon — and extends it in both directions, requiring the connecting application to prove its identity just as rigorously as the server does. In Keycloak, this replaces a simple shared secret with something meaningfully harder to steal or fake: cryptographic proof of holding a specific private key, verified against a trusted certificate authority, and optionally carried forward into the very access tokens a client subsequently uses. The strength this provides is real, but so is the operational responsibility it demands — private keys, truststores, mapping rules, and revocation checks all need to be treated with the seriousness the method itself is designed to enforce.
Key Takeaways
- mTLS extends ordinary TLS in both directions — the client proves its identity to the server, not just the other way around.
- Certificates prove possession, not just knowledge — a stolen public certificate alone is useless without the matching private key.
- Keycloak verifies certificates against a configured truststore — and maps specific certificate fields to specific registered clients.
- Certificate-bound access tokens extend the protection beyond login — a stolen token remains useless without the original certificate’s private key.
- mTLS suits machine-to-machine, high-sensitivity integrations best — its certificate-management overhead is a poor fit for ordinary human, browser-based logins.
- Revocation checking is essential, not optional — without it, a compromised certificate remains accepted until its natural expiry.
- Every link in the chain matters equally — private key protection, truststore scope, mapping precision, and proxy configuration each carry the potential to undermine the whole guarantee if handled carelessly.