diff --git a/credential-change-requests/CCR-2026-0054-net-kingdom-keycape-bind.yaml b/credential-change-requests/CCR-2026-0054-net-kingdom-keycape-bind.yaml index ef38479..97c52f2 100644 --- a/credential-change-requests/CCR-2026-0054-net-kingdom-keycape-bind.yaml +++ b/credential-change-requests/CCR-2026-0054-net-kingdom-keycape-bind.yaml @@ -3,30 +3,46 @@ kind: credential-change-request schema_version: 1 request_type: workload-kv-read title: NetKingdom KeyCape directory bind (svc-keycape) delivery -status: proposed +status: approved created: '2026-10-31' updated: '2026-10-31' requester: agent: claude-code reason: 'NK-WP-0056-T04, third lane (after CCR-2026-0052 svc-provisioner and CCR-2026-0053 - svc-authelia): move the svc-keycape LLDAP bind out of the founder''s personal SOPS custody - into platform custody. KeyCape reads it from KEYCAPE_LLDAP_BIND_PW (key-cape KEY-WP-0046), - so ESO owns a dedicated Secret instead of one field inside keycape-config.' + svc-authelia): move the svc-keycape LLDAP bind out of the founder''s personal + SOPS custody into platform custody. KeyCape reads it from KEYCAPE_LLDAP_BIND_PW + (key-cape KEY-WP-0046), so ESO owns a dedicated Secret instead of one field inside + keycape-config.' review: required: true required_approvers: - platform-owner - net-kingdom-owner - comments: [] + comments: + - at: '2026-10-31T09:36:13+00:00' + reviewer: platform-owner + decision: approved + comment: 'Approved as proposed: read-only svc-keycape lane, CAS=0 from live value, + ESO-owned dedicated Secret keycape-lldap-bind.' + - at: '2026-10-31T09:36:25+00:00' + reviewer: net-kingdom-owner + decision: approved + comment: Approved as proposed for NK-WP-0056-T04, including the KeyCape image + main-e2b5fa1. + - at: '2026-10-31T09:36:35+00:00' + reviewer: platform-owner + decision: binding_confirmed + comment: 'Binding confirmed: ServiceAccount net-kingdom-svc-keycape-bind-eso in + namespace sso only, audience openbao, as declared in net-kingdom sso-mfa/k8s/keycape/bind-eso.yaml.' target: domain: infotech tenant: platform workload: net-kingdom-keycape environment: production - purpose: Hold the svc-keycape LLDAP bind password in platform custody and deliver it as - the dedicated Secret sso/keycape-lldap-bind (key password), read by KeyCape as KEYCAPE_LLDAP_BIND_PW; - no signing key, client or other keycape-config value, no ld-admin, admin or other service - bind + purpose: Hold the svc-keycape LLDAP bind password in platform custody and deliver + it as the dedicated Secret sso/keycape-lldap-bind (key password), read by KeyCape + as KEYCAPE_LLDAP_BIND_PW; no signing key, client or other keycape-config value, + no ld-admin, admin or other service bind openbao: mount: platform kv_path: platform/workloads/net-kingdom/directory-binds/svc-keycape @@ -52,22 +68,23 @@ openbao: - net-kingdom-svc-keycape-bind-eso service_account_namespaces: - sso - bound_claims_confirmed: false + bound_claims_confirmed: true access_frontdoor: type: platform-owner catalog_id: net-kingdom-svc-keycape-bind readiness: pending-review resolvable: false lifecycle: - deactivate: Restore bindPW in keycape-config (directory-bind-rollout.py --operation switch), - remove the KEYCAPE_LLDAP_BIND_PW env from the Deployment, then delete the ExternalSecret - (deletionPolicy Retain keeps the Secret) and withdraw the role and policy. - rotate: Change the svc-keycape password in LLDAP and write the new value as the next KV - version with CAS on the current version; ESO projects it and KeyCape is restarted. Only - after bindPW is cleared from keycape-config, because KeyCape refuses differing values. - Until NK-WP-0056 executors exist this is founder-run. - compromised: Reset svc-keycape in LLDAP first (read-only bind, lldap_strict_readonly), then - rotate as above; fence the reader role if its boundary is in doubt. + deactivate: Restore bindPW in keycape-config (directory-bind-rollout.py --operation + switch), remove the KEYCAPE_LLDAP_BIND_PW env from the Deployment, then delete + the ExternalSecret (deletionPolicy Retain keeps the Secret) and withdraw the role + and policy. + rotate: Change the svc-keycape password in LLDAP and write the new value as the + next KV version with CAS on the current version; ESO projects it and KeyCape is + restarted. Only after bindPW is cleared from keycape-config, because KeyCape refuses + differing values. Until NK-WP-0056 executors exist this is founder-run. + compromised: Reset svc-keycape in LLDAP first (read-only bind, lldap_strict_readonly), + then rotate as above; fence the reader role if its boundary is in doubt. delivery: surface: ESO-owned Secret (creationPolicy Owner, new dedicated Secret) namespace: sso @@ -81,37 +98,40 @@ delivery: risk: classification: medium notes: - - svc-keycape is a read-only directory bind (lldap_strict_readonly); a leak exposes directory - attributes (users, groups, emails), not write access. - - keycape-config also holds the signing key and client configuration; this request delivers - none of it, and setup compares only lldap.bindDN/bindPW in memory. - - Initial KV write is CAS=0 with the value already live in keycape-config and the founder's - custody; no rotation happens in this request. An existing different KV value refuses. - - Setup refuses unless the live config binds uid=svc-keycape. KeyCape refuses to start if - KEYCAPE_LLDAP_BIND_PW and bindPW differ, so a wrong delivery cannot be used silently. + - svc-keycape is a read-only directory bind (lldap_strict_readonly); a leak exposes + directory attributes (users, groups, emails), not write access. + - keycape-config also holds the signing key and client configuration; this request + delivers none of it, and setup compares only lldap.bindDN/bindPW in memory. + - Initial KV write is CAS=0 with the value already live in keycape-config and the + founder's custody; no rotation happens in this request. An existing different + KV value refuses. + - Setup refuses unless the live config binds uid=svc-keycape. KeyCape refuses to + start if KEYCAPE_LLDAP_BIND_PW and bindPW differ, so a wrong delivery cannot be + used silently. - Coding agents are fenced from the data and metadata paths in agent-high-risk-boundary before the first write. - - Node root, ESO administration and platform-admin remain inside this credential boundary. + - Node root, ESO administration and platform-admin remain inside this credential + boundary. verification: positive: - - Exact policy, role and bound claims read back; native reader login as the ESO ServiceAccount - gets only this policy with a lease of at most 15m - - KV value equals the live keycape-config bindPW before ESO is applied (setup), and the - delivered Secret (and bindPW while present) after ESO sync (verify), compared in memory - only - - ExternalSecret Ready/SecretSynced; KeyCape with the env rolls out Ready and a portal login - works, again after bindPW is cleared from keycape-config + - Exact policy, role and bound claims read back; native reader login as the ESO + ServiceAccount gets only this policy with a lease of at most 15m + - KV value equals the live keycape-config bindPW before ESO is applied (setup), + and the delivered Secret (and bindPW while present) after ESO sync (verify), compared + in memory only + - ExternalSecret Ready/SecretSynced; KeyCape with the env rolls out Ready and a + portal login works, again after bindPW is cleared from keycape-config negative: - - Reader cannot read metadata, a sibling path, the other directory-bind paths or create - tokens + - Reader cannot read metadata, a sibling path, the other directory-bind paths or + create tokens - Wrong ServiceAccount, wrong audience and wrong namespace logins are denied - Coding-agent boundary denies data and metadata of the path activation_conditions: - Explicit platform-owner and net-kingdom-owner approval of this exact request (sha256-bound by the setup tool). - - Attended platform-admin (aal2) session for setup; the founder runs it, value read from - the decrypted custody copy without display. - - Policy, role and KV in place and equal to live before the ExternalSecret is applied; the - KeyCape image with KEY-WP-0046 deployed before the env is added. + - Attended platform-admin (aal2) session for setup; the founder runs it, value read + from the decrypted custody copy without display. + - Policy, role and KV in place and equal to live before the ExternalSecret is applied; + the KeyCape image with KEY-WP-0046 deployed before the env is added. - Positive and negative results recorded in value-free receipts. evidence: []