Before you start
- A MudraID account, with your platform registered (step 1 below).
- A FastAPI or Starlette application.
- Python 3.10 or newer.
1. Register your platform
Sign in to the MudraID portal, create a platform, and verify you own its domain (a DNS TXT record). Then define the scopes your routes will require — the permissions you’ll hand out to agents, likeitems:read and items:write.
You’ll get a platform_id, which identifies your platform in the scopes file, and a canonical resource URI. Agents request access tokens for that resource URI, and it becomes the tokens’ audience.
2. Get your scopes file
The portal generates amudraid_scopes.yaml for your platform. It maps each route to one of three outcomes: a required scope, an open public route, or a hidden skip route.
3. Install the middleware
4. Configure verification and add the middleware
Three values tell the middleware which tokens to accept:MUDRAID_JWKS_URL— required, no default. The/.well-known/jwks.jsonpath on the MudraID environment your platform is registered with; the portal prints it on the credential screen.MUDRAID_EXPECTED_ISSUERS— theissueryour environment’s authorization server advertises at/.well-known/oauth-authorization-server. Agents’ access tokens carry it asiss.expected_audience— your platform’s canonical resource URI. Agents’ access tokens carry it asaud.
MUDRAID_JWKS_URL nor jwks_url= set, the middleware raises ValueError when the ASGI stack is built. It will not boot unconfigured.
Without
expected_audience, the middleware expects aud to equal the platform_id in your YAML, and without an issuer setting it expects the legacy issuer mudraid-identity. Those were the claims of native agent tokens, which are retired. Agents’ OAuth access tokens carry the authorization server’s issuer and your resource URI, so set both values above or every agent call fails with WRONG_ISSUER or WRONG_AUDIENCE.5. Verify the integration before trusting it
Do this before you conclude anything is protected.curl a scope-gated route with no Authorization header:
What just happened
For every incoming request, the middleware now:- Matches the method and path against your YAML.
- Lets public routes through untouched.
- Reads the
Authorization: Bearertoken. - Verifies its signature, issuer, audience, and timing against MudraID’s published keys — local verification, no per-request callback.
- Checks the route’s required scope is present in the token.
- Forwards to your handler, or returns a structured
{"error_code", "message"}error.
Troubleshooting
Full table: Interpret verification error codes.
Going further: live enforcement
Offline verification checks the token and the route’s scope. To have MudraID decide each sensitive action against current authority, containment and policy, register an enforcement adapter and use the middleware’s V2 mode (MCP Streamable HTTP servers) — see V2 mode.Next steps
Define scopes
Design the permissions your API exposes.
Manage the scopes lifecycle
How changes roll out safely.
Error responses
The stable error_code contract.
Survive key rotation
Why rotation needs no action from you.

