From d20ebe7bca6fab8453d3b96a824da0f59ba3ab6b Mon Sep 17 00:00:00 2001 From: codex Date: Sat, 31 Oct 2026 10:31:56 +0100 Subject: [PATCH] CCR-2026-0054 (proposed): NetKingdom svc-keycape directory bind custody and ESO delivery Third NK-WP-0056-T04 lane. ESO owns a dedicated Secret sso/keycape-lldap-bind read by KeyCape as KEYCAPE_LLDAP_BIND_PW (key-cape KEY-WP-0046). Binding unconfirmed; apply blocked until owner approval and confirm-binding. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 896183@bnt-lap001 Assistant-Session: 3a18c01a-3205-4d02-94db-9efff25649a2 --- ...CR-2026-0054-net-kingdom-keycape-bind.yaml | 117 ++++++++++++++++++ .../net-kingdom-svc-keycape-bind-eso.hcl | 3 + 2 files changed, 120 insertions(+) create mode 100644 credential-change-requests/CCR-2026-0054-net-kingdom-keycape-bind.yaml create mode 100644 openbao/policies/net-kingdom-svc-keycape-bind-eso.hcl 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 new file mode 100644 index 0000000..ef38479 --- /dev/null +++ b/credential-change-requests/CCR-2026-0054-net-kingdom-keycape-bind.yaml @@ -0,0 +1,117 @@ +id: CCR-2026-0054 +kind: credential-change-request +schema_version: 1 +request_type: workload-kv-read +title: NetKingdom KeyCape directory bind (svc-keycape) delivery +status: proposed +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.' +review: + required: true + required_approvers: + - platform-owner + - net-kingdom-owner + comments: [] +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 +openbao: + mount: platform + kv_path: platform/workloads/net-kingdom/directory-binds/svc-keycape + fields: + - LDAP_BIND_PASSWORD + policy_name: net-kingdom-svc-keycape-bind-eso + policy_file: openbao/policies/net-kingdom-svc-keycape-bind-eso.hcl + metadata_read: false + token_self_lifecycle: true + auth: + method: kubernetes + mount: kubernetes + role: net-kingdom-svc-keycape-bind-eso + audience: openbao + ttl: 15m + token_max_ttl: 15m + token_explicit_max_ttl: 15m + token_no_default_policy: true + policies: + - net-kingdom-svc-keycape-bind-eso + bound_claims: + service_account_names: + - net-kingdom-svc-keycape-bind-eso + service_account_namespaces: + - sso + bound_claims_confirmed: false +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. +delivery: + surface: ESO-owned Secret (creationPolicy Owner, new dedicated Secret) + namespace: sso + secret: keycape-lldap-bind + key: password + service_account: net-kingdom-svc-keycape-bind-eso + reader: KeyCape Deployment in sso, env KEYCAPE_LLDAP_BIND_PW from secretKeyRef keycape-lldap-bind/password + (image with key-cape KEY-WP-0046); no agent credential delivery + manifest: 'net-kingdom: sso-mfa/k8s/keycape/bind-eso.yaml' + cluster_uid: a553c742-0115-43d4-99a4-a5ca56fe0786 +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. + - 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. +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 + negative: + - 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. + - Positive and negative results recorded in value-free receipts. + evidence: [] diff --git a/openbao/policies/net-kingdom-svc-keycape-bind-eso.hcl b/openbao/policies/net-kingdom-svc-keycape-bind-eso.hcl new file mode 100644 index 0000000..801fd32 --- /dev/null +++ b/openbao/policies/net-kingdom-svc-keycape-bind-eso.hcl @@ -0,0 +1,3 @@ +path "platform/data/workloads/net-kingdom/directory-binds/svc-keycape" { capabilities = ["read"] } +path "auth/token/lookup-self" { capabilities = ["read"] } +path "auth/token/revoke-self" { capabilities = ["update"] }