AUTH4D-190 Unmatched management routes: 401, 404 and 405
AUTH4D-190 changes how the API answers a /management/* request that matches no registered route.
No route, contract or migration changes.
Behaviour
| Request | Status | error.code |
|---|---|---|
No Authorization: Bearer header |
401 | unauthorized |
| A bearer token that is malformed, expired, badly signed or for a revoked session | 401 | unauthorized |
| A valid control-plane token; the path exists under other methods | 405 | method_not_allowed |
| A valid control-plane token; no route has this path | 404 | not_found |
Before AUTH4D-190 every unmatched management route answered 401, even with a valid token. The
console BFF treats an upstream 401 as an expired session and signs the operator out, so a single
wrong-method call (for example GET on the PUT-only
/management/tenants/{tenantId}/users/{userId}/roles) ended the session.
The token check is the same one every management route uses: signature, issuer, audience, the console client, the live control-plane session and a verified, enabled user. No particular scope is needed to get a 404 or 405, so these answers reveal only which routes exist, never project data. Callers without a valid token still learn nothing beyond 401.
A 405 carries Allow with the methods registered for the path, comma-separated (for example
Allow: PUT). The console BFF passes Allow through to the browser.
All three answers use the management error envelope and the boundary’s Cache-Control: no-store:
{
"error": {
"code": "method_not_allowed",
"message": "The request method is not allowed for this endpoint.",
"request_id": "req_…"
}
}
The 404 message is “The requested endpoint was not found.” The boundary checks run first, so a write to an unknown path with a body that is not JSON still gets 415, and a request without a bearer header still gets 401 before routing.
Tests
tests/integration/auth4d-190.management-not-found.test.ts drives the real API composition: 405
with Allow: PUT for GET …/users/{userId}/roles, 404 for an unknown path with several methods,
the same with a token holding a single scope, and 401 for a missing, malformed, tampered or
revoked-session token. Its BFF half shows that a proxied 404 or 405 leaves the console session in
place (no revokeAndClear, no cleared cookie) while a 401 still ends it.
Source: docs/api-spec/auth4d-190.md