Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
173 lines
8.1 KiB
YAML
173 lines
8.1 KiB
YAML
id: CCR-2026-0019
|
|
kind: credential-change-request
|
|
schema_version: 1
|
|
request_type: workload-kv-read
|
|
title: secrets-engine client-side read of its approval client secret
|
|
status: in_flight
|
|
created: '2026-09-09'
|
|
updated: '2026-09-10'
|
|
in_flight:
|
|
missing_fields:
|
|
- openbao.auth
|
|
blocking_reason: >-
|
|
The reader is an attended operator running the secrets-engine CLI on a
|
|
workstation, not an in-cluster identity. The auth binding is therefore
|
|
determined in shape but not bindable: method oidc on mount netkingdom, role
|
|
secrets-engine-approval-client-read, the three standard NetKingdom redirect
|
|
URIs, scopes openid/profile/email/groups, user_claim sub, groups_claim
|
|
groups, policy workload-kv-read-secrets-engine-approval-client, ttl 15m --
|
|
with the one missing input being the exact group claim for the authorized
|
|
operator, which NetKingdom/KeyCape own. A role cannot be created without it
|
|
and no placeholder is recorded here. Live inspection on 2026-09-09 found namespace
|
|
secrets-engine holding only ServiceAccount secrets-engine with no workload,
|
|
which confirms there is no in-cluster consumer to bind instead.
|
|
owner: railiance-platform
|
|
requester:
|
|
agent: claude
|
|
reason: >-
|
|
RPF-WP-0035-T06 residual from the completed verifier custody
|
|
(CCR-2026-0017). The verifier copy lets KeyCape authenticate the
|
|
secrets-engine-approval client; it does not let secrets-engine present that
|
|
client. secrets-engine implemented the consumer on 2026-09-09
|
|
(SECRETS-WP-0009-T03, repo revision 9eb07fd,
|
|
secrets-engine/docs/approval-service-auth.md) and reads the value from
|
|
SECRETS_ENGINE_APPROVAL_CLIENT_SECRET_FILE, an explicit protected file. This
|
|
request establishes the separate exact read that fills that file. It reuses
|
|
the existing version-1 custody and requests no reseed and no rotation.
|
|
review:
|
|
required: true
|
|
required_approvers:
|
|
- platform-operator
|
|
- secrets-engine-owner
|
|
comments:
|
|
- at: '2026-09-09'
|
|
reviewer: railiance-platform (claude)
|
|
decision: shape_determined_actor_pending
|
|
comment: >-
|
|
Reader shape determined from owner source rather than assumed: the
|
|
consumer is an operator-run CLI that exchanges the client secret for a
|
|
short-lived token immediately before each approval request, holds it only
|
|
in memory, and has no refresh token, renewal or fallback identity. That
|
|
makes this an attended operator-workstation lane on the OIDC mount, not an
|
|
External Secrets lane. The named operator group claim is the one input
|
|
neither this repo nor secrets-engine can supply; NetKingdom/KeyCape own it.
|
|
- at: '2026-09-10'
|
|
reviewer: codex (consumer source review)
|
|
decision: consumer_procedure_documented
|
|
comment: >-
|
|
Secrets Engine source 98d72ceb1dbcff2d2a80fb8c3058d76777a0ac93,
|
|
docs/approval-service-auth.md, supplies the requested workstation
|
|
procedure: operator-owned 0700 runtime session directory outside Git,
|
|
new 0600 file, path-only configuration across one claim/consume operation,
|
|
EXIT/INT/TERM cleanup, and explicit residual-file handling after a hard
|
|
interruption. The consumer checks file permissions/location/non-emptiness;
|
|
creation, parent custody and removal remain attended responsibilities.
|
|
No automatic cleanup or live read proof is claimed. This documents the
|
|
consumer return; it is not platform-operator/secrets-engine-owner approval,
|
|
group confirmation or authority to apply the role. Existing activation
|
|
conditions and in_flight status remain.
|
|
target:
|
|
domain: financials
|
|
tenant: platform
|
|
workload: secrets-engine
|
|
environment: production
|
|
purpose: >-
|
|
Let the authorized operator running the secrets-engine approval CLI fetch the
|
|
secrets-engine-approval client secret into a protected file, without granting
|
|
any in-cluster reader, any sibling path, or any write on the custody path.
|
|
openbao:
|
|
mount: platform
|
|
kv_path: platform/workloads/secrets-engine/approval-client
|
|
fields:
|
|
- CLIENT_SECRET
|
|
policy_name: workload-kv-read-secrets-engine-approval-client
|
|
policy_file: openbao/policies/workload-kv-read-secrets-engine-approval-client.hcl
|
|
access_frontdoor:
|
|
type: ops-warden
|
|
catalog_id: secrets-engine-approval-client
|
|
selector: secrets-engine approval client secret
|
|
command: warden access secrets-engine-approval-client --out FILE
|
|
resolvable: false
|
|
readiness: pending-review
|
|
delivery:
|
|
surface: operator-workstation
|
|
target: >-
|
|
Protected file consumed as SECRETS_ENGINE_APPROVAL_CLIENT_SECRET_FILE by the
|
|
secrets-engine approval CLI: owner-only mode, outside any Git work tree,
|
|
removed at the end of the session. No Kubernetes Secret, no ExternalSecret
|
|
and no reuse of the sso verifier Secret keycape-secrets-engine-approval-client.
|
|
risk:
|
|
classification: high
|
|
notes:
|
|
- >-
|
|
This is the presenting copy. Anyone holding it can obtain tokens as
|
|
service:secrets-engine for approval:read and approval:consume until KeyCape
|
|
disables the registration. The verifier copy admitted in CCR-2026-0017 does
|
|
not carry that power; the two must not be conflated because they hold the
|
|
same value.
|
|
- >-
|
|
A file-delivered credential outlives the process that read it. The lane
|
|
depends on operator hygiene for removal, which is weaker than an
|
|
ESO-delivered Secret bounded by a pod lifetime. That is a consequence of the
|
|
consumer being a workstation CLI and is recorded rather than engineered away.
|
|
- >-
|
|
approval:consume is a production-effect scope. This lane grants the ability
|
|
to present the client; it does not grant approval decisions, which remain
|
|
with access-engine, approval-engine and the existing consume gates.
|
|
- >-
|
|
No reseed and no rotation. Custody is the existing version 1 from the
|
|
verifier activation; a rotation is a distinct version-guarded operation that
|
|
also invalidates the KeyCape verifier copy and needs both owners.
|
|
verification:
|
|
positive:
|
|
- >-
|
|
The bound operator identity reads CLIENT_SECRET from the exact path into a
|
|
protected file with no value in chat, argv, shell history or logs.
|
|
- >-
|
|
The secrets-engine approval CLI exchanges it for a token with subject
|
|
service:secrets-engine, audience approval-engine, tenant tenant:platform and
|
|
the single requested scope, verified against live JWKS.
|
|
negative:
|
|
- >-
|
|
An identity outside the confirmed group claim cannot authenticate through
|
|
role secrets-engine-approval-client-read.
|
|
- >-
|
|
The role cannot read the approval-engine operator-client path, cannot list
|
|
any parent, and cannot write or patch the custody path.
|
|
- >-
|
|
No in-cluster ServiceAccount, including secrets-engine/secrets-engine, gains
|
|
a read through this lane.
|
|
- >-
|
|
The KeyCape verifier role cannot be substituted for this reader, and this
|
|
reader cannot read the verifier's delivery Secret.
|
|
activation_conditions:
|
|
- >-
|
|
NetKingdom/KeyCape confirm the exact group claim for the authorized operator
|
|
and it is recorded in openbao.auth.bound_claims with
|
|
bound_claims_confirmed true.
|
|
- >-
|
|
secrets-engine confirms the workstation procedure, file mode and removal step
|
|
for SECRETS_ENGINE_APPROVAL_CLIENT_SECRET_FILE.
|
|
- >-
|
|
Policy and OIDC role applied under attended authority
|
|
(openbao-platform-admin-login, founder_required) with metadata-only receipts.
|
|
- Positive and negative results recorded with non-secret request ids.
|
|
evidence: []
|
|
lifecycle:
|
|
deactivate: >-
|
|
Detach the policy from role secrets-engine-approval-client-read and disable
|
|
the ops-warden catalog entry. The KeyCape verifier lane and its delivery are
|
|
unaffected.
|
|
rotate: >-
|
|
Shared with CCR-2026-0017: the value is one client secret. Rotation is minted
|
|
by KeyCape and rewritten once under attended authority; both the verifier
|
|
delivery and this reader then see the new version. No independent rotation
|
|
exists for this lane alone.
|
|
compromised: >-
|
|
KeyCape disables the secrets-engine-approval registration first, since that
|
|
is what stops token issuance, then the value is rotated and this role's
|
|
policy detached pending review.
|
|
state_hub:
|
|
workplan_id: RPF-WP-0035
|
|
task_id: RPF-WP-0035-T06
|
|
related_request: CCR-2026-0017
|