Keycloak is the Identity Provider for this PoC: it authenticates users, owns session state, and issues the JWTs that drive every downstream authorization decision.
What An IdP Is
An IdP (Identity Provider) is the system responsible for authenticating users and issuing tokens. See 01 — Concepts for the full glossary.
In short:
- the IdP proves who the user is
- other systems decide what that user can do
Why This Project Needs An IdP
Without an IdP, every service would need to implement and maintain its own login logic, token issuing logic, password handling, user storage, and claim management.
That would create:
- duplicated security code
- inconsistent identity rules across services
- harder auditing and troubleshooting
- harder integration with gateways and policy engines
This project uses Keycloak as the IdP so identity is centralized:
- one place to authenticate users
- one place to manage roles like
customerandops-admin - one place to issue JWTs
- one place to define claims like
customer_idandaccount_ids
Where Keycloak Sits In This PoC
Keycloak is not the gateway, not the policy engine, and not the banking API. It is the source of identity and token claims.
How Keycloak Works
Realm
A realm is a security boundary with its own users, clients, roles, and token settings.
This project uses the realm banking-poc. All demo users and clients live inside that realm.
Users
Users are the identities that log in. The demo users in this PoC are:
aliceops-admin
The identity-bootstrap-service creates and manages these users via Keycloak admin APIs, setting attributes such as:
customer_idaccount_idsdemo_managed
Roles
Roles represent coarse-grained permission groups. This PoC uses two realm roles:
customerops-admin
These roles appear in the JWT and are used by Kong, OPA, and banking-api-service.
Clients
A client is an application or service that interacts with Keycloak. This repo defines two:
mobile-banking-app— the public client used by the demo login flow to obtain access tokens (directAccessGrantsEnabled: true,publicClient: true)kong-introspection— a confidential service-account client (publicClient: false,serviceAccountsEnabled: true) used byKongto introspect tokens
Protocol Mappers
Protocol mappers control what claims go into the token. mobile-banking-app maps:
customer_id— from user attribute, written to access token, ID token, and userinfoaccount_ids— from user attribute (multivalued), written to access token, ID token, and userinfo- audience
mobile-banking-app— written to access token only
Those claims flow downstream: Kong forwards them to OPA, OPA uses them in policy, and banking-api-service uses them for defense-in-depth checks.
Tokens
After a successful login, Keycloak issues a signed JWT access token containing:
subpreferred_usernameaudissexprealm_access.rolescustomer_idaccount_ids
The token is signed by Keycloak, which allows downstream systems to validate it cryptographically.
OAuth 2.0 And OpenID Connect In This Project
Keycloak speaks standard identity protocols.
OAuth 2.0
OAuth 2.0 is a framework for delegated access. It provides a standard way to obtain access tokens and use them when calling APIs.
OpenID Connect
OpenID Connect is an identity layer on top of OAuth 2.0. It standardizes identity claims and endpoints.
In practice:
- Keycloak authenticates users
- Keycloak issues OIDC-compatible JWTs
- services use those tokens to identify the caller
Flow Used Here
The demo script uses direct username/password token exchange (directAccessGrantsEnabled) against Keycloak.
What matters for this PoC:
- credentials go to Keycloak
- Keycloak validates them
- Keycloak returns a signed JWT access token
- that token is sent to
Kongand the banking API path
Keycloak Sessions And Token Activity
Keycloak owns the live session state behind the JWT, which is why token introspection can answer active: false even for a structurally valid JWT. See 11 — JWT Signature, Validation & Introspection for full introspection mechanics.
Logical Session Types
Keycloak tracks three layers of session state:
- Authentication session (short-lived) — temporary state during the login flow; removed after login completes or expires
- User session — represents the authenticated user in a realm; tracks start time, idle/expiry state, and logout status
- Client session (per client app) — attached to a user session for each client such as
mobile-banking-app; tracks client-specific participation in that login session
Physical Storage
At runtime, Keycloak stores online session state in Infinispan caches. In clustered deployments these caches are distributed across nodes. Offline sessions are persisted in the database.
The key practical point: token claims travel in the JWT, but live session state lives server-side in Keycloak. That is why a token can decode correctly while introspection still returns active: false.
For the access token / refresh token lifecycle and how each relates to session state, see 13 — Access & Refresh Token Lifecycle.
Token Issuance And Validation Flow
Why JWT Validation Still Matters After Login
A common misunderstanding:
“Keycloak already authenticated the user, so the service does not need to validate the token again.”
That is wrong. Once the token leaves Keycloak, downstream systems must still verify that the token was really issued by Keycloak, is meant for this application, has not expired, and has not been tampered with.
That is why this PoC validates tokens in more than one place:
Kongintrospects with Keycloakbanking-api-servicevalidates JWT signature, issuer, and audience
How Keycloak Is Configured In This Repo
The main configuration file is infra/keycloak/realm-export.json.
Key settings verified from that file:
| Setting | Value |
|---|---|
| Realm | banking-poc |
| Realm roles | customer, ops-admin |
| Public client | mobile-banking-app (directAccessGrantsEnabled: true) |
| Confidential client | kong-introspection (serviceAccountsEnabled: true) |
| Protocol mappers | customer_id, account_ids (user attributes), aud=mobile-banking-app |
| User profile attributes | customer_id (single-value), account_ids (multivalued) — admin-edit only |
The realm-export also declares the user-profile schema so the identity-bootstrap-service can write customer_id and account_ids attributes safely.
How Keycloak Interoperates With The Other Components
Keycloak And identity-bootstrap-service
The bootstrap service uses Keycloak admin APIs to:
- create demo users
- set passwords
- assign realm roles
- set custom attributes (
customer_id,account_ids,demo_managed)
This makes the PoC repeatable without manual Keycloak configuration.
Keycloak And Kong
Kong uses Keycloak token introspection to check whether a token is active before forwarding the request or asking OPA for a decision. Kong authenticates to Keycloak using the kong-introspection confidential client credentials.
Keycloak And OPA
OPA does not talk directly to Keycloak. Instead:
- Keycloak issues claims in the JWT
Kongreads validated token context after introspectionKongsends the relevant claims toOPAOPAuses those claims in policy
So Keycloak influences OPA decisions indirectly through token claims.
Keycloak And banking-api-service
banking-api-service trusts Keycloak as the token issuer but validates independently:
- signature (via JWKS)
- issuer
- audience
Then reads claims such as realm_access.roles, customer_id, and account_ids for service-side authorization checks.
Claim Flow In This PoC
Practical Examples In This PoC
Example 1: alice Accessing Her Own Account
Keycloak issues a token for alice containing:
- role
customer customer_id=C-1001account_ids=[A-1001]
Then:
Kongconfirms the token is activeOPAseesA-1001is in the token claimsbanking-api-servicechecks the same claim set again- the request is allowed
Example 2: alice Accessing Another Account
If alice requests account A-2001:
- the token is still a valid identity token
- but the claims do not authorize access to
A-2001 OPAreturns denyKongreturns403
This shows the key idea: valid identity does not automatically mean valid authorization.
Example 3: ops-admin Access
If the user has the ops-admin role:
OPAallows broader accessbanking-api-servicealso sees the role and allows service-side access
Why Keycloak Is A Good Fit Here
Keycloak provides:
- centralized authentication
- standard token issuance (OIDC/OAuth 2.0)
- support for custom claims via protocol mappers
- admin APIs for automated demo setup
- standard integration patterns for gateways and services
It lets the project focus on banking authorization logic rather than reinventing login infrastructure.
Common Misunderstandings
“Keycloak already handles all security”
No. Keycloak handles identity and token issuance. It does not replace gateway enforcement (Kong), policy evaluation (OPA), or business-service checks (banking-api-service).
“OPA could replace Keycloak”
No. OPA is the PDP — it decides policy. It does not authenticate users or issue tokens.
“Kong could replace Keycloak”
No. Kong is the PEP — the gateway. It is not the identity provider.
“Spring Boot could just do everything itself”
Technically it could do more, but that would collapse identity, policy, and business logic into one place and make the architecture harder to maintain and reason about.
Summary
- Keycloak authenticates the user
- Keycloak issues a JWT with identity and entitlement claims
Kongchecks token activity and asksOPAfor an authorization decisionbanking-api-servicevalidates the JWT again and enforces service-side checks
That is why Keycloak matters in this project: it is the system that makes the rest of the security flow possible in a standard, centralized, and repeatable way.
📚 返回专栏目录

427

被折叠的 条评论
为什么被折叠?



