This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 3, 2026. Spotted a mistake? Tell us.
Token introspection (RFC 7662) is how a resource server asks the authorization server whether a token is still valid, and what it grants. Token revocation (RFC 7009) is how a client or the server retires a token before it expires.
Both matter most when tokens are opaque. A JWT can be validated locally with a public key, but a random-looking access token cannot be checked without asking the server that issued it. Even with JWTs, introspection is the only way to learn that a token was revoked or that its user was disabled.
Opaque tokens vs JWTs
- A JWT carries claims. The resource server verifies the signature and checks
exp,aud,issand scope locally. Validation is fast and offline, but a JWT stays valid until it expires unless the service consults another source. - An opaque token carries no readable claims. Every check requires the authorization server. The token can be revoked instantly, and the response can include live user state.
Many deployments mix both: short-lived JWTs for normal traffic, introspection for sensitive operations, and a revocation endpoint for logout and incident response.
The introspection request
The resource server posts to the introspection endpoint with its own client credentials:
POST /introspect
Authorization: Basic <resource-server credentials>
Content-Type: application/x-www-form-urlencoded
token=<access token>&token_type_hint=access_token
tokenis required.token_type_hintis optional and only a hint; the server must still find the token if the hint is wrong.- The caller must authenticate. Introspection is not an anonymous endpoint: an unauthenticated caller could probe tokens.
The response
active is the only required member. false means the token is invalid, expired, revoked or unknown; the server should not explain which. When active is true, the response can include:
| Field | Meaning |
|---|---|
scope |
Space-separated scopes granted |
client_id |
The client the token was issued to |
username |
Human-readable subject, when the server exposes it |
token_type |
For example Bearer |
exp, iat, nbf |
Validity window |
sub, aud, iss, jti |
Subject, audience, issuer and token identifier |
Treat the response as authoritative for the decisions it covers. Do not introspect a token and then still skip audience checks: a token issued for another service may be active but not valid for this one.
When to introspect
Introspection is a network call on the request path, so use it deliberately:
- Every request when tokens are opaque and revocation must be immediate.
- On sensitive actions such as payments, admin operations or data export, even when JWTs are used for ordinary reads.
- At token exchange boundaries when a service accepts tokens from several issuers.
- Never as a substitute for signature checks on JWTs in normal traffic; that turns a fast local check into a round trip to the authorization server.
If you introspect on every request, cache the result briefly, keyed by token hash, and make sure the cache lifetime is shorter than the revocation SLA you promise. Cache the negative result too, but for a very short time, so a revoked token cannot keep working from a stale positive entry.
Revocation
Revocation (RFC 7009) is a POST to the revocation endpoint with the token and optional token_type_hint, authenticated as the client. The server responds 200 OK even when the token is already invalid or unknown; that behavior is intentional, because it avoids telling an attacker whether a token existed.
Revocation is not instantaneous across a distributed system. If resource servers validate JWTs locally, a revoked JWT can still be accepted until it expires. The practical controls are short access-token lifetimes, refresh-token revocation, and introspection or a revocation feed for high-risk operations.
Revoke on:
- User logout, when the client owns the token.
- Password change or account disable.
- A detected leak, lost device or suspicious session.
- Client decommissioning.
Common mistakes
- Introspecting without authenticating. Some servers leave the endpoint open; do not rely on that in production.
- Trusting
token_type_hint. The server must look up the token regardless of the hint. - Caching a positive result forever. A cached active response defeats revocation.
- Forgetting audience checks. Active does not mean "valid for this API".
- Skipping the user-state check. A token can be structurally valid while the account is disabled. Good introspection implementations fold that into
active. - Building revocation on JWTs alone. Without introspection or a shared deny list, a revoked JWT remains valid until
exp.
Introspection and revocation in Casdoor
Casdoor exposes both endpoints in its discovery document:
- Introspection:
POST /api/login/oauth/introspect, with client authentication and thetokenform field plus an optionaltoken_type_hint. The response includesactive,scope,username,token_type,exp,iat,nbf,sub,aud,issandjti. - Revocation:
POST /api/login/oauth/revoke, acceptingtoken,token_type_hintand client credentials (basic auth or form fields). It returns200with an empty body on success, as RFC 7009 expects.
Casdoor returns active: false for tokens that are expired, revoked, or whose user has since been disabled or deleted, so a resource server can rely on the field instead of re-checking the user itself. For JWTs, the response is built from the token's claims; for opaque tokens, Casdoor looks the token up in its store.
If you are protecting an API, introspect opaque tokens on the request path with a short positive cache, and introspect JWTs only for sensitive actions. Casdoor is open source, and Casdoor Cloud starts at $6.67/month billed yearly for a dedicated instance.
FAQ
Is introspection the same as userinfo? No. Userinfo returns profile claims for a user. Introspection returns token metadata for a resource server, including whether the token is still active.
Should the introspection endpoint be public? No. Require client authentication and restrict which clients may introspect. The endpoint reveals whether a token is valid.
Can I revoke a JWT? You can revoke the refresh token and stop issuing new access tokens, but an already-issued JWT remains valid until it expires unless resource servers consult introspection or a deny list. Keep access tokens short-lived.
Does revocation return an error for an unknown token? No. RFC 7009 says to return 200, because reporting "not found" leaks information.
How often should I introspect? As often as your revocation SLA requires. For most APIs, a positive cache of a few seconds to a few minutes is a reasonable trade-off between load and freshness.
Sources
- RFC 7662: OAuth 2.0 Token Introspection
- RFC 7009: OAuth 2.0 Token Revocation
- RFC 6750: Bearer Token Usage
- RFC 9700: OAuth 2.0 Security Best Current Practice
- Casdoor OAuth documentation
Product names are trademarks of their respective owners.