What you just saw
You're not signed in, so this is the explanation on its own, without anything from your own account - everything below still applies. Sign up to see it happen live instead of just reading about it.
Granting and revoking your assistant's access, and watching a caseworker's actions get checked against both a role and a live authorisation model, turns what's normally an invisible question - "did the AI have access, on whose authority, for how long?" - into something accountable: revocable in real time, and recorded in a machine-readable audit trail rather than inferred from a chat transcript.
We've written up the full explanation of what's actually happening here — FGA, on-behalf-of token exchange, and Auth0's Agent as Principal feature, end to end — on the blog.
RBAC decided which tools existed for your role before you ever typed anything. A citizen account never even sees contractor-management tools listed — they're not hidden or greyed out, they don't exist for that identity. This is the coarse, cheap-to-reason-about layer: a role check that runs once, at the boundary, before any specific resource is even in view.
Auth0 FGA decided, fresh on every single request, exactly what your assistant (a separate identity from you) was allowed to do. This is the layer RBAC alone can't do: RBAC answers "can this role use this tool at all," but not "is this specific assistant allowed to touch this specific case, right now." That's a relationship (ReBAC) — the assistant's delegated relationship to your case. FGA evaluates that relationship against live conditions: a 15-minute delegation window, a 30-day appeal window, a 5-minute step-up window — not a static permission that's either granted or not. A plain role could never expire on its own the way a condition can. That self-expiry is the whole reason the demo's delegation toggle is interesting instead of just being another checkbox.
Every one of those decisions is sitting in your access log, not reconstructed after the fact from a chat transcript — and the cross-service token exchanges you saw there (chatbot backend → MCP server → case service) use a fresh, narrowly-scoped token per hop instead of one shared credential, plus Auth0's Agent as Principal feature to record which real backend service actually proxied each request (the act claim), separate from and verifiable independently of whatever the assistant's own delegation state claims. Auth0 could have solved "an AI agent needs to act on a user's behalf" by inventing a custom header the backend just trusts — instead it's a real, cryptographically verifiable claim inside a standard OAuth token, which is why none of this had to be taken on faith.
For the technically curious, the actual code — none of what you just read is a simplification of what's really there: