From 5ae80d341f201e32a58ca44504742fcc698844e8 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 9 Sep 2026 16:41:38 +0200 Subject: [PATCH] Record the two unreleased fail-closed startup changes for the rollout Both changes on main that postdate the deployed image affect startup or issuance and both fail closed, so a mistake in either presents as a refusal rather than a warning. That fact currently lives only in a State Hub message to the deployment owner; messages age out of attention, and the repo is what the next session reads, so operations.md is where it belongs. Records what was actually checked rather than what is assumed: the deployed image digest and the commit it was built from, that the live config's three browser clients carry neither newly-rejected field, and that no deployed client declares a tenant on a browser grant so the refusal is not yet reachable. Also states plainly that neither change has been exercised against a running issuer, and that the proof belongs to the attended window rather than to a session running against production on its own. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016uV8zoCKpA1WRAxsKRYbdH Assistant: claude-code Assistant-Model: opus Assistant-Process: 1182213@bnt-lap001 Assistant-Session: 966597b9-ae61-46a4-8b9e-1594ab3ec4ad --- docs/operations.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) 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