railiance-platform/credential-change-requests/CCR-2026-0018-keycape-approval-engine-operator-client.yaml
codex c6dc4286e2
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
feat: verify live KeyCape custody and preserve versions on resume
Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-09 02:18:12 +02:00

162 lines
8.4 KiB
YAML

id: CCR-2026-0018
kind: credential-change-request
schema_version: 1
request_type: workload-kv-read
title: KeyCape verifier custody for the approval-engine-operator confidential client
status: verified
created: '2026-09-08'
updated: '2026-09-09'
requester:
agent: claude
reason: 'Second of the two registrations in KEY-WP-0013-T02 (State Hub message 278a3ebe-b529-49f6-bd1a-e3ebcf318260):
client approval-engine-operator, subject service:approval-engine-operator, audience
approval-engine, tenant:platform per resolved decision 5ed3fb35-eca9-413a-82b9-95171ba85bf6,
15m token lifetime. Scopes are approval:create, read, approve, revoke, supersede,
observe and emit, explicitly without approval:consume. KeyCape owns registration
and issuance; this request establishes only custody and the KeyCape-side delivery.'
review:
required: true
required_approvers:
- platform-operator
- key-cape-owner
comments:
- at: '2026-09-08'
reviewer: railiance-platform (codex/claude)
decision: paths_confirmed_field_corrected
comment: KV path platform/workloads/approval-engine/operator-client is confirmed
unchanged and conforms to the platform/workloads/<workload>/<lane> convention.
Field client_secret is corrected to CLIENT_SECRET for the same uppercase convention
and validator constraint as CCR-2026-0017. Kubernetes Secret sso/keycape-approval-engine-operator-client
with key client-secret and the KeyCape environment name are confirmed as proposed.
- at: '2026-09-08T23:05:20+00:00'
reviewer: User (platform-operator; explicit session approval)
decision: approved
comment: User answered "I approve, go on." to the explicit two-CCR approval question
naming both required roles. Scope remains verifier-side custody and its attended
rollout, as reviewed in docs/credential-lane-designs/keycape-approval-clients-review.md.
No client-side read or factory spending grant.
- at: '2026-09-08T23:05:20+00:00'
reviewer: User (key-cape-owner; explicit session approval)
decision: approved
comment: User answered "I approve, go on." to the explicit two-CCR approval question
naming both required roles. Scope remains verifier-side custody and its attended
rollout, as reviewed in docs/credential-lane-designs/keycape-approval-clients-review.md.
No client-side read or factory spending grant.
target:
domain: financials
tenant: platform
workload: approval-engine
environment: production
purpose: Hold the approval-engine-operator confidential client secret in platform
custody and project it into the KeyCape runtime so KeyCape can verify presented
client_credentials for the operator client.
openbao:
mount: platform
kv_path: platform/workloads/approval-engine/operator-client
fields:
- CLIENT_SECRET
policy_name: workload-kv-read-keycape-approval-engine-operator
policy_file: openbao/policies/workload-kv-read-keycape-approval-engine-operator.hcl
auth:
method: kubernetes
mount: kubernetes
role: external-secrets-keycape-approval-engine-operator
bound_claims:
service_account_names:
- external-secrets
service_account_namespaces:
- external-secrets
bound_claims_confirmed: true
policies:
- workload-kv-read-keycape-approval-engine-operator
ttl: 15m
access_frontdoor:
type: ops-warden
catalog_id: keycape-approval-engine-operator-client
selector: KeyCape approval-engine-operator confidential client secret
command: warden access keycape-approval-engine-operator-client --fetch CLIENT_SECRET
resolvable: false
readiness: pending-review
delivery:
surface: external-secrets
target: 'ClusterSecretStore openbao-keycape-approval-engine-operator, limited to
namespace sso, to ExternalSecret sso/keycape-approval-engine-operator-client and
Secret sso/keycape-approval-engine-operator-client with key client-secret. KeyCape
resolves it as KEYCAPE_APPROVAL_ENGINE_OPERATOR_CLIENT_SECRET through a secretKeyRef.
Manifests: argocd/platform-addons/openbao-secretstore/openbao-keycape-approval-clients.clustersecretstore.yaml
and keycape-approval-clients.externalsecrets.yaml.'
risk:
classification: high
notes:
- "This client carries the widest approval scope set in the pair \u2014 create,\
\ approve, revoke and supersede. A leak allows forging approval lifecycle actions,\
\ which is a stronger outcome than the read/consume client in CCR-2026-0017."
- The absence of approval:consume is a deliberate separation of duties. Any later
request to add consume to this client is a new lane decision, not a scope edit.
- Kept on its own policy, role and store so it can be revoked independently of the
secrets-engine-approval client.
- Compromise response is KeyCape disabling the registration plus rotation of this
KV version; approval actions already emitted are not retracted by rotation and
need approval-engine's own audit review.
verification:
positive:
- The ExternalSecret in namespace sso syncs CLIENT_SECRET to Secret key client-secret
without printing the value.
- The KeyCape build issues a token for subject service:approval-engine-operator
with audience approval-engine, tenant:platform and 15m lifetime, verified against
live JWKS signature.
negative:
- A namespace outside the approved ClusterSecretStore condition cannot use this
store to read the path.
- A service account outside external-secrets/external-secrets cannot authenticate
through role external-secrets-keycape-approval-engine-operator.
- The role cannot read the sibling secrets-engine approval-client path, any parent
listing, or any other platform workload path.
- The operator client is denied approval:consume, and denial is observed rather
than assumed.
activation_conditions:
- Same single attended rollout window and prepared-but-undeployed KeyCape image
as CCR-2026-0017; see docs/credential-lane-designs/keycape-approval-clients.md.
- Attended first provision only through openbao-platform-admin-login (founder_required,
attended OIDC via netkingdom role=platform-admin) with a unique receipt path.
- Policy, Kubernetes auth role and ClusterSecretStore applied before the ExternalSecret;
sync confirmed before the KeyCape rollout.
- Positive and negative results recorded with non-secret request ids or timestamps.
evidence:
- at: '2026-09-09T00:14:27+00:00'
actor: the-custodian (codex)
kind: verifier_custody_and_rollout
result: passed
details:
- Named user approval recorded for platform-operator and key-cape-owner on 2026-09-09.
- Initial CAS=0 custody created version 1. Verified rollback/resume retained the
same values and versions.
- Both stores Valid and ExternalSecrets SecretSynced; exact native read, sibling/listing
and wrong service account/namespace/store-use denials passed; reader revocation
and coding-agent deny precedence passed.
- Pinned image 7ff54c54e63e has one ready replica; protected previous config/image
retained and signing key unchanged.
- Both clients passed live JWKS and exact audience/subject/tenant/role/scope/900-second
lifetime checks, excess-scope and wrong-secret denials; human client consume
denied.
- Native verifier from pinned image ran in the attended owner process with memory-only
credentials. Pod network policy remains unchanged. Future iat bound is the existing
30-second contract; expiry has zero leeway.
- Fresh post-rollout OpenBao OIDC login succeeded and self-revoked. No client-side
fetch front door or factory spending was admitted.
- 'Receipt: docs/evidence/2026-09-09-keycape-verifier-admission.json'
lifecycle:
deactivate: KeyCape disables the approval-engine-operator registration; platform
detaches the policy from role external-secrets-keycape-approval-engine-operator
and removes the ExternalSecret.
rotate: KeyCape mints a replacement client secret; platform writes the new KV version
under the same attended authority. Rotation is independent of CCR-2026-0017.
compromised: Disable the registration at KeyCape, rotate the KV version, and refer
emitted approval actions to approval-engine for audit review.
state_hub:
decision_id: efa90517-0cae-4eb6-a68d-5b0489c84d65
decision_api_url: http://127.0.0.1:8000/decisions/efa90517-0cae-4eb6-a68d-5b0489c84d65
workplan_id: RPF-WP-0035
task_id: RPF-WP-0035-T05
related_message: 278a3ebe-b529-49f6-bd1a-e3ebcf318260
related_decision: 5ed3fb35-eca9-413a-82b9-95171ba85bf6