Summary
Add standard OAuth2 endpoints for /oauth/introspect and /oauth/revoke so resource servers can verify token status (active, scopes, expiry, subject) and clients can proactively revoke access and refresh tokens. Works with both JWT and opaque tokens; enables central revocation beyond JWT signature checks.
Why
- Plays nicely with gateways/API proxies that expect RFC endpoints.
- Lets services confirm a token is still valid (not expired/revoked) even if it’s a self-verifying JWT.
- Clean logout flows: clients can revoke refresh tokens and derived access tokens immediately.
- Complements the OIDC provider feature and supports mixed ecosystems.
Scope (MVP)
Endpoints
-
POST /oauth/introspect
-
Auth: client authentication (basic or body client_id/client_secret for confidential clients; public clients denied).
-
Request: token, optional token_type_hint (access_token | refresh_token).
-
Response (per RFC 7662):
{
"active": true,
"scope": "openid email",
"client_id": "myapp-web",
"username": "[email protected]",
"token_type": "access_token",
"exp": 1712345678,
"iat": 1712342078,
"nbf": 1712342078,
"sub": "user-uuid",
"aud": "myapp-web",
"iss": "https://auth.example.com",
"jti": "uuid-of-token"
}
-
If inactive/unknown/expired → {"active": false}.
-
POST /oauth/revoke
-
Auth: confidential client auth (same as above).
-
Request: token, optional token_type_hint.
-
Effect:
- If refresh token → revoke that session + invalidate its descendant access tokens.
- If access token (opaque or JWT) → mark as revoked (store
jti) until expiry.
-
Response: 200 with empty body (idempotent per RFC 7009).
Token model & storage
- Store
jti, sub, client_id, scopes, exp, type for refresh and opaque access tokens in SQLite.
- For JWT access tokens, include
jti claim and maintain a revocation set (SQLite table) to deny listed JTIs at introspect and during internal validation.
- Indexes on
jti, client_id, sub, exp.
Client policy
- Public clients: may not call introspect/revoke (lack client secret).
- Confidential clients: must match the token’s
client_id unless server policy allows broader admin clients.
- Rate-limit per client & IP.
Config (TOML)
[oauth_introspection]
enable = true
allow_jwt_access_tokens = true # if true, introspect JWTs too
include_username = true # mirror email as username
[oauth_revocation]
enable = true
revoke_access_jwt_by_jti = true # maintain revocation list for JWTs
Acceptance Criteria
-
POST /oauth/introspect returns active:true for valid tokens; false for expired/unknown/revoked.
-
POST /oauth/revoke successfully revokes:
- refresh token → subsequent refresh fails; new access tokens no longer issued.
- access token (JWT or opaque) → introspection shows
active:false; internal middleware denies it.
-
Confidential client auth enforced; public clients rejected with 401/400.
-
Proper handling of token_type_hint (optional optimization; not required).
-
Unit tests: happy paths, wrong client auth, wrong client_id, expired, already revoked, JWT jti revocation.
-
Integration tests: full login → introspect(active) → revoke → introspect(inactive).
-
Basic DoS safeguards: per-route rate limiting & short DB queries (indexes present).
Security Notes
- Always require client authentication for these endpoints; do not leak token metadata to unauthorized parties.
- Introspection must only reveal claims for the owning client (or an admin client role).
- Store only necessary fields; avoid logging raw tokens.
- Keep revocation list bounded by TTL (delete expired rows).
- Ensure constant-time comparisons where applicable.
Out of Scope (v1)
- UMA/RPT, token exchange, back-channel logout, PAR.
- Admin UI for viewing sessions (future).
- JWT Detachment or MTLS-bound tokens.
Migration / Docs
-
New sections in README.md: Introspection & Revocation with cURL examples.
-
Add docs/oauth-introspection-revocation.md covering policies, examples for NGINX/Kong/API Gateway integration.
-
Provide sample snippet for resource servers:
- Prefer local JWT verify; fallback to introspect for revocation checks, or periodic revocation cache.
Summary
Add standard OAuth2 endpoints for /oauth/introspect and /oauth/revoke so resource servers can verify token status (active, scopes, expiry, subject) and clients can proactively revoke access and refresh tokens. Works with both JWT and opaque tokens; enables central revocation beyond JWT signature checks.
Why
Scope (MVP)
Endpoints
POST /oauth/introspectAuth: client authentication (basic or body
client_id/client_secretfor confidential clients; public clients denied).Request:
token, optionaltoken_type_hint(access_token|refresh_token).Response (per RFC 7662):
{ "active": true, "scope": "openid email", "client_id": "myapp-web", "username": "[email protected]", "token_type": "access_token", "exp": 1712345678, "iat": 1712342078, "nbf": 1712342078, "sub": "user-uuid", "aud": "myapp-web", "iss": "https://auth.example.com", "jti": "uuid-of-token" }If inactive/unknown/expired →
{"active": false}.POST /oauth/revokeAuth: confidential client auth (same as above).
Request:
token, optionaltoken_type_hint.Effect:
jti) until expiry.Response:
200with empty body (idempotent per RFC 7009).Token model & storage
jti,sub,client_id,scopes,exp,typefor refresh and opaque access tokens in SQLite.jticlaim and maintain a revocation set (SQLite table) to deny listed JTIs at introspect and during internal validation.jti,client_id,sub,exp.Client policy
client_idunless server policy allows broader admin clients.Config (TOML)
Acceptance Criteria
POST /oauth/introspectreturnsactive:truefor valid tokens;falsefor expired/unknown/revoked.POST /oauth/revokesuccessfully revokes:active:false; internal middleware denies it.Confidential client auth enforced; public clients rejected with 401/400.
Proper handling of
token_type_hint(optional optimization; not required).Unit tests: happy paths, wrong client auth, wrong client_id, expired, already revoked, JWT
jtirevocation.Integration tests: full login → introspect(active) → revoke → introspect(inactive).
Basic DoS safeguards: per-route rate limiting & short DB queries (indexes present).
Security Notes
Out of Scope (v1)
Migration / Docs
New sections in
README.md: Introspection & Revocation with cURL examples.Add
docs/oauth-introspection-revocation.mdcovering policies, examples for NGINX/Kong/API Gateway integration.Provide sample snippet for resource servers: