Add contained issuer-only configuration check and revision-guarded pin
Assistant: codex Assistant-Model: gpt-5.6-luna Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
46455439cf
commit
ad9979b159
3 changed files with 305 additions and 1 deletions
52
docs/keycape-upstream-issuer-pin.md
Normal file
52
docs/keycape-upstream-issuer-pin.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Pin KeyCape's verified upstream issuer
|
||||
|
||||
Exercise status: read-only check exercised 2026-09-09 by codex; guarded write unexercised.
|
||||
|
||||
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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue