The problem opaque token revocation for MCP actually solves
Here is the failure mode, in one line. You revoke an agent's access. The agent keeps working for another twenty minutes anyway. Not because anyone made a mistake. It's because the token it holds never has to ask. It never checks if it's still good.
A self-contained JWT carries its own claims. Subject, scopes, an expiry time, a signature. A resource server can check all of that offline. No network call back to an authorization server needed. That's the entire appeal of JWTs. It's also the entire problem. Once issued, a JWT stays valid until its exp claim says otherwise. Nothing about the token itself changes that. RFC 9700, the OAuth 2.0 security best current practice, is blunt about the tradeoff. Self-contained tokens are hard to revoke before they expire. Full stop.
Opaque token revocation for MCP, in the classic sense, is the other design. The token is a pointer. A random handle with no claims baked in. Each call checks it against live state. Revoke the handle, and the very next call fails. No matter what a clock no one is watching might say.
Keep that picture in mind for the rest of this post. It is not a format preference. It is the gap between two incidents. One ends in seconds. The other runs for the length of a coffee break.
Why MCP tool calls make this worse, not better
An MCP tool call is not a one-time login. It is a long-running session. It dispatches many calls to many tools. Often over minutes or hours. And often against systems that can do real damage per call. A database write, a file delete, a payment.
Stretch a JWT's lifetime across that whole session. You get the classic revocation gap. Mint a token with a two-hour expiry, so the agent doesn't keep logging in again. You have also made a promise, to an attacker or a misbehaving agent. Up to two hours of still-open access. That's if something goes wrong mid-session. Shrink the expiry to close that gap. Now you're back to logging in again every few minutes. That's its own day-to-day headache for a long agent run.
RFC 7009 sets a revocation endpoint, for just this reason. But that endpoint only helps if the resource server checks it. On each call. A JWT-only setup has no reason to make that call. The whole point of a JWT was to skip it.
This is why revocation keeps coming up in agent security threads. An MCP session is the long-lived, high-stakes case. One OAuth's own token design never had to solve well. A browser logout is a low-stakes event, compared to an autonomous agent mid-tool-call.
What DataShield Auth actually does, precisely
It would be easy to round this up. Into a marketing claim: "opaque tokens for MCP." That is not quite what ships. This post would rather be precise than punchy.
DataShield Auth issues MCP tool tokens as RFC 9068 JWTs, checked against a JWKS endpoint. It runs over the same kind of authorization flow the MCP specification itself expects. Like any other bearer token. What makes revocation instant is not that the token is opaque. It's that Auth does not stop at the JWT check. Each governed tool call runs a dispatch pipeline. Token scope ceiling, declared authority tier, then a mid-session revocation re-check. The pipeline meters and dispatches the call only after that. The re-check reads live session state. Not a claim baked into the token at mint time. Revoke or suspend an agent, and the pipeline downgrades its very next tool call mid-flight. Whatever the JWT's exp claim still says.
Think of it as opaque-token rules layered on top of a signed token. The JWT proves who is asking, and what scope it holds. The live re-check answers the only question that matters at call time. Whether that grant still holds right now.
The scope ceiling matters as much as the revocation clock
Instant revocation only closes half the gap. The other half is what happens between issuance and revocation. The token is still valid, and still doing its job.
A scope-ceiling token can never grant more access than its owner intended. That's enforced at dispatch. Not by convention, or a comment in a config file. A passed-down key inherits a ceiling, never more. That holds even for a global admin's own passed-down tokens. So the two controls work together. The ceiling bounds what a live, still-valid token can reach. On any single call. The mid-session re-check bounds how long a token keeps that reach. Once someone decides it shouldn't.
Without the ceiling, instant revocation still leaves a window. A token can reach further than it should. Right up until someone notices. Without the live re-check, the ceiling still leaks time. The token stays properly scoped. But a suspended agent keeps using its old scope until expiry. You need both. Building only one is how vendors end up with a bad revocation story. It sounds fine in a demo. Then it fails in a real incident.
How to verify this yourself
The dispatch pipeline runs five stages. Scope ceiling. Authority tier. Mid-session revocation re-check. Metered dispatch. A sealed audit entry. Each governed MCP tool call runs all five, every time. Not just at session start. Cedar handles the slower admin, platform, config, and token-management calls, with policy_explain attached. But it's not on the hot path for each tool dispatch. Auth's own documentation is specific about that split, on purpose.
The part worth checking yourself is the record left behind. Don't just trust a blog post. Each allowed and denied call lands in a SHA-256 hash-chained audit log. Ed25519-signed checkpoints back it up. So a revoked agent's denied calls are not just a design promise. Not just words. They are a row you can point to. Verify a sample chain yourself. Read the architecture page for the pipeline, stage by stage. See how it runs in code. Not as a diagram someone drew for a sales deck. That is the real test. Not whether the marketing page says it. Whether the log shows a denied call the instant after the revoke.
So someone asks: does MCP need opaque token revocation, or a signed JWT? The honest answer is that the question is a bit off. This is really about where the revocation check lives, not the token's format. A JWT no one re-checks behaves like an opaque token. One no one is willing to invalidate. Unrevocable, in effect. A JWT paired with a live re-check on each call gets you both. The fast offline check of a signed token. The kill switch of a pointer token, at the same time. That is the whole point of building the pipeline this way. Instead of picking one side of the tradeoff.
- Self-contained access tokens, such as JWTs, are hard to revoke or invalidate early. They live until they expire naturally. Issuers must weigh short lifetimes against the day-to-day cost of frequent re-authentication. - IETF, RFC 9700, OAuth 2.0 Security Best Current Practice
- OAuth 2.0 Token Revocation defines an endpoint. A client uses it to tell the authorization server a token is no longer needed. Then it can be invalidated. This only closes the gap if resource servers check revocation status. Servers can't just rely on the token's own claims. - IETF, RFC 7009, OAuth 2.0 Token Revocation
- The JWT Profile for OAuth 2.0 Access Tokens (RFC 9068) standardizes claims for self-contained bearer tokens. Resource servers can then validate them without a call back to the authorization server. That trades a revocation check for offline verification speed. - IETF, RFC 9068, JWT Profile for OAuth 2.0 Access Tokens
MCP catch-all scopes: why per-tool permissions matter
Why MCP servers default to one catch-all OAuth scope. The best-practice list for scoping tools one by one.
2026 AuthorizationPer-call vs per-session authorization for AI agents
One broad grant at login, versus authorizing every tool call against live policy. Why per-call shrinks blast radius.
2025 MCP SecurityMCP tool schema drift detection
Why a widened parameter is a widened permission. How to pin, diff, alert on, and refuse drifted tool schemas.
2026Scope-ceiling MCP tool tokens, with a mid-session revocation re-check on each governed call. A hash-chained audit log you can check yourself. Self-hosted on your own infrastructure.
Read the Auth architectureFrequently asked questions
What is opaque token revocation for MCP?
It treats an MCP tool token as a pointer. Each call checks it against live state. Not just claims baked in at mint time. The goal is instant revocation. A suspended agent loses access on its very next call. Not at token expiry.
Are DataShield Auth's MCP tool tokens opaque tokens or JWTs?
They are RFC 9068 JWTs, checked against a JWKS endpoint. What makes revocation instant is not that the token is opaque. Each governed call also runs a mid-session revocation re-check against live session state. That check runs on its own, apart from the JWT's own expiry claim.
Why can't a self-contained JWT be revoked immediately?
A resource server checks a JWT offline, from its own signed claims, including its expiry. Nothing about the token changes after it's issued. A resource server that trusts the JWT alone has no way to know the issuer revoked it early. Not unless it checks an outside source on each call.
Is a scope ceiling the same thing as revocation?
No. A scope ceiling bounds what a valid, still-live token can reach. On any single call. Mid-session revocation bounds how long a token keeps working. Once someone decides it should not. You need both. The ceiling limits the blast radius while a token is live. The re-check limits how long that window stays open.