What Is a Client Secret in Keycloak?

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?

Let’s start with a plain definition, then place it correctly within Keycloak’s broader client model.

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.

Everyday Analogy

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.

Confidential Client

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.

Public Client

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.

i
Key Distinction

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.

1
SECRET PER CONFIDENTIAL CLIENT
2
ROLES: CLIENT ID (PUBLIC) + SECRET (PRIVATE)
0
SECRETS BELONGING IN A MOBILE APP BINARY

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

Let’s see exactly where the Client Secret fits within Keycloak’s client configuration and token-issuance architecture.
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
    
Fig. 1 — Where the Client Secret fits into a confidential client’s interaction with the Token Endpoint

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.

!
Common Misconception

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

Let’s look at exactly what happens when a confidential client presents its Client Secret to Keycloak.

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.

Everyday Analogy

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.

i
Why Rotation Matters

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

Let’s trace exactly where the Client Secret is used within a typical Authorization Code login flow.
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"]
    
Fig. 2 — Where the Client Secret is presented during the Authorization Code flow’s token exchange step
1

User-Facing Login

The user authenticates through Keycloak’s login page in their browser — no Client Secret is involved or visible at this stage.

2

Authorization Code Issued

Keycloak redirects the browser back to the application with a short-lived, single-use authorization code.

3

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.

4

Secret Verification

Keycloak confirms the Client Secret matches what’s on record for that Client ID before proceeding any further.

5

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

Client Secrets add real protection — but they also add real operational responsibility.

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.
Everyday Analogy

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

Because a Client Secret grants an application-level trust relationship, protecting it deserves the same seriousness as protecting a database password.

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.

!
A Real Risk: Accidental Commit to Version Control

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.

SECURITY PATTERN · PUBLIC CLIENTS USE PKCE, NOT SECRETS Standard Practice
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

How experienced teams handle Client Secrets well — and the mistakes that quietly create risk.

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.

ANTI-PATTERN · SHARED SECRET ACROSS ENVIRONMENTS Avoid
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.

ANTI-PATTERN · SECRET IN A MOBILE APP Avoid
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

Practical, hands-on guidance for handling Client Secrets safely in a Keycloak deployment.
Best Practice

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.

Best Practice

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.

Best Practice

Audit Client Configuration Regularly

Periodically review which Clients are marked Confidential versus Public, confirming each matches how that application is actually deployed and secured.

Best Practice

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

Seeing how real systems handle Client Secrets makes the concept concrete.

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.

“A Client Secret doesn’t ask who the user is — it asks whether the application itself deserves to be trusted at all.”

JFrequently Asked Questions

Q1Is a Client Secret the same as a user’s password?
No — a Client Secret authenticates an application to Keycloak, while a user’s password authenticates a specific person. They serve entirely different purposes and are never interchangeable.
Q2Does every Keycloak Client have a Client Secret?
No — only Confidential clients have one. Public clients, like single-page apps and mobile apps, deliberately don’t use a Client Secret and rely on PKCE instead.
Q3What happens if a Client Secret is regenerated?
The previous secret is immediately invalidated, and any application still using the old value will fail client authentication until it’s updated with the new one.
Q4Can a mobile app safely use a Client Secret?
No — any secret embedded in a distributed app binary can potentially be extracted, so mobile apps should be configured as Public clients using PKCE rather than relying on a Client Secret.
Q5Where should a Client Secret be stored?
In a dedicated secrets manager or securely injected environment variable on the server side — never hardcoded into source code, committed to version control, or exposed to client-side code.
Q6Are there alternatives to a shared Client Secret?
Yes — Keycloak also supports client authentication using a signed JWT the client generates with its own private key, or mutual TLS certificates, both of which avoid transmitting a shared secret value at all.

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.