What Is an Access Token in Keycloak?
The short-lived, signed proof of permission that lets an application call a protected API on a user's behalf — without ever asking for their password again.
Once a user has successfully logged in through Keycloak, something interesting happens: the application doesn’t keep asking for a password on every single action the user takes. Instead, it holds onto a small, cryptographically signed piece of text called an Access Token, and presents that token every time it needs to call a protected API on the user’s behalf. This one small object is the workhorse of modern API security — and understanding exactly what’s inside it, how it’s verified, and how it differs from Keycloak’s other tokens is essential for anyone building or securing applications on top of Keycloak. This guide covers it end to end.
ACore Concepts: What Exactly Is an Access Token?
An Access Token is a signed, time-limited piece of proof issued by Keycloak after a successful login, which an application presents to a protected resource — typically an API — to say, in effect, “here is cryptographic evidence that this specific user, with these specific permissions, is allowed to make this request.” The resource receiving it doesn’t need to call Keycloak back and ask “is this really valid?” for every single request — it can verify the token’s authenticity entirely on its own, using Keycloak’s published public signing key.
In Keycloak, Access Tokens are typically formatted as a JSON Web Token (JWT) — a compact, URL-safe string made up of three parts separated by dots: a header, a payload (the actual claims about the user and their permissions), and a cryptographic signature. Anyone can decode and read a JWT’s contents (it isn’t encrypted by default), but only Keycloak, holding the matching private key, could have produced a validly signed one.
Think of a Access Token like a concert wristband. Once security checks your ticket at the entrance (your login), they snap on a wristband that clearly shows your access level — general admission, VIP, backstage. For the rest of the night, staff at each checkpoint just glance at the wristband instead of re-checking your original ticket every time. The wristband is time-limited (it’s useless after the concert ends) and hard to fake convincingly (special material, a stamp), which is exactly the role an Access Token plays for API calls.
Keycloak actually issues three related but different tokens after a login: the ID Token (describes who the user is, meant for the client application itself), the Access Token (proves permission to call APIs, meant for resource servers), and the Refresh Token (used to get new Access Tokens later without a fresh login). This guide focuses specifically on the Access Token.
What actually lives inside an Access Token’s payload? A set of claims — structured pieces of information such as who issued it, who it’s intended for, when it expires, which user it represents, and which roles or permissions that user holds. Applications and APIs read these claims directly from the token itself, rather than needing a separate lookup for basic authorization decisions.
BArchitecture & Core Components
flowchart TB
User["User"] --> Client["Client Application"]
Client -->|"Login request"| Keycloak["Keycloak Token Endpoint"]
Keycloak --> SigningKey["Realm Signing Key (private)"]
Keycloak -->|"Issues"| AccessToken["Access Token (JWT)"]
Keycloak -->|"Issues"| IDToken["ID Token"]
Keycloak -->|"Issues"| RefreshToken["Refresh Token"]
Client -->|"Presents Access Token"| API["Protected API / Resource Server"]
API -->|"Verifies signature using"| PublicKey["Realm Public Key (JWKS endpoint)"]
Let’s walk through the components shown in this diagram.
The Realm Signing Key
Each Keycloak realm maintains its own cryptographic key pair. The private half is used internally by Keycloak to sign every token it issues; the public half is published openly (typically at a well-known JWKS — JSON Web Key Set — endpoint) so that any resource server can verify a token’s signature without ever needing the private key itself.
The Token Endpoint
The specific Keycloak endpoint responsible for actually issuing tokens once a login (or a refresh) succeeds. Client applications call this endpoint as part of the OpenID Connect / OAuth 2.0 flow to obtain the Access Token, ID Token, and Refresh Token together.
Claims: realm_access and resource_access
Two especially important claims inside a Keycloak Access Token describe permissions: realm_access lists the realm-level roles the user holds, while resource_access breaks down client-specific roles per application — letting one token carry precise, per-application permission data in a single compact payload.
The Resource Server
Any protected API expecting to receive an Access Token on incoming requests. It verifies the token’s signature against the realm’s public key, checks that it hasn’t expired, confirms it was issued for the correct audience, and only then trusts the claims inside to make an authorization decision.
People sometimes assume a resource server must call back to Keycloak on every single request to check if a token is valid. For standard signed JWT Access Tokens, that’s not necessary — the resource server can verify the signature and claims entirely offline, using the realm’s already-fetched public key, which is exactly what makes JWTs fast at scale.
CHow Access Tokens Work Internally
The Three Parts of a JWT
A JWT Access Token is really just three Base64-encoded segments joined by dots. The header describes the signing algorithm used. The payload contains the actual claims — user identity, roles, expiration, and more. The signature is a cryptographic proof, computed over the header and payload together using the realm’s private key, that lets anyone detect if even a single character of the token has been tampered with.
Common Claims Inside a Keycloak Access Token
- iss (issuer): Identifies which Keycloak realm issued the token.
- sub (subject): The unique internal ID of the authenticated user.
- aud (audience): Which client(s) or resource server(s) the token is intended for.
- exp (expiration): The exact timestamp after which the token is no longer valid.
- realm_access / resource_access: The user’s realm and client-specific roles, as described earlier.
- scope: The granted OAuth 2.0 scopes, describing what categories of access were requested and approved.
Verification Without a Round-Trip
When a resource server receives a request with an Access Token attached, it decodes the token, re-computes what the signature should be using the realm’s public key, and compares it against the signature actually present. If they match, and the expiration hasn’t passed, and the audience matches, the resource server trusts the claims inside — all without a single network call back to Keycloak.
This is like a banknote with a security watermark. A shopkeeper doesn’t need to call the central bank every time they receive a note — they can hold it up to the light and check the watermark themselves, instantly, because the verification method is public even though only the mint could have produced a genuine note.
Reference Tokens: The Alternative Model
Keycloak also supports an alternative approach called reference tokens — a short opaque string instead of a full JWT, which the resource server must actively send back to Keycloak’s token introspection endpoint to validate on each use. This trades the offline-verification speed of JWTs for the ability to instantly revoke a token server-side at any moment.
DData Flow & the Token Lifecycle
flowchart LR
A["1. User authenticates successfully"] --> B["2. Keycloak issues Access + ID + Refresh Tokens"]
B --> C["3. Client stores tokens securely"]
C --> D["4. Client calls API with Access Token"]
D --> E["5. API verifies signature and claims"]
E --> F["6. API grants or denies based on roles"]
F --> G["7. Access Token eventually expires"]
G --> H["8. Client uses Refresh Token to get a new Access Token"]
Issuance
After a successful login (or a successful token refresh), Keycloak’s Token Endpoint issues a new Access Token alongside an ID Token and Refresh Token.
Storage
The client application holds onto the Access Token — ideally in a secure location appropriate to its platform, such as memory rather than easily accessible browser storage for sensitive front-end apps.
Use on API Calls
The client attaches the Access Token to outgoing API requests, typically in an Authorization: Bearer header.
Verification & Authorization
The receiving API verifies the token and uses its embedded roles and scopes to decide whether to allow the specific requested action.
Expiration
After the configured lifespan passes, the Access Token stops being accepted by any resource server, regardless of whether the user is still “logged in” at the application level.
Silent Renewal
The client uses its still-valid Refresh Token to request a brand-new Access Token from Keycloak, usually without requiring the user to log in again — keeping the experience seamless.
EAdvantages, Disadvantages & Trade-offs
Advantages
- Resource servers can verify tokens offline, with no network round-trip to Keycloak, enabling very fast, scalable API calls.
- All the permission information an API needs travels inside the token itself, simplifying authorization logic.
- Short lifespans naturally limit how long a stolen token remains useful to an attacker.
- Standardized JWT format means broad, mature library support across virtually every programming language and framework.
Disadvantages / Trade-offs
- A standard signed JWT cannot be instantly revoked before its natural expiration — it remains valid until it expires, even if the underlying account is disabled moments later.
- Anyone can decode and read a JWT’s payload (it’s not encrypted by default), so sensitive data should never be placed inside its claims.
- Short lifespans mean more frequent token refresh traffic, which must be handled gracefully by client applications.
- Reference tokens solve the revocation problem but reintroduce a network call on every single request, trading speed for control.
A signed JWT Access Token is like a printed, dated parking permit — fast for a security guard to check at a glance, but if you need to cancel someone’s permit mid-day, you can’t reach into their car and erase it; you have to wait for the printed date to pass, or switch to a system that phones the office to check every single time (a reference token).
FSecurity Considerations
Keep Lifespans Short
Configuring a short Access Token lifespan (commonly just a few minutes) limits the window during which a stolen token remains usable, even though it means more frequent, mostly invisible refresh operations behind the scenes.
Always Validate the Audience
A resource server must confirm the aud claim actually names it as an intended recipient — accepting a token issued for a completely different application is a classic, dangerous integration mistake.
Never Put Sensitive Data in the Payload
Because JWT payloads are readable by anyone who obtains the token (they’re only signed, not encrypted, by default), sensitive personal data or secrets should never be embedded directly inside an Access Token’s claims.
Access Tokens accidentally logged in plaintext, or passed as URL query parameters that end up in browser history or server access logs, can leak just as damagingly as a stolen password. Tokens should always travel in headers over HTTPS and be explicitly excluded from application logging.
Secure Client-Side Storage
For browser-based applications, storing Access Tokens in locations vulnerable to cross-site scripting (like unprotected local storage) creates real risk; many security-conscious teams prefer in-memory storage or backend-for-frontend patterns that keep tokens away from client-side JavaScript entirely.
The Idea
Pair a short Access Token lifespan with a comparatively longer-lived, more carefully protected Refresh Token used only to obtain new Access Tokens.
Why It Matters
This balances usability (users aren’t forced to log in constantly) against security (a stolen Access Token alone expires quickly, and Refresh Tokens can be individually revoked server-side if compromise is detected).
GDesign Patterns & Anti-Patterns
Good Pattern: Validate Fully, Every Time
Resource servers should always check signature, expiration, issuer, and audience on every request — never assume a token is valid just because it decodes successfully or “looks right.”
Good Pattern: Scope Tokens Narrowly
Request and issue only the specific scopes and roles a client genuinely needs, rather than defaulting to broad, all-encompassing permissions embedded in every token.
Good Pattern: Rotate Signing Keys Periodically
Configuring Keycloak to rotate its realm signing keys on a schedule limits how long any single compromised key could be misused, while the JWKS endpoint lets resource servers adapt automatically without manual reconfiguration.
What It Looks Like
A resource server decodes a JWT’s payload and trusts its claims directly, without actually verifying the cryptographic signature against the realm’s public key.
Why It’s a Problem
Without signature verification, anyone can craft an arbitrary token payload claiming any identity or role they want — this single omission defeats the entire security model of signed tokens.
What It Looks Like
Extending the Access Token lifespan to hours or days purely to reduce refresh traffic or simplify client implementation.
Why It’s a Problem
Because a standard JWT Access Token can’t be instantly revoked, a long lifespan directly extends how long a stolen or leaked token remains dangerously usable.
HBest Practices & Common Mistakes
Use Established Libraries
Rely on well-maintained JWT and OpenID Connect libraries for validation rather than writing custom signature-checking logic by hand.
Fetch JWKS Dynamically
Retrieve and cache the realm’s public keys from its JWKS endpoint rather than hardcoding a key that will eventually be rotated.
Monitor Token-Related Errors
Track expired, invalid-signature, and audience-mismatch errors in production, since spikes can indicate misconfiguration or active attack attempts.
Choose Reference Tokens for High-Sensitivity Cases
Consider opaque reference tokens with introspection for scenarios where instant revocation matters more than raw verification speed.
Common Mistakes to Avoid
- Trusting an unverified token’s claims: Reading a JWT’s payload without checking its signature is functionally the same as trusting user-supplied input blindly.
- Ignoring token expiration client-side: Applications that don’t gracefully handle an expired Access Token can produce confusing failures instead of a smooth refresh.
- Embedding sensitive data in claims: Placing anything genuinely secret inside a readable JWT payload defeats its purpose.
- Reusing one client’s Access Token against a different, unrelated API: Skipping audience checks can allow a token meant for one service to be misused against another.
IReal-World & Industry Examples
Microservices Architectures
Companies running many small backend services commonly have a single Keycloak realm issue Access Tokens that every microservice can verify independently and offline, avoiding a centralized authentication bottleneck on every internal call.
Mobile Apps Calling Backend APIs
Mobile applications typically store a Refresh Token securely on-device and request short-lived Access Tokens as needed, keeping the actual bearer credential used on each API call valid for only a brief window.
Single-Page Applications with a Backend-for-Frontend
Security-conscious single-page applications increasingly keep Access Tokens on a backend server rather than in browser JavaScript, using a backend-for-frontend pattern to reduce exposure to cross-site scripting risks.
Service-to-Service Calls via Client Credentials
Backend services authenticating to each other (with no human user involved) commonly use Keycloak’s client-credentials flow to obtain their own Access Tokens representing the calling service itself, following the same verification model as user-issued tokens.
JFrequently Asked Questions
realm_access claim, while roles specific to individual client applications appear under resource_access, letting one token carry precise, per-application permission data.KSummary & Key Takeaways
Key Takeaways
- An Access Token is a signed, short-lived proof of permission that a client application presents to protected APIs, typically formatted as a JWT.
- It is distinct from the ID Token (identity, for the client itself) and the Refresh Token (used to obtain new Access Tokens without a fresh login).
- Resource servers verify it offline using the realm’s public signing key, checking signature, expiration, issuer, and audience before trusting its claims.
- Claims like
realm_accessandresource_accesscarry precise role-based permission data directly inside the token itself. - Short lifespans, careful audience validation, and secure client-side storage are essential protections given how much trust an Access Token carries.
- Reference tokens with introspection offer an alternative when instant revocation matters more than the speed of offline JWT verification.