Public Client vs Confidential Client in Keycloak: What’s the Real Difference?

Public Client vs Confidential Client in Keycloak: What's the Real Difference?

A beginner-friendly breakdown of one of the most important decisions when registering an application in Keycloak — whether it can be trusted to keep a secret, and why that single question changes everything about how it logs users in.

Imagine two different types of employees at a company. One works inside a locked, badge-access-only server room, where nobody outside the company could ever peek at what’s on their screen. The other works at a public information desk in the building’s lobby, visible to literally anyone who walks by. Both employees can be trusted to do their job, but you’d never hand the lobby employee a secret master key to every door in the building — because anyone could simply watch them use it. In Keycloak, every application you register faces this exact same distinction. Some run in trusted, locked-away environments and can safely hold a secret. Others run out in the open, visible to anyone, and cannot. This single difference is what separates a Confidential Client from a Public Client.

1What Are Client Types, and Why Do They Exist?

Before comparing the two, let’s understand what a “client” is and why Keycloak needs to classify them differently at all.

A Quick Refresher: What Is a Client?

In Keycloak, a client is any application that has been registered to use Keycloak for login — a website, a mobile app, a backend service, or a single-page application. Every client is given a unique identifier so Keycloak knows exactly which application is asking for a login at any given moment.

The Core Question Keycloak Asks

When registering a client, Keycloak asks one crucial question: can this application safely keep a secret hidden from end users and potential attackers? The honest answer to that question depends entirely on where the application’s code actually runs, and it determines which of the two client types it should be.

Client Type

Public Client

An application that cannot safely hold a secret, because its code is visible or extractable by whoever runs it.

Client Type

Confidential Client

An application that runs in a trusted, access-controlled environment and can safely store a secret credential.

Term

Client Secret

A private password-like credential that proves a confidential client’s identity when talking to Keycloak.

Term

Client Authentication

The process by which a client proves its own identity to Keycloak, separate from the end user proving theirs.

Simple Analogy

Think of a client secret like the combination to a safe. A confidential client is like a bank vault room — only trusted staff with proper clearance can ever get close enough to even attempt opening it. A public client is like a safe sitting in a shop window — no matter how strong the combination is, anyone walking by could eventually watch someone open it and learn the combination too.

i
Good To Know

This isn’t about whether an application is “less important” or “less trusted” in a general sense — it’s purely about whether its code and runtime environment can physically prevent a secret from being seen or extracted by whoever is running or inspecting it.

2Why This Classification Actually Matters

This isn’t just a technical label — getting it wrong has real security consequences.

A client secret is meant to prove that a request genuinely came from your registered application, and not from an impostor pretending to be it. If that secret is embedded in code that runs on a user’s own device — like a mobile app or a browser-based single-page application — a sufficiently motivated user could extract it by inspecting the app’s files or its network traffic. Once extracted, that secret is no longer secret at all, and the entire point of having one collapses.

Risks of Misclassifying a Client

  • Treating a browser app as confidential embeds a secret anyone can extract from the code
  • A leaked client secret can let an attacker impersonate the application itself
  • False confidence in a “secret” that was never actually secret at all

What Correct Classification Provides

  • Public clients use flows specifically designed to work safely without any secret
  • Confidential clients get a genuinely private credential, since their environment supports it
  • Security guarantees match reality, rather than relying on false assumptions
Simple Analogy

Writing your house key’s shape into a public flyer doesn’t make your door more secure just because you called it a “secret key.” Treating a browser-based app as a confidential client is the same mistake — giving it a secret doesn’t create real security if that secret can be read by anyone who opens the app’s developer tools.

3Side-by-Side: Public Client vs Confidential Client

With the concepts established, let’s compare the two directly across the dimensions that matter most.

DimensionPublic ClientConfidential Client
Can it hold a secret?NoYes
Where it typically runsBrowser, mobile device, user’s own machineTrusted backend server
Client authenticationNot required; relies on other safeguards insteadRequires a client secret or certificate
Typical examplesSingle-page apps, native mobile appsBackend web servers, internal APIs
Recommended flow safeguardPKCE (Proof Key for Code Exchange)Standard Authorization Code Flow
Risk if code is inspectedNo secret exists to leak in the first placeSecret must be protected from ever leaving the server
Public Client Examples

Single-Page Applications

JavaScript-based apps running entirely in the user’s browser, where all code is visible to anyone who opens developer tools.

Public Client Examples

Native Mobile Apps

Apps installed directly on a user’s phone, where the app’s compiled code can potentially be decompiled and inspected.

Confidential Client Examples

Traditional Backend Web Servers

Server-rendered applications where all sensitive logic and credentials stay on a server the user never directly accesses.

Confidential Client Examples

Internal Service-to-Service APIs

Backend services calling each other within a trusted internal network, safely holding credentials no external user ever sees.

4Architecture: How Keycloak Treats Each Type Differently

The distinction isn’t just paperwork — it changes what Keycloak actually requires during every single login.

flowchart TB
    subgraph Public["Public Client Flow"]
        PU[Browser / Mobile App] -->|Auth Code, No Secret| PKC[Keycloak checks PKCE proof]
    end
    subgraph Confidential["Confidential Client Flow"]
        CS[Backend Server] -->|Auth Code + Client Secret| CKC[Keycloak checks Client Secret]
    end
    PKC --> TOK1[Tokens Issued]
    CKC --> TOK2[Tokens Issued]
        
FIG 1 — Both flows end with Keycloak issuing tokens, but they prove the client’s identity through very different mechanisms

How Public Clients Prove Legitimacy Without a Secret

Since a public client can’t hold a secret, Keycloak relies instead on a mechanism called PKCE (Proof Key for Code Exchange), pronounced “pixy.” Rather than a fixed secret, the application generates a random, one-time value at the start of the login, keeps a mathematically related “proof” locally, and presents that proof back to Keycloak at the very end of the flow. Even if someone intercepts the authorization code in transit, they can’t complete the exchange without also having generated that one-time proof themselves.

How Confidential Clients Prove Legitimacy With a Secret

A confidential client, running safely on a backend server, simply includes its pre-registered client secret directly when exchanging the authorization code for tokens. Since only the legitimate backend server ever holds that secret, Keycloak can trust that the request genuinely came from the real application.

PKCE
protects public clients instead of a secret
1 Secret
per confidential client, kept server-side
Per-Client
configured individually in the Admin Console

5How the Login Flow Differs, Step by Step

Let’s walk through both flows side by side to see exactly where they diverge.

Public Client Login Flow

1

App generates a one-time PKCE proof

Before redirecting the user, the application creates a random value and a related, derived version of it.

2

User logs in at Keycloak as usual

The derived value is sent along with the initial redirect, and Keycloak remembers it for later verification.

3

App exchanges the authorization code plus the original proof

No client secret is involved — instead, the original random value is sent, and Keycloak checks it matches what was derived earlier.

4

Tokens are issued

With the proof successfully verified, Keycloak issues the access, refresh, and ID tokens as normal.

Confidential Client Login Flow

1

User is redirected to Keycloak as usual

No special one-time proof is needed at this stage, since the application will authenticate itself later using its secret.

2

User logs in and is redirected back with a code

This part of the process looks identical to the public client flow from the user’s perspective.

3

Backend server exchanges the code plus its client secret

The server includes its registered secret directly in this private, server-to-server request to Keycloak.

4

Tokens are issued

With the secret successfully verified, Keycloak issues tokens back to the trusted backend server.

i
Good To Know

From the end user’s point of view, both flows look and feel identical — they see the same login page and the same redirect behavior. The real difference happens invisibly, behind the scenes, in how the application proves its own legitimacy to Keycloak.

6The Backend-for-Frontend Pattern: Getting the Best of Both

Many modern applications combine both client types to get the strongest possible security for browser-based apps.

A pure single-page application talking directly to Keycloak must be a public client, since its code runs entirely in the user’s browser. But some teams prefer to avoid even handling tokens in the browser at all. In this pattern, called Backend for Frontend (BFF), a small backend server sits between the browser and Keycloak. That backend is registered as a confidential client, safely holding the client secret and any refresh tokens, while the browser itself only ever talks to this trusted backend, never directly to Keycloak’s token endpoint.

Simple Analogy

It’s like a receptionist who handles all sensitive paperwork on your behalf, rather than handing you the paperwork to carry around yourself. You interact only with the receptionist (the backend), who quietly manages the sensitive documents (tokens and secrets) in a locked office you never see inside of.

!
Common Misconception

Adopting a Backend for Frontend pattern doesn’t mean the frontend itself becomes a confidential client — the frontend remains a public client, or often isn’t registered as a Keycloak client at all, while the separate backend service is the one actually classified as confidential.

7Configuring Client Type in the Admin Console

Choosing between the two isn’t a permanent architectural decision made in code alone — it’s a setting configured directly in Keycloak.

Setting

Client Authentication Toggle

Turning this on makes a client confidential, generating a client secret; leaving it off keeps the client public.

Setting

Standard Flow Enabled

Controls whether the client can use the Authorization Code Flow, the standard flow for both public and confidential clients.

Setting

Valid Redirect URIs

Restricts exactly where Keycloak is allowed to send users back after login, an important safeguard for both client types.

Setting

PKCE Method

For public clients, specifies the exact algorithm used to generate and verify the one-time login proof.

Administrators make this decision while registering a new client, based entirely on an honest assessment of where and how that application actually runs — not based on how “important” the application feels, and not something that should be changed casually once real users depend on it.

8Advantages, Disadvantages, and Trade-offs

Each client type comes with its own genuine strengths and limitations, rather than one simply being “better” than the other.

Public Client Trade-offs

  • Works correctly in environments where no secret could ever stay safe
  • PKCE provides strong protection without needing any hidden credential
  • Slightly more exposed to certain attacks if redirect URIs aren’t tightly restricted
  • Cannot be trusted with especially sensitive, long-lived credentials on its own

Confidential Client Trade-offs

  • Stronger authentication guarantee, since only the legitimate server holds the secret
  • Can safely be trusted with more sensitive operations and longer-lived credentials
  • Only usable where a genuinely trusted, access-controlled backend actually exists
  • Requires careful secret storage and periodic rotation as an ongoing responsibility

Neither type is inherently more secure in the abstract — each is the correct, secure choice for its own kind of environment, and the real risk comes from mismatching a client’s type to where it actually runs.

9Security Considerations for Each Type

Regardless of which type an application uses, a few security practices deserve extra attention.

For Public Clients

Always Require PKCE

PKCE should be treated as mandatory, not optional, for every public client to prevent authorization code interception attacks.

For Public Clients

Restrict Redirect URIs Tightly

Only exact, pre-approved redirect addresses should be allowed, closing off a common avenue for token theft.

For Confidential Clients

Rotate Client Secrets Periodically

Treat client secrets like passwords, rotating them on a schedule and immediately if a leak is ever suspected.

For Confidential Clients

Never Expose the Secret to the Browser

The client secret should never appear in any code, logs, or network traffic reachable by the end user’s browser.

“The safest client type isn’t the one with a secret — it’s the one whose type honestly matches the environment it actually runs in.”

10Monitoring, Logging, and Metrics

Watching how each client type behaves in production helps catch misconfiguration and misuse early.

What to MonitorWhy It Matters
PKCE validation failuresCan indicate a misconfigured public client or an attempted interception attack
Client secret authentication failuresRepeated failures may signal a leaked or rotated-but-unupdated secret
Unexpected redirect URI attemptsRequests targeting unregistered redirect addresses can indicate an attack attempt
New client registrationsWorth reviewing to confirm each new client was assigned the correct, honest type

Keycloak’s event logs capture client authentication attempts and failures, giving administrators the visibility needed to spot a misconfigured client type or a potential attack before it causes real damage.

i
Practical Tip

A sudden wave of client secret authentication failures right after a secret rotation usually means one deployed instance of the application still has the old secret configured — worth checking deployment consistency before assuming an attack.

11Design Patterns and Anti-Patterns

Real-world Keycloak deployments have converged on clear guidance around choosing and managing client types correctly.

Pattern: Classify Honestly, Not Optimistically

Always base the client type decision on where the code genuinely runs and who can inspect it, never on a hopeful assumption that “probably nobody will look.”

Pattern: Use a Backend for Frontend for Sensitive Browser Apps

When a browser-based application handles especially sensitive data, routing token handling through a confidential backend adds meaningful extra protection over a pure public-client setup.

Pattern: Enforce PKCE Everywhere, Even for Confidential Clients

Many teams enable PKCE across all client types as an extra defensive layer, even though it’s strictly mandatory only for public ones.

ANTI-PATTERN-01 Avoid
Problem

Registering a mobile app as a confidential client and embedding its client secret directly inside the compiled app.

Why It’s Harmful

Compiled mobile app code can often be decompiled or inspected, meaning the “secret” is effectively public, giving a false sense of security while providing no real protection.

Correct Approach

Register mobile apps as public clients using PKCE, which is specifically designed to provide strong security without requiring a hidden secret at all.

ANTI-PATTERN-02 Avoid
Problem

Reusing the exact same client registration for both a browser-based frontend and its backend API, blurring the two roles together.

Why It’s Harmful

This makes it unclear which part of the system is actually meant to hold the secret, increasing the chance that sensitive credentials end up somewhere they shouldn’t, like exposed frontend code.

Correct Approach

Register the frontend and backend as separate clients with distinct, clearly-defined types, matching each to the environment it actually runs in.

12Best Practices and Common Mistakes

Concrete, actionable guidance for getting client type classification right the first time.

Best Practice

Ask “Who Can See This Code?” First

Before configuring a new client, honestly identify who could potentially inspect its running code or network traffic.

Best Practice

Default to Public for Anything Client-Side

When in doubt about a browser or mobile application, treating it as public and relying on PKCE is the safer default assumption.

Best Practice

Store Confidential Secrets in a Secrets Manager

Keep client secrets in a dedicated secrets management tool rather than hardcoded in source code or configuration files committed to version control.

Best Practice

Review Client Types Periodically

As applications evolve — for example, moving logic from a backend into the browser — revisit whether the original client type classification still holds true.

!
Common Mistake

Committing a confidential client’s secret directly into a source code repository, even a private one. Repository access often expands over time, and secrets committed to version control history are notoriously difficult to fully remove once exposed.

13Real-World and Industry Examples

This distinction shows up constantly across everyday software architecture, even when developers don’t explicitly think in these exact terms.

E-Commerce Storefronts

A store’s customer-facing website, running in the browser, is typically a public client, while its internal inventory management backend is a confidential client with its own separate credentials.

Ride-Sharing and Delivery Apps

The mobile app installed on a customer’s phone is a public client using PKCE, while the company’s backend systems processing payments and trip data are confidential clients.

Enterprise Internal Dashboards

Server-rendered internal tools, where all sensitive logic runs on a company-controlled server, are commonly registered as confidential clients.

Modern SPA-Plus-API Architectures

A JavaScript frontend acts as a public client, while its separate backend API — the one actually calling other protected services on the user’s behalf — is registered as confidential.

This pattern repeats across virtually every modern software architecture: whatever runs directly on a user’s device is public, and whatever runs safely on a company-controlled server is confidential.

14Frequently Asked Questions

Q1Can I change a client from public to confidential later?

Yes, this can be changed in the Admin Console, though it typically requires updating the application’s code to handle the new authentication requirements correctly.

Q2Is PKCE only used by public clients?

PKCE is mandatory for public clients, but many organizations also enable it for confidential clients as an additional layer of protection, since it adds security without real downsides.

Q3What happens if I accidentally treat a mobile app as confidential?

The embedded client secret can likely be extracted from the app’s code, giving a false sense of security rather than genuine protection — it should be reconfigured as a public client using PKCE instead.

Q4Do public clients have weaker security overall?

Not inherently — when properly configured with PKCE and restricted redirect URIs, public clients offer strong security appropriate to their environment; they simply rely on different mechanisms than confidential clients do.

Q5Can a single application use both client types?

Yes, this is common in the Backend for Frontend pattern, where a browser-based frontend and its dedicated backend are registered as two separate clients with two different types.

Q6How is a client secret generated and stored in Keycloak?

Keycloak generates it automatically when a client is configured as confidential, and it can be viewed or regenerated by an administrator directly from that client’s Credentials tab in the Admin Console.

15Summary and Key Takeaways

The difference between a Public Client and a Confidential Client in Keycloak comes down to one honest question: can this application actually keep a secret safe from anyone who might run or inspect it? Applications running on a user’s own device — browsers, mobile apps — cannot, and should be registered as public clients relying on PKCE for security. Applications running on a company-controlled backend server can, and should be registered as confidential clients using a genuinely private client secret. Getting this classification right, rather than optimistically hoping nobody inspects the code, is foundational to building a Keycloak integration that’s actually secure rather than just appearing secure.

Key Takeaways

  • The core question is whether a secret can stay genuinely hidden — not how important or trusted the application feels.
  • Public clients run where end users can inspect the code, such as browsers and mobile apps, and use PKCE instead of a secret.
  • Confidential clients run on trusted backend servers, and safely hold a genuine client secret for authentication.
  • Both flows look identical to the end user — the real difference happens invisibly, behind the scenes.
  • The Backend for Frontend pattern combines both, keeping a browser app public while a trusted backend handles confidential credentials.
  • Misclassifying a client creates false security — an embedded “secret” that anyone can extract offers no real protection.
  • PKCE and tightly restricted redirect URIs are essential safeguards for public clients specifically.