docs(security): pin privacyidea resolver reconciliation
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
This commit is contained in:
tegwick 2026-08-23 15:05:18 +02:00
parent dc21d246e4
commit eec7007c21
2 changed files with 102 additions and 1 deletions

View file

@ -0,0 +1,100 @@
# KeyCape exposure: privacyIDEA resolver reconciliation
Incident: `KEYCAPE-EXPOSURE-20260823-01`
Workplan: `NK-WP-0033`
NetKingdom procedure revision: `f2e578c`
Platform recovery contract: railiance-platform `453fed3`
Owner cutover receipt: State Hub message `45b236c8-052f-43d3-a472-44f8e9694da2`
This is the remaining attended provider-admin operation after the owner-reported
four-class cutover. It updates only privacyIDEA resolver `lldap-coulomb` so the
resolver uses the replacement LLDAP bind credential. It does not modify realms,
policies, tokens, KeyCape Secrets, or any other resolver.
No password, hash, token, Secret payload, or manifest belongs in this document,
State Hub, Git, chat, command arguments, or ordinary logs.
## Authority and pinning gate
The operator must record a private approval receipt containing, at minimum:
- incident `KEYCAPE-EXPOSURE-20260823-01`;
- NetKingdom revision `f2e578c` and platform contract `453fed3`;
- the owner receipt `45b236c8-052f-43d3-a472-44f8e9694da2`;
- the exact start/end window, attended driver, and independent abort operator;
- confirmation that the replacement LLDAP credential is the provider-approved
value and that no exposed predecessor will be restored.
No live action is permitted if any revision, owner, cluster, or approval
identifier differs from the receipt.
## Preflight (metadata and health only)
Run from the approved operator workstation, with the cluster context and
provider endpoint already authorized. Do not render any Secret data.
1. Verify the checked-out revision is exactly `f2e578c` and the helper has mode
`0755`; inspect its source, not live credential material.
2. Confirm LLDAP, privacyIDEA, KeyCape, Authelia, and
identity-provisioner are Ready using deployment/pod status fields only.
3. Confirm privacyIDEA and KeyCape health endpoints return an HTTP success
status, discarding response bodies. Do not use a command that prints a
bearer token or configuration response.
4. Confirm the approved window, driver, abort operator, provider custody, and
cleanup workspace are ready. Stop on any drift or missing owner.
## Apply (one attended operation)
1. Create one private mode-`0700` workspace with a cleanup trap. Keep the
pi-admin password and replacement LLDAP bind password in separate
mode-`0600` files or supply them only through the helper's hidden prompts.
2. From the pinned checkout, run exactly:
```text
bash sso-mfa/k8s/privacyidea/update-lldap-resolver-live.sh --apply
```
The helper prompts for both passwords, authenticates to privacyIDEA, and
performs one `POST /resolver/lldap-coulomb`. It passes only protected file
paths to its child process, never prints values, and prints only a boolean
result. It must not be combined with `repair-realm-live.sh`,
`bootstrap-realm.sh`, `creds-rotate.sh`, or any full-bundle generator.
3. Stop immediately on any non-success response, timeout, unexpected endpoint,
or output that is not the documented boolean result. Do not restore the
exposed bundle or predecessor credential.
## Postflight and predecessor denial
Record only status codes, readiness, timestamps, revision identifiers, and
boolean results.
1. Confirm privacyIDEA, LLDAP, KeyCape, Authelia, and identity-provisioner are
Ready again. Confirm the privacyIDEA health endpoint succeeds and the
resolver endpoint returns success without retaining its response body.
2. Exercise one approved KeyCape MFA path that requires the `coulomb` realm.
Record pass/fail only; never record the token or response body.
3. Using protected file inputs, prove an LDAP bind with the replacement value
succeeds and a bind with the exposed predecessor fails. The predecessor
test must be a boolean result and must not put the password in argv or
stdout. A failed predecessor bind is required evidence; do not retry it
against another provider.
4. Confirm the KeyCape owners existing four-class positive/negative receipt
remains associated with this resolver update. If any class lacks a receipt,
keep T05 open.
5. Securely remove the temporary workspace and record only cleanup success.
## Abort and rollback
Abort before mutation on revision drift, missing authority, unavailable health,
uncertain workspace cleanup, or any unsafe helper output. Abort forward after
mutation on a failed resolver response, failed readiness, failed replacement
MFA, or missing predecessor denial. The exposed bundle and every exposed
predecessor are never rollback material. Recovery after a partial write must
use a newly approved replacement value and revision, not a stale local bundle.
## Completion evidence
T03 may move to done only after the helper run and cleanup receipt are recorded
by the attended operator. T05 may move to done only after the resolvers
replacement success, predecessor denial, owner cutover receipt, and all
residual limitations are recorded as sanitized evidence.

View file

@ -121,7 +121,8 @@ NetKingdom also added the unattended-safe shape of the remaining provider
operation in `sso-mfa/k8s/privacyidea/update-lldap-resolver-live.sh`. It is operation in `sso-mfa/k8s/privacyidea/update-lldap-resolver-live.sh`. It is
explicitly gated by `--apply`, requires an interactive terminal, uses protected explicitly gated by `--apply`, requires an interactive terminal, uses protected
0600 files, updates only `lldap-coulomb`, and emits no credential values. It 0600 files, updates only `lldap-coulomb`, and emits no credential values. It
has not been run; attended provider-admin reconciliation remains pending. has not been run; the exact attended runbook is pinned in
`docs/keycape-exposure-resolver-reconciliation.md`.
Do not use `sso-mfa/bootstrap/creds-rotate.sh` through an agent as currently Do not use `sso-mfa/bootstrap/creds-rotate.sh` through an agent as currently
written: it prints generated replacement values and its signing-key path written: it prints generated replacement values and its signing-key path