Not by itself. A self-contained JWT is valid until its exp time unless the API checks something else, such as a revocation list or the authorization server. Your options are short lifetimes, refresh token revocation under RFC 7009, a denylist of token IDs, or opaque tokens that the API introspects.
Why revocation is hard for JWTs
When an API validates a JWT locally, it checks the signature and claims and never calls the issuer. That is fast and scales, and it is also why the issuer cannot pull the token back. The token carries its own proof of validity.
RFC 7009 acknowledges this design choice. It says access tokens may be self-contained so that a resource server needs no further interaction with the authorization server, or they may be handles that refer to authorization data stored at the server.
What RFC 7009 gives you
RFC 7009 defines a revocation endpoint. A client sends the token it no longer needs, with an optional token_type_hint. The server first validates the client, then checks the token was issued to that client, and invalidates it. The RFC says invalidation takes place immediately, but notes that in practice a propagation delay may exist where some servers know about the revocation and others do not.
A few details worth knowing:
- Revoking a refresh token should also revoke access tokens based on the same grant, where the server supports it.
- The server answers HTTP 200 both when it revoked the token and when the token was invalid, so callers cannot probe for valid tokens.
- Clients must not use a token after receiving a 200 response.
Four ways to handle it
| Approach | How it works | Trade off |
|---|---|---|
| Short lived access tokens | Expire in minutes, refresh to continue | Window of exposure equals the lifetime |
| Revoke the refresh token | Stops new access tokens being issued | Existing access token works until expiry |
| Denylist by jti | API checks a shared list of revoked token IDs | Adds a lookup, loses some statelessness |
| Opaque tokens with introspection | API asks the server on each use | Always current, adds a network call |
See token introspection vs local JWT validation for that last trade off in detail.
A practical design
- Keep access tokens short, such as 5 to 15 minutes. That range is a common practice, not a spec rule.
- Make refresh tokens revocable and rotating. RFC 9700 says refresh tokens for public clients must be sender constrained or use rotation.
- Revoke the refresh token on logout, password change and suspected theft.
- For high risk APIs, add a denylist keyed by
jtithat expires entries when the token would have expired anyway. That keeps the list small. - For the most sensitive actions, require a fresh authentication or introspect the token.
What to revoke, and when
- User logs out: revoke refresh token, end the session.
- Password or MFA change: revoke all refresh tokens for that user.
- Device lost: revoke grants for that client.
- Client compromised: revoke the client's grants and rotate its credentials.
- Employee leaves: disable the account and revoke grants centrally.
Test it
After revoking a refresh token, try to use it. It must fail. Then confirm how long the last access token keeps working, and write that number down. That number is your real revocation delay.
Quick check
Does logging out invalidate my JWT?
Not unless the API checks revocation. Without that, the access token keeps working until it expires.
Is a denylist the same as a session store?
Similar, but smaller. A denylist stores only revoked IDs until their natural expiry, rather than every active session.
Safeguard's SBOM and dependency scanning shows which token libraries you ship, which helps you review how each handles expiry and revocation hooks. A free scan is available.
Sources
Last reviewed: 19 October 2026.