diff --git a/docs/operations.md b/docs/operations.md index 32c0b2b..f889513 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -125,6 +125,37 @@ curl -s -H "Host: auth.coulomb.social" \ | jq -r .issuer ``` +## Unreleased fail-closed startup changes (read before the next rollout) + +The deployed image at the time of writing is +`sha256:7ff54c54e63ee172ae9e6e7fd2da96e427352f712343d74626ee6fe0f6f82611`, built +from `dcebd46`. Two changes on `main` postdate it, both affect startup or +issuance, and **both fail closed**, so they land together on the next rollout and +a mistake in either presents as a refusal rather than as a warning. + +**1. Browser clients reject service-identity fields (`74b35b6`, KEY-WP-0028).** +Config validation now rejects `serviceSubject` or `roles` on a client whose +grant is not `client_credentials`; those fields were silently ignored there, so a +registration could look effective and do nothing. This is a **startup** error: +a stray field in the deployed config stops the process from booting rather than +degrading. The live `sso/keycape-config` was checked on 2026-09-09 and none of +its three browser clients carries either field, so it passes as deployed — but +re-check if that config changed since. `tenant` is deliberately not rejected; +see below. + +**2. A conflicting tenant binding refuses issuance (`329e48f`, KEY-WP-0013-T05).** +A client registration may declare a `tenant`, which is supplied when the +directory has placed the user nowhere and enforced when it has. A declared zone +that **conflicts** with a directory assignment refuses the token with `403` and +`error_type: tenant_binding`. No deployed client declares a tenant on a browser +grant today, so nothing changes on rollout; the refusal only becomes reachable +once the approver client is registered. See +[the tenant contract](tenant-claim-contract.md). + +Neither has been exercised against a running issuer. The honest proof for both is +a live boot with the new binary, which belongs to the attended rollout window and +not to a session running against production on its own. + ## What is not claimed No resource-efficiency or throughput bounds are asserted here. Nothing in this