Registry API Authentication FAQ¶
Common questions about authenticating against the Registry API (/api/*, /v0.1/*). For the full authentication model, see Registry API Authentication.
Can I use an IdP token and the static token on the same deployment?¶
Yes, as of #871. When REGISTRY_STATIC_TOKEN_AUTH_ENABLED=true, the static token is accepted as an additional credential, not an exclusive gate. Valid Okta / Entra / Cognito / Keycloak JWTs, UI-issued self-signed JWTs, and session cookies all continue to work on /api/*. A bearer that doesn't match the static token falls through to the JWT validation pipeline.
Before #871, turning on static-token mode silently broke every non-static-token caller on /api/* with a 401/403 before JWT validation ran.
Do I need to seed MongoDB with mcp-servers-unrestricted/* scope docs for the static token to work?¶
After #779: Yes, the standard scope-resolution path is used for all static-token keys (including the legacy REGISTRY_API_TOKEN). The auth server resolves each key's groups to scopes via group_mappings in MongoDB. If the group-to-scope mappings are missing, the key will authenticate but carry an empty scope set, which means the registry will treat it as a non-admin caller.
Before #779: No. The registry hard-coded full admin access when the auth server set X-Auth-Method == "network-trusted". Scopes returned in the /validate response were informational only.
Can I give a static token read-only access?¶
Yes, since #779. Define a key in REGISTRY_API_KEYS whose groups list maps to read-only scopes (e.g., mcp-servers-unrestricted/read). The key will authenticate successfully but will not carry mutating scopes, so the registry treats it as a non-admin caller.
Make sure the group mcp-readonly is mapped to the desired read-only scopes in your group_mappings collection.
Why does the static token not work on /<server>/tools/list?¶
By design. The static token is only accepted on Registry API paths (/api/*, /v0.1/*). MCP gateway tool invocations always require full IdP authentication regardless of static-token settings. This is a deliberate boundary, not a bug: the static token grants admin-level access on registry metadata endpoints, but tool invocations — which can have real-world side effects — stay gated behind per-user identity and scopes from the IdP.
A curl with -H "Authorization: Bearer $REGISTRY_API_TOKEN" against an MCP gateway path will currently return a 500 wrapping the JWT validation failure. That's a pre-existing error-code bug (separate from #871), not a sign the call should have succeeded.
What status code does a fully invalid bearer get?¶
Since #871: 401 from the JWT block (detail: "Missing or invalid Authorization header. Expected: Bearer <token> or valid session cookie").
Before #871: 403 from the static-token block (detail: "Invalid API token").
No caller with a valid credential is affected by this change. The status-code shift only applies to bearers that were going to be rejected anyway.
Is my UI-issued JWT usable against /api/*?¶
Yes, since #871. Before the fix, the Get JWT Token sidebar in the UI produced valid HS256 JWTs that were nonetheless rejected on /api/* when static-token mode was on. After #871 they flow through the same _validate_self_signed_token path as any other UI-issued token, regardless of whether static-token mode is on.
How do I rotate a static token without downtime?¶
With REGISTRY_API_KEYS (recommended): Zero-downtime rotation is straightforward:
- Add a new key entry to the JSON array (the old key stays).
- Deploy the updated config. Both keys are now valid.
- Migrate clients to the new key at your own pace.
- Remove the old key entry and redeploy.
With legacy REGISTRY_API_TOKEN only: There is still a cutover window during which old clients are rejected while new clients have yet to pick up the new value. Mitigations:
- Roll out the new token value to clients first, then flip the server value.
- Or accept a brief 401/403 window and notify callers.
- Or migrate to
REGISTRY_API_KEYSfor zero-downtime rotation.
Where do I see the current values in the UI?¶
The Settings → Authentication page shows:
| Field | Label | Behavior |
|---|---|---|
registry_static_token_auth_enabled | Static Token Auth Enabled | Displayed as true / false |
registry_api_token | Registry API Token | Masked |
registry_api_keys | Registry API Keys | Masked |
m2m_direct_registration_enabled | M2M Direct Registration Enabled | Displayed as true / false (from #851) |
The field registry is defined in registry/api/config_routes.py.
What's the roadmap?¶
Three improvements, landing in order on top of each other:
- #871 — coexistence (shipped): static token and JWT auth work together on
/api/*. - #779 — multi-key static tokens (shipped): replaces the single
REGISTRY_API_TOKENwith aREGISTRY_API_KEYSJSON object, each key carrying its own groups. Lets operators give scripts the minimum privilege they need. Zero-downtime rotation is built in. - #826 — external user access tokens: lets a frontend application that has its own IdP integration call the Registry API on behalf of a logged-in user, either via
/userinfogroup enrichment (Solution A) or a new token-exchange endpoint (Solution B).
See the full design in Registry API Authentication.