The problem opaque token revocation for MCP actually solves
Here is the failure mode in one sentence: you revoke an agent's access, and the agent keeps working for another twenty minutes anyway. Not because anyone made a mistake, but because the token it holds does not need to ask anyone whether it is still good.
A self-contained JWT carries its own claims: subject, scopes, an expiry time, a signature. A resource server can verify all of that offline, with no network call back to an authorization server. That is the entire appeal of JWTs, and it is also the entire problem. Once issued, a JWT is valid until its exp claim says otherwise, and 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 reference, a random handle with no embedded claims, and every call checks it against live state. Revoke the handle and the very next call fails, regardless of an expiry clock nobody is watching.
Keep that picture in mind for the rest of this post: it is not a format preference, it is the difference between a security incident that ends in seconds and one that 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 that dispatches many separate calls to many separate 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 and you get the classic revocation gap. Mint a token with a two-hour expiry so the agent does not keep re-authenticating, and you have also promised an attacker, or a misbehaving agent, up to two hours of unrevoked access if something goes wrong mid-session. Shrink the expiry to close that gap and you are back to re-authenticating every few minutes, which is its own operational headache for a long agent run.
RFC 7009 defines a revocation endpoint for exactly this reason, but a revocation endpoint only helps if the resource server actually checks it on every call. A JWT-only architecture has no reason to make that call: the whole point of a JWT was to avoid it.
This is exactly why the revocation problem keeps coming up in agent security threads: an MCP session is the long-lived, high-stakes case OAuth's original token design never had to solve well, because a browser session logging out 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, and this post would rather be precise than punchy.
DataShield Auth issues MCP tool tokens as RFC 9068 JWTs, checked against a JWKS endpoint, over the same kind of authorization flow the MCP specification itself expects, like any other bearer token. What makes revocation immediate is not that the token is opaque. It is that Auth does not stop at the JWT check. Every governed tool call runs a dispatch pipeline: token scope ceiling, declared authority tier, and then a mid-session revocation re-check, before the call is metered and dispatched. That re-check reads live session state, not a claim baked into the token at mint time. Revoke or suspend an agent, and its very next tool call is downgraded mid-flight, whatever the JWT's exp claim still says.
Think of it as opaque-token semantics layered on top of a signed token. The JWT proves who is asking and what scope they were issued. The live re-check answers the only question that actually matters at call time: whether that grant still holds right now.
The scope ceiling matters as much as the revocation clock
Immediate revocation only closes half the gap. The other half is what happens between issuance and revocation, while the token is still valid and doing its job.
A scope-ceiling token can never grant more access than its owner intended, enforced at dispatch, not by convention or a comment in a config file. A delegated key inherits a ceiling, never more, and that holds even for a global admin's own delegated tokens. So the two controls work together: the ceiling bounds what a live, unrevoked token can reach on any single call, and the mid-session re-check bounds how long a token keeps that reach once somebody decides it shouldn't.
Without the ceiling, immediate revocation still leaves a window where 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 is properly scoped, but a suspended agent keeps using its old scope until expiry. You need both, and building only one is how vendors end up with a revocation story that sounds fine in a demo and fails in an incident.
How to verify this yourself
The dispatch pipeline is: scope ceiling, then authority tier, then mid-session revocation re-check, then metered dispatch, then a sealed audit entry. Every governed MCP tool call runs all five stages, every time, not just at session start. Cedar handles the slower admin, platform, config and token-management decisions with policy_explain attached, but it is not on the hot path for every tool dispatch, and Auth's own documentation is deliberately specific about that split.
The part worth checking yourself, rather than trusting a blog post, is the record left behind. Every allowed and denied call lands in a SHA-256 hash-chained audit log with Ed25519-signed checkpoints, so a revoked agent's denied calls after the fact are not just a design promise, they are a row you can point to. Verify a sample chain yourself, and read the architecture page for the pipeline stage by stage, as it runs in code rather than as a diagram someone drew for a sales deck. That is the actual test: not whether the marketing page says it, but whether the log shows a denied call the instant after the revoke.
So when someone asks whether MCP needs opaque token revocation or a signed JWT, the honest answer is that the question is slightly wrong. This is really about where the revocation check lives, not about the token's format. A JWT that never gets re-checked behaves exactly like an unrevocable opaque token nobody is willing to invalidate. A JWT paired with a live re-check on every call gets you the fast offline verification of a signed token and the kill switch of a reference token, at the same time. That is the entire point of building the pipeline this way instead of picking one side of the tradeoff.
- Self-contained access tokens such as JWTs are inherently difficult to revoke or invalidate prior to their natural expiration, and issuers must weigh short lifetimes against the operational cost of frequent re-authentication. - IETF, RFC 9700, OAuth 2.0 Security Best Current Practice
- OAuth 2.0 Token Revocation defines an endpoint that lets a client notify the authorization server that a previously obtained token is no longer needed, so it can be invalidated, but this only closes the gap if resource servers check revocation status rather than relying solely 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 so resource servers can validate them without a call back to the authorization server, trading 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, and 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, and why per-call shrinks blast radius.
2025 MCP SecurityMCP tool schema drift detection
Why a widened parameter is a widened permission, and how to pin, diff, alert on, and refuse drifted tool schemas.
2026Scope-ceiling MCP tool tokens with a mid-session revocation re-check on every governed call, and a hash-chained audit log you can verify yourself, self-hosted on your infrastructure.
Read the Auth architectureFrequently asked questions
What is opaque token revocation for MCP?
It is the practice of treating an MCP tool token as a reference that gets checked against live authorization state on every call, rather than trusting only the claims baked into a self-contained token at mint time. The goal is immediate revocation, so a suspended agent loses access on its very next call instead of 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 immediate is not that the token is opaque, it is that every governed call also runs a mid-session revocation re-check against live session state, independent of the JWT's own expiry claim.
Why can't a self-contained JWT be revoked immediately?
A JWT is validated offline from its own signed claims, including its expiry. Nothing about the token changes after it is issued. A resource server that trusts the JWT alone has no way to learn that the issuing authority revoked it early, short of checking a separate revocation source on every call.
Is a scope ceiling the same thing as revocation?
No. A scope ceiling bounds what a valid, unrevoked 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, and the re-check limits how long that window stays open.