What Is a Client Secret in Keycloak?
The password an application itself must prove it knows — separate from any human user's credentials — before Keycloak will trust it with tokens.
So far, most discussions of Keycloak authentication focus on proving who a person is. But applications themselves sometimes need to prove their own identity too — and that’s exactly what a Client Secret is for. It’s easy to glance past this small configuration value in the Keycloak Admin Console, but it plays a critical security role: it’s the mechanism that stops a random, untrusted piece of software from pretending to be your application and requesting tokens on its behalf. This guide explains exactly what a Client Secret is, how Keycloak uses it, and how to handle it safely.
ACore Concepts: What Exactly Is a Client Secret?
In Keycloak, a Client represents an application — a website, an API, a mobile app, a backend service — that has been registered to use Keycloak for authentication. Every Client has a unique Client ID that identifies which application is making a request. But an ID alone can be seen and copied by anyone; it isn’t secret. That’s where the Client Secret comes in: a confidential value, known only to the application and to Keycloak, that the application must present alongside its Client ID to prove it really is the legitimate application it claims to be — not an impersonator who simply discovered the public Client ID.
Think of the Client ID like a store’s publicly listed business name, and the Client Secret like the private account number and password that store uses when calling its bank’s wholesale supplier line. Anyone can see and say the store’s name — that’s not secret. But only the real store, holding the private account credentials, can actually place a wholesale order and have the bank trust it.
This distinction maps directly onto a core concept in Keycloak’s client configuration: whether a Client is Confidential or Public.
Has a Client Secret
A server-side application (a backend web app, an API, a batch service) that can safely keep a secret hidden from end users, and authenticates itself using it.
No Client Secret
A client that runs entirely on a user’s device — a single-page app or a mobile app — where any embedded secret could be extracted by anyone, so Keycloak doesn’t rely on one at all.
A Client Secret authenticates the application itself to Keycloak. It is completely separate from — and should never be confused with — a user’s password, which authenticates a specific person. A request can involve both: a user proves who they are with their password, while the application separately proves what it is with its Client Secret.
Where does the Client Secret actually get used? Primarily at the moment an application talks directly to Keycloak’s Token Endpoint — for example, exchanging an authorization code for tokens, or requesting a token for service-to-service communication. It is not something an end user ever sees, types, or interacts with directly.
BArchitecture & Core Components
flowchart TB
Client["Client (Confidential)"] -->|"Client ID + Client Secret"| TokenEndpoint["Keycloak Token Endpoint"]
TokenEndpoint --> Verify["Verify Client Credentials"]
Verify --> ClientStore["Stored Client Secret (hashed/protected)"]
Verify -->|"if valid"| IssueTokens["Issue Access / ID / Refresh Tokens"]
Verify -->|"if invalid"| Reject["Reject Request"]
Admin["Admin Console"] -->|"Generates / Rotates"| ClientStore
Let’s unpack each labeled component.
Client ID and Client Secret Pair
Together, these two values act like a username and password, but for the application rather than a person. The Client ID is visible in configuration files, browser network requests, and logs without concern. The Client Secret must never appear in any of those places for a properly secured confidential client.
The Credentials Tab
Within the Keycloak Admin Console, each confidential Client has a dedicated Credentials tab where administrators can view, regenerate, or configure the authentication method for that client’s secret — including switching between a simple shared secret and more advanced methods like signed JWT assertions or mutual TLS.
The Token Endpoint
The specific Keycloak endpoint where a confidential client presents its ID and Secret (commonly via HTTP Basic authentication or as form parameters) as part of exchanging an authorization code, refreshing a token, or requesting a token via the client-credentials grant.
Client Authentication Methods Beyond a Shared Secret
While a simple shared secret is the most common approach, Keycloak also supports stronger alternatives for confidential clients — such as authenticating with a signed JWT the client generates using its own private key, or using mutual TLS certificates — each avoiding the need to transmit a shared secret value at all.
People sometimes assume every Keycloak Client has a secret. Public clients — like single-page apps and mobile apps — deliberately do not use a Client Secret, because there’s no way to keep it hidden from anyone with access to the client-side code. Those clients instead rely on other protections, such as PKCE (Proof Key for Code Exchange), covered in later chapters.
CHow Client Secret Verification Works Internally
Storage of the Secret
When a Client Secret is generated, Keycloak stores it in a form suitable for later verification (protected according to the realm’s configured storage and credential provider settings) rather than displaying it anywhere after the fact except at the moment it’s shown once in the Admin Console — which is exactly why teams are advised to copy and securely store it immediately upon generation or regeneration.
Verification During a Token Request
When a confidential client calls the Token Endpoint, it includes its Client ID and Client Secret — commonly using HTTP Basic Authentication in the request header. Keycloak looks up the specified Client and checks whether the supplied secret matches what’s on record for it, only proceeding to issue tokens if that check succeeds.
Think of calling a company’s automated phone banking line. Before the system will read out any account details, it asks for an account number (the Client ID) and a PIN (the Client Secret). Getting the account number right isn’t enough on its own — without the matching PIN, the call goes nowhere.
Where This Verification Applies
Client authentication using the secret happens specifically during direct, back-channel communication between the client application and Keycloak — most commonly during the Authorization Code flow’s final token exchange step, and during the Client Credentials grant used for pure service-to-service, no-human-involved requests.
Regeneration and Rotation
Administrators can regenerate a Client Secret at any time from the Credentials tab. Doing so immediately invalidates the previous secret, meaning any application still configured with the old value will start failing authentication until it’s updated — a deliberate, important operational consideration during rotation.
Periodically rotating Client Secrets — much like rotating any long-lived credential — limits how long a leaked or accidentally exposed secret remains useful to an attacker, even if the leak itself goes unnoticed for a period of time.
DData Flow & the Client Authentication Lifecycle
flowchart LR
A["1. User logs in via browser"] --> B["2. Keycloak returns Authorization Code"]
B --> C["3. Backend app receives the code"]
C --> D["4. Backend calls Token Endpoint with Code + Client ID + Client Secret"]
D --> E["5. Keycloak verifies Client Secret"]
E --> F["6. Keycloak issues Access, ID, Refresh Tokens"]
F --> G["7. Backend app uses tokens on the user's behalf"]
User-Facing Login
The user authenticates through Keycloak’s login page in their browser — no Client Secret is involved or visible at this stage.
Authorization Code Issued
Keycloak redirects the browser back to the application with a short-lived, single-use authorization code.
Server-Side Token Exchange
The application’s own backend — never the browser — sends that code, together with its Client ID and Client Secret, directly to Keycloak’s Token Endpoint.
Secret Verification
Keycloak confirms the Client Secret matches what’s on record for that Client ID before proceeding any further.
Token Issuance
Only after both the authorization code and the Client Secret check succeed does Keycloak issue the actual Access, ID, and Refresh Tokens back to the application.
Notice that the Client Secret is only ever exchanged directly between the application’s backend and Keycloak — it’s never sent through the user’s browser, which is precisely what keeps it out of reach of anyone able to inspect browser traffic or history.
EAdvantages, Disadvantages & Trade-offs
Advantages
- Prevents an unauthorized application from impersonating a legitimate client and requesting tokens under its identity.
- Simple to configure and understand — a shared secret is straightforward for most server-side integrations.
- Enables the powerful client-credentials grant for secure, human-free service-to-service authentication.
- Can be regenerated on demand, giving administrators direct control during suspected compromise or routine rotation.
Disadvantages / Trade-offs
- A leaked Client Secret can let an attacker request tokens as if they were the legitimate application, until it’s rotated.
- Unsuitable for public clients entirely — there’s no safe way to embed and hide a shared secret in code running on user devices.
- Rotation, if not coordinated carefully, can cause outages for any deployment still configured with the previous value.
- A simple shared secret is inherently weaker than certificate-based or signed-JWT client authentication for the highest-security scenarios.
A shared office door code is convenient and easy to set up, but everyone who knows it can open the door — and if it leaks, the only real fix is changing it for everyone who’s supposed to still have access. That operational cost is the trade every shared-secret system, including a Keycloak Client Secret, ultimately makes.
FSecurity Considerations
Never Embed a Secret in Public Code
A Client Secret must never be placed inside a mobile app binary, a single-page application’s JavaScript bundle, or any other artifact that ends up on a user’s device — anyone can extract strings from client-side code, no matter how it’s obfuscated.
Store Secrets in a Dedicated Secrets Manager
Rather than hardcoding a Client Secret directly into source code or configuration files committed to version control, mature deployments store it in a dedicated secrets manager or environment-variable injection system, keeping it out of source history entirely.
Restrict Who Can View or Regenerate It
Access to view or regenerate a Client Secret in the Admin Console should be limited to administrators who genuinely need it, following the same least-privilege thinking that applies to Master Realm access more broadly.
One of the most common real-world Client Secret leaks happens when a developer accidentally commits a configuration file containing the secret to a source code repository. Once committed, that history often persists even after the file is later removed, which is exactly why immediate rotation — not just deletion — is the correct response to a suspected leak.
Prefer Stronger Authentication Where Available
For especially sensitive integrations, Keycloak’s support for signed-JWT or mutual-TLS client authentication avoids transmitting any shared secret value at all, offering a meaningfully stronger security posture than a simple shared secret.
The Idea
Rather than forcing a public client (like a mobile app) to hold an inherently exposable secret, it instead uses PKCE — a per-request, dynamically generated proof tied to that specific login attempt.
Why It Matters
PKCE protects the authorization code exchange without requiring any long-lived secret to be embedded in client-side code at all, closing the exact gap a shared Client Secret would otherwise leave open for public clients.
GDesign Patterns & Anti-Patterns
Good Pattern: Confidential for Backend, Public + PKCE for Frontend
Configure server-side applications as Confidential clients using a Client Secret, and configure browser-based or mobile applications as Public clients relying on PKCE instead — matching the authentication method to what each platform can actually keep secure.
Good Pattern: Scheduled Rotation
Rotate Client Secrets on a defined schedule, coordinated with deployment processes, rather than only reacting after a suspected leak — treating rotation as routine hygiene rather than an emergency-only procedure.
Good Pattern: Separate Secrets per Environment
Use distinct Client Secrets for development, staging, and production environments, so a leak or misconfiguration in one environment can’t be used against another.
What It Looks Like
Reusing the exact same Client Secret across development, staging, and production Keycloak realms for convenience.
Why It’s a Problem
A leak in a less-protected environment (like a shared development setup) immediately compromises production as well, collapsing the isolation those environments were meant to provide.
What It Looks Like
Embedding a Client Secret directly in a mobile application’s code so it can act as a “confidential” client, believing obfuscation keeps it hidden.
Why It’s a Problem
Any value shipped inside a distributed app binary can be extracted by a sufficiently motivated party — this configuration provides a false sense of security while a Public client with PKCE would have been the appropriate, genuinely safer choice.
HBest Practices & Common Mistakes
Inject Secrets at Runtime
Use environment variables or a secrets manager to supply the Client Secret at deploy or runtime, rather than baking it into source code.
Automate Rotation
Where possible, integrate secret rotation into deployment pipelines so it’s a routine, low-friction operation rather than a rare, risky manual task.
Audit Client Configuration Regularly
Periodically review which Clients are marked Confidential versus Public, confirming each matches how that application is actually deployed and secured.
Prefer Stronger Auth for High-Value Clients
Use signed-JWT or mutual-TLS client authentication for especially sensitive integrations rather than defaulting to a simple shared secret everywhere.
Common Mistakes to Avoid
- Committing secrets to version control: Even a brief accidental commit can leave a lasting trace in repository history.
- Treating Public clients as if they could hold a secret: Marking a browser-based app as Confidential and embedding a secret in it provides no real protection.
- Forgetting to update all deployments after rotation: Regenerating a secret without coordinating the update across every instance of the application causes avoidable authentication failures.
- Logging request bodies that include the secret: Overly verbose application or proxy logging can inadvertently capture and persist the Client Secret in plaintext logs.
IReal-World & Industry Examples
Backend Web Applications
A traditional server-rendered web application — where all sensitive logic runs on a server the organization controls — is a textbook Confidential client, safely holding its Client Secret in server-side configuration and never exposing it to the browser.
Internal Automation and CI/CD Pipelines
Automated systems that need to call protected internal APIs without any human involved commonly use the client-credentials grant, authenticating purely with a Client ID and Client Secret stored securely in the pipeline’s secrets management system.
Mobile and Single-Page Applications
Consumer-facing mobile and browser-based apps are configured as Public clients with no Client Secret at all, relying instead on PKCE to secure their login flow — a deliberate, correct architectural choice given what those platforms can and cannot keep hidden.
JFrequently Asked Questions
KSummary & Key Takeaways
Key Takeaways
- A Client Secret authenticates an application itself to Keycloak — proving that a request genuinely comes from a legitimate, registered client, not an impersonator.
- It applies only to Confidential clients (typically server-side applications); Public clients like mobile and single-page apps use PKCE instead, since they cannot safely hide a secret.
- The secret is exchanged directly between an application’s backend and Keycloak’s Token Endpoint — never through the user’s browser.
- It must be stored securely (in a secrets manager, never in source control or client-side code) and rotated periodically to limit the impact of any potential leak.
- Stronger alternatives — signed-JWT or mutual-TLS client authentication — exist for especially sensitive integrations that want to avoid a shared secret altogether.
- Matching the right client type (Confidential vs. Public) to how an application is actually deployed is one of the most foundational security decisions in any Keycloak integration.