net-kingdom/docs/keycape-upstream-issuer-pin.md
tegwick 896c1200c0
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Record exercised live issuer pin and unchanged production deployment
Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-09 00:40:23 +02:00

60 lines
3.5 KiB
Markdown

# Pin KeyCape's verified upstream issuer
Exercise status: read-only check and guarded live write exercised 2026-09-09 by codex under user continuation authorization.
Owner implementation: `sso-mfa/k8s/keycape/openbao-client-config.py`.
Dependency: KEY-WP-0013-T02 / HFACT-WP-0001-T03. The actual signed upstream
issuer was verified as `https://auth.coulomb.social` at 2026-09-08T21:44:44Z;
KeyCape retains that signed-token receipt. This procedure ensures its exact
`authelia.issuer` configuration pin before the separately reviewed client rollout.
The existing `patch` mode also reconciles client registrations and LLDAP defaults.
Use the dedicated issuer modes for this operation. They read the live Secret in
captured process memory and emit only metadata and fixed result fields. They do
not print the configuration, private key, prior field value or Kubernetes errors.
No Secret backup or patch is written to disk. The patch travels only through
child stdin, never command arguments. The current Kubernetes owner context is
used; no credential is fetched through a generic or unrelated Warden route.
```bash
python3 -B sso-mfa/k8s/keycape/openbao-client-config.py issuer-check-live
python3 -B sso-mfa/k8s/keycape/openbao-client-config.py issuer-pin-live \
--expected-uid <uid-from-check> \
--expected-resource-version <resource-version-from-check>
```
The target is fixed to `sso/keycape-config`; the issuer is fixed to the verified
HTTPS value. The write requires both the observed UID and resourceVersion and
tests them atomically in a JSON patch. A matching pin is a no-op. A concurrent
change refuses the write instead of replaying stale configuration. Duplicate
mapping keys, aliases, anchors and unsupported YAML shapes fail closed.
The mutation inserts or replaces only the issuer scalar. Every other configuration
byte is preserved, and readback compares every Secret data entry, including the
existing private key, without publishing hashes or values. API or parser failures
return fixed reason codes. A readback mismatch stops without another write;
the owner must reconcile the current revision before retrying. There is no
automatic rollback that could overwrite a concurrent credential rotation.
This step changes no Deployment, process, client registration, credential or
custody policy. The existing process is not restarted. Its separate compatible
image/configuration cutover must still prove readiness and existing human login,
and must retain its owner-controlled rollback pair. Do not call this stored
configuration check proof that the current process has reloaded the field.
The CCR-2026-0017/0018 named reviews and attended custody window remain separate
gates. This field pin does not approve either request.
Validation: `python3 -B -m unittest discover -s sso-mfa/k8s/keycape -p 'test_*.py' -v`
passes 13 tests, covering byte preservation, duplicate/alias rejection, stale
revision refusal, atomic preconditions, readback conflict and secret-free failure
output. The first live check on 2026-09-09 found the pin absent at resourceVersion
`51346058`, UID `2e94519d-1550-41c7-9701-2efe47fe1fd3`.
Live result: the guarded write at 2026-09-08T22:23:58Z (00:23:58 Berlin on
September 9) inserted the missing issuer, advancing the Secret resourceVersion
from `51346058` to `58713343`. Independent check returned `issuer_matches=true`;
all other configuration bytes and Secret data entries were unchanged. The
Deployment stayed at generation 29 with one ready/available replica.
[Receipt](evidence/2026-09-09-keycape-upstream-issuer-pin.json).