Why You Can't Revoke Stateless Access Tokens

Access tokens are stateless and verified cryptographically, meaning they cannot be revoked before they expire without complex workarounds. To secure your system, use short-lived access tokens (valid for minutes) paired with a revokable, database-backed refresh token to balance performance with immediate security control.
A colleague of mine recently encountered a classic architectural headache. A developer left their startup, and the CTO asked to have the former employee's system access revoked immediately. The problem? The team had designed their auth system using standalone, long-lived access tokens with a lifespan of several months.
My colleague had to deliver the bad news: it was impossible to instantly revoke the token. Because of that design choice, the ex-employee retained access to the APIs for months.
I want to break down why this architectural trap happens, how stateless authentication works under the hood, and how you can avoid this scenario entirely.
How do access tokens actually work?
Access tokens act as self-contained, stateless passes that allow clients to access resources without constantly querying a central database. The receiving server validates the token solely by verifying its cryptographic signature and checking the expiration claim. If the signature is valid and the token has not expired, access is granted.
Think of an access token like a movie ticket. When you buy a ticket, the theater prints the movie name, date, and showtime on it, and signs it with a unique watermark. When you walk up to the screen, the ticket-taker does not call the front desk or query a database to see if you are still allowed in. They look at the ticket, verify the watermark, check the date, and let you pass.
In a web architecture, your API acts as that ticket-taker. It verifies the JSON Web Token (JWT) signature using a public key. If the signature matches and the exp timestamp is in the future, the API fulfills the request. No database lookups, no external network calls, and incredibly fast response times.
Why can't you easily revoke a long-lived access token?
You cannot easily revoke an access token because the resource server operates under a stateless validation model. It has no built-in mechanism to check if a user was recently deactivated; it only trusts the token's unexpired signature. If you issue an access token that lasts for months, that token remains an open key until its timer runs out.
If you want to invalidate a token early, you have to break the stateless rule. You would need to build a blocklist database of revoked tokens that your API queries on every single request.
Doing this means you lose the scaling benefits of stateless JWTs. You are back to making database or Redis calls on every incoming API request, defeating the entire purpose of using self-contained tokens in the first place.
How do you implement secure token revocation?
Secure revocation is achieved by splitting auth duties between short-lived access tokens and longer-lived refresh tokens. The resource server quickly validates the short-lived token, while the identity provider manages the stateful refresh token, allowing you to revoke the refresh token and block new access token generation instantly.
In this pattern, the access token is only valid for a tiny window—say, 15 minutes. When it expires, the client app sends the refresh token to your authentication server. The authentication server performs a stateful check against your database.
If the user is still active, the server issues a brand-new 15-minute access token. If the employee has been terminated, you simply delete the refresh token from your database. The next time the client tries to renew their access, the request is rejected, and they are locked out within minutes.
| Feature | Access Token | Refresh Token |
|---|---|---|
| Lifespan | Short-lived (e.g., 15 minutes) | Long-lived (e.g., 30 days) |
| Verification | Stateless (cryptographic signature check) | Stateful (database or cache lookup) |
| Primary Storage | Memory or short-term client storage | Secure, HTTP-only cookies |
| Revocability | Hard (requires a complex blacklist) | Easy (delete the database record) |
FAQ
Can you block access tokens using a token blacklist?
Yes, but it introduces state back into your stateless architecture. You would need to store revoked token IDs in a fast-access cache like Redis and check this cache on every API request, which partially defeats the performance benefit of using stateless tokens.
What is the ideal lifespan for an access token?
For most web applications, an access token lifespan of 5 to 15 minutes offers the best balance between security and performance. This limits the window of exposure if a token is intercepted, without overloading your authentication server with refresh requests.
What happens to active access tokens when a user logs out?
When a user logs out, the client application should discard the access token from its local memory. Simultaneously, your application must call your backend auth server to delete the corresponding refresh token, ensuring no new access tokens can be requested.



