Prepare the two approval client-side reader admissions
RPF-WP-0035-T06. Adds CCR-2026-0019 (secrets-engine) and CCR-2026-0020 (approval-engine-operator) with their exact-path read policies, reusing the existing version-1 custody from the verifier activation. No reseed, rotation, shared reader or verifier Secret reuse; both requests are in_flight and nothing is applied. The two shapes were decided by read-only survey rather than assumed. secrets-engine consumes its client secret through an operator-run CLI reading a protected file, and its namespace holds no workload, so reader 1 is an attended operator-workstation OIDC lane rather than an ESO lane; its one missing input is the operator group claim, which NetKingdom and KeyCape own. approval-engine is not deployed and no owner source names who presents the operator client, so reader 2 records the undetermined actor instead of guessing one for the widest approval scope in the pair. Both declare openbao.auth missing rather than carrying a placeholder binding. T06 moves to wait on those two owner inputs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WLUjpv3ssxNRAEPPgLFnEB Assistant: claude-code Assistant-Model: opus Assistant-Process: 1275505@bnt-lap001 Assistant-Session: 97265baa-f08f-4032-b290-a1e2965a69c5
This commit is contained in:
parent
5507fac156
commit
32d5cf0211
7 changed files with 431 additions and 1 deletions
|
|
@ -12,6 +12,7 @@ KeyCape approval-client admission below, which carries executable CCRs
|
|||
| [Fluid-telegram operator KV](fluid-telegram-operator-kv.md) | RPF-WP-0033 (finished) / RPF-WP-0035-T03 | MASON-WP-0005; FT-WP-0002 | Tenant acceptance, actual OIDC group, write-capable CCR support |
|
||||
| [State Hub preflight signing](state-hub-preflight-signing.md) | RPF-WP-0034 (finished) / RPF-WP-0035-T04 | FLEX-WP-0020-T05; STATE-WP-0085-T09 delivered | Deployment binding, owner-approved custody and rotation window |
|
||||
| [KeyCape approval-engine clients](keycape-approval-clients.md) | RPF-WP-0035-T05 | KEY-WP-0013-T02; GLAS-WP-0015 | Owner approval of CCR-2026-0017/0018, attended founder window, KeyCape reading build |
|
||||
| [Approval client-side readers](keycape-approval-client-side-readers.md) | RPF-WP-0035-T06 | SECRETS-WP-0009-T03; APPROVAL-WP-0002 | Reader 1: exact operator group claim; Reader 2: the presenting actor is unnamed by any owner source |
|
||||
|
||||
The completed design workplans are archived. RPF-WP-0035 is the canonical
|
||||
queue for owner review, implementation, and live acceptance still required.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
# Approval client-side readers
|
||||
|
||||
RPF-WP-0035-T06, the residual handed over by the completed verifier custody
|
||||
(T05). Requests:
|
||||
[CCR-2026-0019](../../credential-change-requests/CCR-2026-0019-secrets-engine-approval-client-read.yaml)
|
||||
and [CCR-2026-0020](../../credential-change-requests/CCR-2026-0020-approval-engine-operator-client-read.yaml).
|
||||
Both are `in_flight`, neither is approved, and nothing is applied.
|
||||
|
||||
## Why this exists as separate requests
|
||||
|
||||
CCR-2026-0017/0018 admitted the **verifier** copies: KeyCape holds the two client
|
||||
secrets so it can authenticate credentials presented to it. Presenting them is a
|
||||
different power with a different holder, so it needs its own admission. The two
|
||||
Warden fetch selectors that the verifier review left unresolved are exactly this
|
||||
gap. Both readers use the **existing version-1 custody** — no reseed, no
|
||||
rotation, no shared reader, no reuse of the `sso` verifier Secrets.
|
||||
|
||||
## Survey, 2026-09-09
|
||||
|
||||
Read-only, against owner source and the live cluster.
|
||||
|
||||
| Question | Finding |
|
||||
| --- | --- |
|
||||
| Is there an in-cluster secrets-engine consumer? | No. Namespace `secrets-engine` holds only ServiceAccount `secrets-engine` and no workload. `flex-auth/flex-auth-secrets-engine` is the flex-auth PDP for that consumer, not the service. |
|
||||
| How does secrets-engine consume the client secret? | Operator-run CLI reading `SECRETS_ENGINE_APPROVAL_CLIENT_SECRET_FILE`, exchanged for a fresh token before each request, held in memory only, no refresh token or fallback identity. Implemented 2026-09-09, SECRETS-WP-0009-T03, `secrets-engine` revision `9eb07fd`. |
|
||||
| Is approval-engine deployed? | No. No namespace, workload or Service. The owner manifest targets namespace `approval-engine` with a digest-pinned image and is unapplied. |
|
||||
| Who presents `approval-engine-operator`? | Not identified by any owner source. approval-engine verifies these tokens and never presents them. |
|
||||
|
||||
## Reader 1 — secrets-engine-approval (CCR-2026-0019)
|
||||
|
||||
Shape is determined; one input is missing.
|
||||
|
||||
| Item | Value |
|
||||
| --- | --- |
|
||||
| Path / field | `platform/workloads/secrets-engine/approval-client` / `CLIENT_SECRET` |
|
||||
| Policy | `workload-kv-read-secrets-engine-approval-client` (exact data + metadata read, written and committed) |
|
||||
| Auth | `oidc` on mount `netkingdom`, role `secrets-engine-approval-client-read`, standard three redirect URIs, scopes `openid profile email groups`, `user_claim: sub`, `groups_claim: groups`, ttl 15m |
|
||||
| Front door | `warden access secrets-engine-approval-client --out FILE` |
|
||||
| Delivery | Protected owner-only file outside any Git work tree, consumed as `SECRETS_ENGINE_APPROVAL_CLIENT_SECRET_FILE`, removed at end of session |
|
||||
|
||||
**Missing:** the exact group claim for the authorized operator. NetKingdom and
|
||||
KeyCape own it; this repo and secrets-engine cannot supply it. The role cannot
|
||||
be created without it, so `openbao.auth` is declared missing rather than
|
||||
recorded with a placeholder that would later be mistaken for a confirmed
|
||||
binding.
|
||||
|
||||
This is an operator-workstation lane, not an External Secrets lane — because the
|
||||
consumer is a CLI, not a pod. A file-delivered credential outlives the process
|
||||
that read it, so removal depends on operator hygiene. That is weaker than the
|
||||
pod-lifetime bound of the verifier delivery and is recorded as a consequence of
|
||||
the consumer's shape rather than engineered away.
|
||||
|
||||
## Reader 2 — approval-engine-operator (CCR-2026-0020)
|
||||
|
||||
Held open deliberately. The exact-path read policy
|
||||
`workload-kv-read-approval-engine-operator-client` is written and committed so
|
||||
the eventual reader inherits a bounded grant rather than one drafted under time
|
||||
pressure. Writing the policy is not admitting a reader.
|
||||
|
||||
**Missing:** the presenting actor and its placement. This client carries the
|
||||
widest scope set in the pair — `approval:create`, `read`, `approve`, `revoke`,
|
||||
`supersede`, `observe`, `emit`, and deliberately not `consume`. approval-engine
|
||||
records `principal_type` on every entry rather than restricting who may supply
|
||||
approver evidence, and its owner records that whether a non-human principal
|
||||
*should* is approval doctrine belonging to `gate-house`. Naming a reader here
|
||||
would hand the widest approval scope to a guessed identity, so the request names
|
||||
what is undetermined instead.
|
||||
|
||||
The delivery surface follows the actor: an attended operator implies a protected
|
||||
workstation file; an in-cluster component implies an ExternalSecret into the
|
||||
eventual `approval-engine` namespace; an agent surface implies neither.
|
||||
|
||||
## Not in scope
|
||||
|
||||
- No reseed or rotation of either custody path. Rotation is one version-guarded
|
||||
operation shared with the verifier copies and needs both owners.
|
||||
- No `approval:consume` on the operator client, now or by later scope edit.
|
||||
- No reuse of the `sso` verifier Secrets or the KeyCape verifier roles.
|
||||
- No audit-sender custody; that stays with the existing owner records.
|
||||
Loading…
Add table
Add a link
Reference in a new issue