Default vs. Optional Client Scopes in Keycloak

Default vs. Optional Client Scopes in Keycloak

The quiet setting that decides whether a piece of user data rides along in every single token, or only shows up when an application specifically asks for it.

Every token Keycloak issues is a small, carefully curated bundle of information — a user’s identity claims, their roles, sometimes their phone number or offline access rights. But how does Keycloak decide exactly what to put inside that bundle for a given application? The answer lives in a feature called Client Scopes, and specifically in the distinction between Default and Optional Client Scopes. This single distinction — whether something is baked into every token automatically, or only added when explicitly requested — has real consequences for token size, application design, user consent, and security posture. This guide walks through exactly how Default and Optional Client Scopes work, how they differ, and how to use each one deliberately and well.

ACore Concepts: What Are Client Scopes, and How Do Default and Optional Differ?

Let’s build the foundational vocabulary carefully, since this topic sits at the intersection of several Keycloak concepts.

A Client Scope in Keycloak is a named, reusable bundle of configuration — primarily Protocol Mappers (rules that decide which claims get written into a token) and, in some cases, Role Scope Mappings — that can be attached to one or many Clients. Instead of configuring “include the user’s email in the token” separately for every single application, an administrator defines that behavior once, inside a Client Scope named something like email, and then simply attaches that scope to whichever Clients need it.

Once a Client Scope exists, it can be assigned to a specific Client in one of two ways, and this is exactly where our central distinction lives:

Default Client Scope

Always Included

Automatically applied to every token issued to that Client, with no need for the application to request it explicitly in the authorization request.

Optional Client Scope

Included Only on Request

Only applied if the application explicitly asks for it by name, typically by including it in the scope parameter of the authorization request.

Everyday Analogy

Think of ordering a meal at a restaurant with a fixed menu. A Default Client Scope is like the side dishes that automatically arrive with every main course — you don’t have to ask for the bread basket, it just shows up. An Optional Client Scope is like an à la carte add-on, such as extra dessert — it’s available on the menu, but the kitchen only sends it out if you specifically order it. The menu (the realm’s list of Client Scopes) stays the same; what changes is whether an item is bundled automatically or added by request.

i
Key Distinction

Defining a Client Scope and assigning it as Default or Optional to a specific Client are two separate configuration steps. The same Client Scope — say, phone — could be a Default scope for one Client and an Optional scope for a completely different Client, because this assignment happens per-Client, not globally for the scope itself.

2
ASSIGNMENT TYPES PER CLIENT SCOPE
Per-Client
ASSIGNMENT SCOPE, NOT GLOBAL
4+
BUILT-IN SCOPES SHIPPED BY DEFAULT

Keycloak’s Built-In Client Scopes

Out of the box, a fresh Keycloak realm ships with several ready-made Client Scopes, already sensibly categorized. Commonly included as Default scopes are profile (basic identity fields like name), email, roles (the role claims discussed in earlier guides), web-origins (CORS-related configuration), and acr (authentication context class reference, describing how strongly the user authenticated). Commonly included as Optional scopes are offline_access (long-lived refresh capability), address, phone, and microprofile-jwt (a claim format tailored for certain Java microservice frameworks).

This default categorization reflects a sensible general principle: information nearly every application needs (basic profile, email, roles) is bundled automatically, while more specialized or privacy-sensitive information (a phone number, a physical address, long-lived offline access) is only included when an application specifically asks for it and, depending on configuration, the user explicitly consents to sharing it.

Why This Distinction Exists At All

It would be technically possible for Keycloak to simply include every conceivable piece of user data in every token, all the time. The Default/Optional split exists instead because of three converging concerns: token size (larger tokens cost more bandwidth and parsing time on every single request), data minimization (a well-designed system shares only what’s actually needed, reducing exposure if a token is ever intercepted), and user consent (certain categories of personal data — like a phone number or physical address — are often subject to explicit consent requirements that shouldn’t apply to basic login information).

BArchitecture & Core Components

Let’s see exactly how Client Scopes, Protocol Mappers, and individual Clients cooperate architecturally.
flowchart TB
    Realm["Realm: Client Scopes Catalog"] --> ScopeA["Client Scope: profile"]
    Realm --> ScopeB["Client Scope: email"]
    Realm --> ScopeC["Client Scope: phone"]
    Realm --> ScopeD["Client Scope: offline_access"]
    ClientX["Client: Web App"] -->|"Default"| ScopeA
    ClientX -->|"Default"| ScopeB
    ClientX -->|"Optional"| ScopeC
    ClientX -->|"Optional"| ScopeD
    ScopeA --> MapperA["Protocol Mappers"]
    ScopeC --> MapperC["Protocol Mappers"]
    MapperA --> Token["Issued Token"]
    MapperC -.->|"only if requested"| Token
    
Fig. 1 — Client Scopes defined once at the realm level, assigned per-Client as Default or Optional

Let’s unpack each labeled piece in this architecture.

The Realm-Level Client Scope Catalog

Every Client Scope is defined once, at the realm level, inside a central catalog visible under the realm’s “Client Scopes” section in the Admin Console. This is where the scope’s name, description, and attached Protocol Mappers live — completely independent of any specific Client until it’s assigned to one.

Protocol Mappers Inside a Client Scope

Each Client Scope typically bundles one or more Protocol Mappers — the actual rules that pull specific pieces of data (a user attribute, a role, a group membership) and write them into a token claim with a specific name and format. A single Client Scope like profile might bundle several mappers together: one for given_name, one for family_name, one for preferred_username, and so on.

Per-Client Assignment

Each individual Client has its own configuration listing which Client Scopes are assigned to it, and — critically — whether each assignment is Default or Optional. This is managed in the Client Scopes tab of a specific Client’s settings in the Admin Console, and it’s entirely independent from how that same Client Scope might be assigned to a different Client.

Role Scope Mappings

Beyond claims like email or phone number, Client Scopes can also carry Role Scope Mappings — restricting which of a Client’s available roles are actually eligible to appear in tokens issued under that scope. This gives administrators a second axis of control: not just “which claims appear” but “which roles are even allowed to surface” for a given scope.

!
Common Misconception

People sometimes assume a Client Scope’s category (Default or Optional) is a fixed, global property of the scope itself. It isn’t — the exact same phone Client Scope could be marked Default for an internal HR application (where a phone number is always relevant) while remaining Optional for a public-facing marketing site (where it’s rarely needed and should only be requested when genuinely useful).

The Full Scope Allowed Toggle

Separately from this model entirely, each Client also has a Full Scope Allowed setting. When enabled, it bypasses fine-grained scope-based role filtering altogether, granting the Client access to every realm and client role the user holds, regardless of Client Scope configuration. This is a powerful but coarse setting, discussed further in the Design Patterns chapter, and is generally discouraged for production Clients that don’t genuinely need such broad access.

CHow Default vs. Optional Scope Resolution Works Internally

Let’s look closely at exactly what happens when Keycloak decides which claims to include in a specific token.

The scope Parameter in the Authorization Request

When an application initiates a login, it typically includes a scope parameter in its request to Keycloak — a space-separated list of scope names it wants included, such as openid profile email phone. Every OpenID Connect request implicitly includes the special openid scope, which triggers ID Token issuance in the first place.

How Default Scopes Are Resolved

Regardless of what the application explicitly requests in its scope parameter, every Client Scope marked as Default for that Client is automatically included in the resolution process. There’s no need for the requesting application to name them — Keycloak applies them unconditionally as part of that Client’s baseline token contract.

How Optional Scopes Are Resolved

A Client Scope marked as Optional is only included if its exact name appears in the incoming scope parameter of that specific authorization request. If the application never requests phone, the phone Client Scope’s mappers simply never run for that login, and no phone-related claims appear in the resulting token — even though the scope is technically available to that Client if it chose to ask for it.

Everyday Analogy

Think of checking into a hotel that automatically includes breakfast and Wi-Fi with every room (Default scopes) but offers a spa treatment or airport shuttle only if you specifically request them at check-in (Optional scopes). The hotel’s full list of available amenities (the realm’s Client Scope catalog) stays the same for every guest — what changes is which ones actually get delivered to your room, based on what’s automatic versus what you asked for.

Mapper Execution and Claim Assembly

Once Keycloak has determined the final, resolved set of scopes for a given request — combining every Default scope with whichever Optional scopes were explicitly requested — it runs every Protocol Mapper attached to each of those resolved scopes, writing their resulting claims into the appropriate token (ID Token, Access Token, or both, depending on each mapper’s own configuration).

The Resulting scope Claim

Interestingly, the final set of resolved scopes is itself reported back inside the issued token, typically as a scope claim — giving both the client application and any resource server inspecting the token a clear, explicit record of exactly which scopes were actually granted for that specific token, Default and Optional alike.

i
Requesting a Scope Doesn’t Guarantee Approval

An application can request an Optional Client Scope by name, but that request is only honored if the scope is actually assigned to that specific Client in the first place (as either Default or Optional). Requesting a scope name that was never assigned to the Client at all is simply ignored — it doesn’t grant unexpected access purely by being mentioned in the request.

DData Flow & the Scope Resolution Lifecycle

Let’s trace one login request from initiation through to a token carrying a precise, resolved set of claims.
flowchart LR
    A["1. App builds authorization request with scope parameter"] --> B["2. Keycloak identifies the Client"]
    B --> C["3. Every Default Client Scope for this Client is included"]
    C --> D["4. Requested scopes checked against Client's assigned Optional scopes"]
    D --> E["5. Matching Optional scopes added to resolved set"]
    E --> F["6. Consent screen shown if required for Optional scopes"]
    F --> G["7. Protocol Mappers for all resolved scopes executed"]
    G --> H["8. Token issued with resulting claims + scope claim"]
    
Fig. 2 — The complete path from an application’s scope request to a fully resolved, issued token
1

Request Construction

The client application builds its authorization request, listing whichever scopes it wants to request beyond the implicit baseline.

2

Client Identification

Keycloak identifies which registered Client is making the request, loading that Client’s specific Default and Optional scope assignments.

3

Default Scope Inclusion

Every scope marked Default for this Client is automatically added to the resolved set, with no dependency on the request’s scope parameter.

4

Optional Scope Matching

Each scope named in the request’s scope parameter is checked against the Client’s assigned Optional scopes — only genuine matches are added.

5

Consent (If Configured)

If the realm or Client requires user consent, and any resolved Optional scopes are marked as requiring it, the user sees a consent screen naming what’s being shared.

6

Token Assembly

Protocol Mappers for every scope in the final resolved set run, and their resulting claims are written into the appropriate issued tokens.

It’s worth noting this resolution happens fresh on every login and every token refresh — an application that starts requesting an additional Optional scope it hadn’t asked for before will simply begin receiving that scope’s claims on its next fresh authentication, without any change needed on Keycloak’s configuration side, as long as the scope was already assigned to that Client as Optional.

EAdvantages, Disadvantages & Trade-offs

Splitting scopes into Default and Optional buys real flexibility — at the cost of a slightly more involved configuration model.

Advantages

  • Keeps tokens lean by default, including only what’s genuinely needed for baseline application functionality.
  • Lets applications request additional, more specific data only when a particular feature genuinely requires it.
  • Supports data-minimization and privacy-by-design principles by making sensitive claims opt-in rather than automatic.
  • Enables precise, per-Client tuning — the same scope can behave differently depending on which application it’s attached to.
  • Naturally integrates with consent screens, giving users visibility into exactly what optional data an application is requesting.

Disadvantages / Trade-offs

  • Requires deliberate configuration — a scope left as Optional when an application actually needs it as Default can cause confusing, hard-to-diagnose missing-claim bugs.
  • Adds a layer of indirection that developers integrating a new application must understand and account for in their authorization requests.
  • Misconfigured scope assignments can silently under- or over-share data if not reviewed carefully during Client setup.
  • Applications must remember to explicitly request every Optional scope they depend on — an easy detail to overlook during development.
Everyday Analogy

A restaurant with a fixed base menu plus optional à la carte add-ons gives diners real flexibility and keeps the base bill lean — but it also means the kitchen staff must clearly understand which items are automatic and which require an explicit order, or a diner might be surprised by a missing side dish they assumed would just show up.

FSecurity Considerations

Because Client Scopes directly shape what data flows into every issued token, this configuration deserves real security scrutiny.

Data Minimization as a Security Control

Keeping sensitive or rarely needed claims as Optional — rather than Default — reduces the amount of personal data present in every single token, directly shrinking what’s exposed if any individual token is ever intercepted, logged inappropriately, or leaked.

Review Default Scopes for Over-Sharing

It’s worth periodically reviewing exactly which claims are bundled into each Client’s Default scopes — a scope that made sense as Default early in an application’s life might, as the application’s scope of use grows, actually warrant being downgraded to Optional and requested only where genuinely needed.

!
A Real Risk: Full Scope Allowed Bypassing Careful Design

Enabling Full Scope Allowed on a Client entirely bypasses the deliberate, curated model Default and Optional Client Scopes are designed to provide — granting that Client every realm and client role the user holds, regardless of how carefully scopes were otherwise configured. This setting should be reserved for genuinely trusted, tightly controlled administrative or internal tooling Clients, not applied broadly as a convenience shortcut.

Consent as a Transparency Mechanism

Requiring user consent for Optional scopes that carry more sensitive claims gives users direct visibility into what a specific application is requesting beyond the baseline — an important transparency and trust-building mechanism, particularly for third-party or less-familiar applications connecting to a realm.

Role Scope Mappings as an Additional Filter

Beyond claim-level control, using Role Scope Mappings within a Client Scope to restrict which roles can even appear in that Client’s tokens provides an extra layer of defense — ensuring that even if a role is broadly assigned to a user elsewhere, it doesn’t automatically leak into every application’s token unless that specific Client genuinely needs visibility into it.

SECURITY PATTERN · LEAST-CLAIM TOKENS Recommended
The Idea

Keep each Client’s Default scopes limited to genuinely universal baseline claims, pushing anything more specific or sensitive to Optional scopes requested only by the specific application features that need them.

Why It Matters

This mirrors the broader least-privilege principle applied specifically to token contents — every claim included by default is one more piece of data present in every token, whether or not that particular login actually needed it.

GMonitoring, Logging & Metrics

Visibility into how scopes are actually being used in practice helps catch misconfiguration before it becomes a production problem.

Tracking Token Size Over Time

As Client Scopes are added or reconfigured, it’s worth periodically monitoring the size of issued tokens for high-traffic Clients — a steadily growing token size can indicate scope creep, where claims that are rarely used by the application are nonetheless being included in every single request.

Auditing Scope Requests via Events Logging

Keycloak’s Events Logging system (covered in a companion guide) can be reviewed to understand which scopes applications are actually requesting in practice, helping identify Optional scopes that are consistently requested (and might be better promoted to Default for that Client) versus scopes that are rarely or never used despite being configured.

Consent Screen Analytics

For realms with consent enabled, tracking how often users decline or hesitate on a consent screen listing a specific Optional scope can surface user-experience friction — if a particular scope’s request consistently causes drop-off, it may be worth reconsidering whether that data is genuinely necessary for the flow it supports.

i
A Useful Habit: Periodic Scope Audits

Treat Client Scope configuration the way many teams treat dependency audits in software projects — periodically reviewing which scopes are assigned to which Clients, whether each assignment is still appropriately Default versus Optional, and whether any scopes have quietly become unused legacy configuration worth cleaning up.

Alerting on Unexpected Scope Requests

In higher-security environments, monitoring for authorization requests attempting to request scope names that aren’t assigned to the requesting Client at all can be a useful, low-noise signal — while such requests are simply ignored rather than granted, a pattern of them might indicate misconfigured or misbehaving client integrations worth investigating.

HDesign Patterns & Anti-Patterns

How experienced teams structure Default and Optional scopes well — and the mistakes that quietly cause friction later.

Good Pattern: Default for Baseline, Optional for Feature-Specific Data

Keep Default scopes limited to what nearly every part of an application genuinely needs on every login — identity and basic profile information, typically — while pushing anything tied to a specific feature (like requesting a phone number only for an SMS-notification opt-in flow) into an Optional scope requested only where that feature is actually used.

Good Pattern: Mirror Scope Names to Their OpenID Connect Meaning

Where possible, align custom Client Scope names and behavior with the standard OpenID Connect scope conventions (like profile, email, phone) rather than inventing entirely bespoke naming — this keeps integrations predictable for developers already familiar with the broader OAuth 2.0 and OpenID Connect ecosystem.

Good Pattern: Separate Scopes by Sensitivity, Not Just Feature

Group claims into Client Scopes based partly on how sensitive they are, not purely on which feature uses them — this makes it easier to apply consent requirements or stricter review specifically to the more sensitive scopes without needing to touch less sensitive, more universally needed ones.

ANTI-PATTERN · EVERYTHING AS DEFAULT Avoid
What It Looks Like

Marking every available Client Scope as Default for a Client simply to avoid having to configure and remember explicit scope requests in application code.

Why It’s a Problem

It defeats the entire purpose of the Default/Optional distinction, bloats every issued token with claims the application may rarely use, and increases the amount of personal data exposed in every single token regardless of actual need.

ANTI-PATTERN · RELYING ON FULL SCOPE ALLOWED INSTEAD Avoid
What It Looks Like

Enabling Full Scope Allowed on a Client to sidestep configuring Client Scopes carefully, rather than deliberately assigning and tuning Default and Optional scopes for that specific application.

Why It’s a Problem

It grants sweeping, unfiltered access to every realm and client role a user holds, removing the precise, curated control that Client Scopes are specifically designed to provide — a convenience shortcut with outsized security implications.

ANTI-PATTERN · FORGETTING TO REQUEST NEEDED OPTIONAL SCOPES Avoid
What It Looks Like

An application depends on an Optional scope’s claims (like offline_access for background sync) but never actually includes that scope name in its authorization requests.

Why It’s a Problem

This produces confusing runtime bugs where a feature silently fails because expected claims or tokens simply never appear, even though the scope was correctly assigned to the Client on Keycloak’s side all along.

IBest Practices & Common Mistakes

Practical, hands-on guidance for configuring and working with Default and Optional Client Scopes well.
Best Practice

Start Minimal, Add Deliberately

Begin with a lean set of Default scopes and add Optional scopes explicitly as specific application features genuinely require them.

Best Practice

Document Scope Requirements Per Application

Keep a clear record of which Optional scopes each application depends on and why, so future developers understand what to request and why it matters.

Best Practice

Test Both With and Without Optional Scopes

Verify application behavior both when an Optional scope is requested and when it isn’t, ensuring graceful handling rather than assuming it will always be present.

Best Practice

Avoid Full Scope Allowed for Ordinary Clients

Reserve this setting for genuinely trusted internal tooling, preferring precise Default and Optional scope configuration for everything else.

Common Mistakes to Avoid

  • Assuming a scope is Default when it’s actually Optional: A developer integrating with a new Client may reasonably assume claims they’ve seen in another application’s tokens will “just be there,” without realizing that Client configured the scope differently.
  • Not reviewing scope assignments during Client provisioning: New Clients cloned from a template may inherit Default/Optional assignments that don’t actually fit their specific use case.
  • Overloading a single Client Scope with unrelated mappers: Bundling unrelated claims into one large scope makes it harder to selectively include only what’s genuinely needed for a specific use case.
  • Ignoring consent screen wording: Poorly named or described Optional scopes can confuse users during consent, undermining the very transparency the consent mechanism is meant to provide.

JReal-World & Industry Examples

Seeing how real applications use Default and Optional scopes makes the distinction concrete.

A Web Application’s Baseline Login

A typical customer-facing web application configures profile, email, and roles as Default scopes — every login automatically includes basic identity and permission information the application needs for virtually every page it renders.

A Mobile App’s Background Sync Feature

A mobile application that needs to sync data periodically, even when the app isn’t actively open, requests the offline_access Optional scope specifically during its initial login, obtaining the long-lived refresh capability that feature requires without burdening every other Client with that same capability by default.

An SMS Notification Opt-In Flow

An application offering optional SMS notifications requests the phone Optional scope only at the specific moment a user opts into that feature, rather than requesting phone number access on every ordinary login — a clean example of scope requests mapping directly to genuine feature need.

A Microservice Using microprofile-jwt

A Java-based microservice expecting claims in a specific format compatible with the MicroProfile JWT specification requests the microprofile-jwt Optional scope, tailoring its token’s claim structure to match what that particular framework expects — without affecting how tokens look for other, unrelated Clients in the same realm.

An Internal Admin Tool Using Full Scope Allowed

A tightly controlled, internal-only administrative tool — accessible to a small, trusted group and protected by additional network restrictions — might reasonably use Full Scope Allowed to simplify its access to a broad range of roles, a deliberate exception rather than a default posture applied broadly.

“Default scopes are the promise every login makes. Optional scopes are the promise an application has to ask for.”

KFrequently Asked Questions

Q1Does an application need to do anything special to receive Default scope claims?
No — Default Client Scopes are automatically included in every token issued to that Client, with no need to mention them in the authorization request’s scope parameter.
Q2What happens if an application requests an Optional scope that isn’t assigned to it?
The request is simply ignored for that scope — an application can only receive claims from Optional scopes that have actually been assigned to it in the Client’s configuration, regardless of what it names in its request.
Q3Can the same Client Scope be Default for one Client and Optional for another?
Yes — the Default/Optional categorization is configured per-Client, so the same underlying Client Scope can be treated differently depending on which application it’s attached to.
Q4Do Optional scopes always trigger a consent screen?
Only if the realm or Client is configured to require consent, and the specific scope is marked as needing it — not every Optional scope necessarily requires explicit user consent by default.
Q5How does Full Scope Allowed relate to Default and Optional scopes?
Full Scope Allowed is a separate, coarser setting that bypasses the fine-grained role filtering Client Scopes otherwise provide, granting broad access to every realm and client role a user holds — it isn’t part of the Default/Optional model itself.
Q6Can Client Scopes affect roles as well as identity claims?
Yes — through Role Scope Mappings, a Client Scope can restrict which of a Client’s available roles are eligible to appear in tokens issued under that scope, adding a second layer of control beyond just identity claims.
Q7Is it better to have many small scopes or a few large ones?
Generally, smaller, more purposeful scopes offer finer control and clearer intent — bundling too many unrelated claims into one large scope makes it harder to include only what a specific request genuinely needs.
Q8Does changing a scope from Optional to Default affect existing tokens?
No — existing, already-issued tokens are unaffected. The change takes effect on the next login or token issuance for that Client, since resolution happens fresh at that time.

LSummary & Key Takeaways

Key Takeaways

  • Client Scopes are reusable bundles of Protocol Mappers and Role Scope Mappings, defined once at the realm level and assigned per-Client.
  • Default Client Scopes are automatically included in every token issued to that Client, with no need for the application to request them explicitly.
  • Optional Client Scopes are only included when the application specifically names them in its authorization request’s scope parameter — and only if they’re actually assigned to that Client.
  • This distinction supports token size control, data minimization, and meaningful user consent, all at once.
  • The same Client Scope can be Default for one Client and Optional for another, since assignment happens per-Client rather than globally.
  • Full Scope Allowed is a separate, much coarser setting that bypasses this careful model entirely and should be reserved for genuinely trusted, tightly controlled Clients.
  • Well-run deployments keep Default scopes lean, push specialized or sensitive claims to Optional, and periodically audit scope assignments as applications and their needs evolve over time.