OAuth2 Service Account Verifier

A teaching tool: every step the resource server normally performs internally, surfaced and inspectable.

origin: … flow: client_credentials not signed in
  1. 1Token request
  2. 2Decode
  3. 3Verify

SPA sign-in (PKCE) config

The OAuth client this verifier presents to Keycloak when collecting the user's subject_token. Register an app in the console (Identity → App Registrations, type SPA, with this verifier's callback URL in its allowed redirect URIs), then paste its client_id below. The signed-in user's token will carry this value in its azp claim — iam-service validates azp against the registered apps list before honoring an OBO exchange.

0. Pick a grant

Choose how the verifier should obtain its bearer token. client_credentials is the original M2M flow (a service account using its own secret). token-exchange (RFC 8693) is the on-behalf-of flow: the user signs in via PKCE first, then the SA swaps that user_token for an OBO access_token.

1. Authenticate and verify

Send the SA's client_id + client_secret to iam-service's /oauth/token endpoint, then decode and verify the issued JWT. Every field below maps directly to a form-encoded parameter in the request body. Switch the grant above to token-exchange (OBO) to send a user subject_token instead and receive a delegation token.

Live request body (form-encoded)
// fill the inputs above to see the request body
This is exactly what the SPA will POST when you click Run. Updates as you edit any field above.
1

Token request

Send client_id + client_secret to the OAuth2 token endpoint and receive a signed JWT.

pending
Raw response
// (no token yet)
The exact request that produced this response is shown live in the panel on the left.
2

Token decoding

A JWT is three base64url-encoded segments joined by .; decode the first two and look at the claims your token actually carries.

pending
header
payload
signature
Decoded header
// pending
Decoded payload
// pending
Highlighted claims
// pending
3

Verification replay

This is the work the resource server's auth middleware does silently on every request. Here you watch it happen.

pending
JWKS document fetched from issuer
// pending
Matching key (by kid)
// pending
Verification checklist
  • kid present in JWKS
  • RS256 signature valid (Web Crypto)
  • exp in the future
  • iss matches expected issuer
  • aud matches expected audience