Updating scopes or routes
The middleware loadsmudraid_scopes.yaml once, on the first request, and holds it in memory.
To pick up changes: redeploy, or restart the process. There is no hot-reload in v1. The single-source-of-truth contract is easier to reason about with a restart in the middle.
MudraID key rotation
When MudraID rotates its signing key, the middleware:- Receives a token signed under a new
kid. - Looks up the
kidin its cached JWKS. Not found. - Refetches the JWKS. One in-flight refresh under contention.
- Verifies against the new key. Success.
JWKS endpoint unreachable
Affected requests get500 JWKS_UNAVAILABLE, logged at WARNING.
The cache is not invalidated on a failed fetch. A transient blip doesn’t take down every cached key.
Misconfigured YAML
The middleware loads the YAML lazily on the first request. A schema error returns500 MIDDLEWARE_NOT_READY, logged at ERROR.
The failure is not cached. Fix the YAML and the next request succeeds. No restart needed for that case.
V2 mode: is enforcement actually active?
In V2 mode the portal’s adapter row is the check.HttpDecideClient posts a heartbeat before each bundle fetch, an acknowledgement when a bundle activates, and a first-observed-decision fact on its first /decide call. After start() verifies a bundle the row should show the published version as active; after the first protected tools/call, decision observed. A row that never gets there means no bundle activated — look for bundle REFUSED in the logs. Until a bundle verifies, protected paths answer 503 ENFORCE_NO_VALID_BUNDLE.

