RPF-WP-0035-T14: flex-auth signer custody founder gate, runbook and review dispositions
- CCR-2026-0050: record secrets-engine-owner approval (two receipt conditions) and platform runbook review; link founder decision 18731e84. - Attended creation runbook with preconditions, rollback and negatives. - Warden routing receipt: openbao-platform-admin-login / oidc_login now selected. - Native adapter: owner-review digest excludes expires_at so reviews can precede the 120 s window (close-down checklist row 27). Nothing generated, written or applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 809600@bnt-lap001 Assistant-Session: 40ba228f-c8a0-4ec9-bb29-3129951afdc4
This commit is contained in:
parent
1228cd8407
commit
20db368aee
7 changed files with 317 additions and 5 deletions
|
|
@ -78,6 +78,7 @@
|
|||
| task | RPF-WP-0035-T11 | done | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T12 | progress | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T13 | done | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T14 | wait | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0036-T01 | done | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T02 | done | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T03 | wait | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ request_type: workload-kv-read
|
|||
title: Retained flex-auth lifecycle PDP Ed25519 seed ESO read lane
|
||||
status: proposed
|
||||
created: '2026-10-16'
|
||||
updated: '2026-10-16'
|
||||
updated: '2026-10-21'
|
||||
requester:
|
||||
agent: railiance-platform
|
||||
reason: CUST-WP-0080 / RPF-WP-0035-T12 / FLEX-WP-0024-T06 source proposal. Exact
|
||||
|
|
@ -23,6 +23,12 @@ review:
|
|||
- reviewer: railiance-platform-owner (agent railiance-platform, codex)
|
||||
decision: approved
|
||||
comment: "INTENT Secure Custody/Stable Interfaces/Operable and Observable; RPF-WP-0035-T12. Approved Platform source/plan review only for frozen P4 manifest sha256:9eec861838a8e9138f2c821cff3014998fbe74bb01447642bf50d44e8b3b7cb3 and R2 manifest sha256:5be7a7f438624dcb35b7dbc96e7c9e5a8e2d5d1b1966cb4338aa5aecbe3a8b59; own bounded review artifact docs/evidence/2026-10-16-flex-auth-native-plan-review.json; sanitized supplement sha256:f02a9b595d9246a358d19b37bdad8fde158b7f0c9657a6ff088874732511a32c. Exact read policy/role/ESO proposal and one-use CAS0 writer stay separate. Identified manual Applications and recovery gates are mandatory. No founder decision, native execution, confirmed bindings or completed admission assent; current proposed status unchanged."
|
||||
- reviewer: secrets-engine-owner (agent secrets-engine, hub message e73c9ffc-8a6d-4a17-9604-84324c678dc0)
|
||||
decision: approved
|
||||
comment: "2026-10-21, consumer side only. Consumer has no KV read role and receives no seed; public trust is admitted through a founder ssh-keygen -Y signed trust file (secrets-engine ebd8e49, docs/founder-admission.md, SECRETS-WP-0014-T04, decision e4eee965). Conditions: (1) the public receipt (kid, Ed25519 public key as 43-char unpadded base64url, evaluator/mode/policy_package/policy_version/policy_package_digest) is emitted by the attended writer at creation time or derived from its public output, never from a later read of the KV document; (2) the receipt carries the KV version and source/image provenance hashes. Not founder approval, native execution or a binding."
|
||||
- reviewer: railiance-platform-owner (agent railiance-platform, claude)
|
||||
decision: approved
|
||||
comment: "2026-10-21 runbook review: docs/runbooks/flex-auth-envelope-signing-attended-creation.md prepared. Secrets condition 1 is met for kid/public key/fingerprint/kv_version/source/image hashes by deriving the consumer receipt from the writer receipt (no KV read); the evaluator/mode/policy_package/policy_version/policy_package_digest fields are not in the writer receipt and must come from Access's published pin. Review-scope digest no longer binds expires_at so owner reviews can precede the 120 s window. Pending: access-engine-owner (awaited), cluster-runtime-storage-owner (railiance-cluster, requested f8b4b229), founder. Nothing executed."
|
||||
target:
|
||||
domain: infotech
|
||||
tenant: platform
|
||||
|
|
@ -135,4 +141,6 @@ lifecycle:
|
|||
compromised seed; archive historical public keys for offline audit only.
|
||||
state_hub:
|
||||
workplan_id: RPF-WP-0035
|
||||
task_id: RPF-WP-0035-T12
|
||||
task_id: RPF-WP-0035-T14
|
||||
decision_id: 18731e84-a6ab-4ac5-bf0e-7e7c3a9c4508
|
||||
decision_api_url: http://127.0.0.1:8000/decisions/18731e84-a6ab-4ac5-bf0e-7e7c3a9c4508
|
||||
|
|
|
|||
103
docs/evidence/2026-10-21-flex-auth-signer-warden-route.json
Normal file
103
docs/evidence/2026-10-21-flex-auth-signer-warden-route.json
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
"need": "attended OpenBao platform administration of flex-auth signer CAS0 seed and KV metadata setup",
|
||||
"verdict": "founder_required",
|
||||
"organization_posture": "build",
|
||||
"policy_gate": "zone-aware \u2014 fetches gated by flex-auth-ops-warden-fetch at http://127.0.0.1:19091",
|
||||
"lane_id": "openbao-platform-admin-login",
|
||||
"lane_title": "Attended OpenBao platform administration login",
|
||||
"match_score": 9,
|
||||
"commands": [
|
||||
"warden access openbao-platform-admin-login --exec -- <reviewed-command>",
|
||||
"# owner login is contained by warden; do not invoke it separately"
|
||||
],
|
||||
"founder_act": {
|
||||
"kind": "oidc_login",
|
||||
"summary": "Interactive OIDC/MFA login via railiance-platform",
|
||||
"details": {
|
||||
"lane_id": "openbao-platform-admin-login",
|
||||
"auth_method": "attended KeyCape OIDC/MFA at OpenBao auth mount netkingdom, role platform-admin",
|
||||
"fetch_command": "warden access openbao-platform-admin-login --exec -- <reviewed-command>",
|
||||
"desk_hint": "warden desk --from-plan (act=oidc_login); execute only through: warden access openbao-platform-admin-login --exec -- <reviewed-command>"
|
||||
}
|
||||
},
|
||||
"ccr_stub": null,
|
||||
"catalog": {
|
||||
"path": "/home/worsch/ops-warden/registry/routing/catalog.yaml",
|
||||
"source": "repo",
|
||||
"content_hash": "b007b9598551",
|
||||
"mtime_iso": "2026-10-20T11:42:31.833164+00:00",
|
||||
"package_version": "0.1.2",
|
||||
"entry_count": 49,
|
||||
"active_count": 41,
|
||||
"newest_reviewed": "2026-10-20",
|
||||
"oldest_reviewed": "2026-06-18",
|
||||
"stale_entry_count": 18,
|
||||
"using_bundled": false,
|
||||
"warnings": [
|
||||
"18 catalog entries past 90d review cadence",
|
||||
"17 interim delegations need re-verifying (risk-scaled blocker cadence) \u2014 see `warden route gaps`"
|
||||
]
|
||||
},
|
||||
"candidates": [
|
||||
{
|
||||
"id": "openbao-platform-admin-login",
|
||||
"title": "Attended OpenBao platform administration login",
|
||||
"score": 9,
|
||||
"status": "active",
|
||||
"resolvable": true,
|
||||
"exec_capable": true,
|
||||
"warden_executes": false,
|
||||
"lane": "login",
|
||||
"risk": "high"
|
||||
},
|
||||
{
|
||||
"id": "openbao-structure-survey",
|
||||
"title": "OpenBao existing-structure survey for a construction plan (section 2)",
|
||||
"score": 9,
|
||||
"status": "active",
|
||||
"resolvable": false,
|
||||
"exec_capable": false,
|
||||
"warden_executes": false,
|
||||
"lane": "ceremony",
|
||||
"risk": "high"
|
||||
},
|
||||
{
|
||||
"id": "openbao-api-key",
|
||||
"title": "API key, DB credential, or dynamic lease",
|
||||
"score": 6,
|
||||
"status": "active",
|
||||
"resolvable": false,
|
||||
"exec_capable": true,
|
||||
"warden_executes": false,
|
||||
"lane": "secret",
|
||||
"risk": "high"
|
||||
},
|
||||
{
|
||||
"id": "openbao-shamir-recovery-ceremony",
|
||||
"title": "Attended OpenBao Shamir seal and unseal recovery ceremony",
|
||||
"score": 6,
|
||||
"status": "active",
|
||||
"resolvable": false,
|
||||
"exec_capable": false,
|
||||
"warden_executes": false,
|
||||
"lane": "ceremony",
|
||||
"risk": "high"
|
||||
},
|
||||
{
|
||||
"id": "ops-warden-warden-sign-token",
|
||||
"title": "Scoped OpenBao token for ops-warden SSH signing (warden-sign)",
|
||||
"score": 6,
|
||||
"status": "active",
|
||||
"resolvable": false,
|
||||
"exec_capable": false,
|
||||
"warden_executes": false,
|
||||
"lane": "secret",
|
||||
"risk": "high"
|
||||
}
|
||||
],
|
||||
"reasons": [
|
||||
"login lane requires interactive founder/operator identity act"
|
||||
],
|
||||
"actor": null,
|
||||
"domain": null
|
||||
}
|
||||
143
docs/runbooks/flex-auth-envelope-signing-attended-creation.md
Normal file
143
docs/runbooks/flex-auth-envelope-signing-attended-creation.md
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
# Attended creation: flex-auth decision-envelope signing key (CCR-2026-0050)
|
||||
|
||||
Prepared 2026-10-21 under RPF-WP-0035-T14 (founder gate) for the custody route
|
||||
`flex-auth-decision-envelope-signing-key`. **Nothing in this file has been
|
||||
executed.** Every step that changes OpenBao or the cluster needs the founder's
|
||||
explicit go for that change, given at the time of the change. No value of the
|
||||
seed is printed, stored in Git, the hub, chat or a log at any point.
|
||||
|
||||
Inputs that are fixed by reviewed source:
|
||||
|
||||
| Item | Value |
|
||||
| --- | --- |
|
||||
| Read CCR | `credential-change-requests/CCR-2026-0050-flex-auth-envelope-signing.yaml` |
|
||||
| Native action | `docs/credential-lane-designs/flex-auth-envelope-signing-native-plan.json` (`RPF35-PDP-SIGNER-NATIVE-20261016-R1`) |
|
||||
| KV document | `platform/data/workloads/flex-auth/envelope-signing`, fields `ED25519_PRIVATE_KEY`, `ED25519_PUBLIC_KEY`, `kid` |
|
||||
| kid | `flex-auth-lifecycle-20261016-r1` |
|
||||
| Metadata contract | `cas_required=true`, `max_versions=2`, `delete_version_after=0s`; bootstrap is CAS 0 |
|
||||
| Read policy | `workload-kv-read-flex-auth-envelope-signing` (`openbao/policies/workload-kv-read-flex-auth-envelope-signing.hcl`) |
|
||||
| Read role | `auth/kubernetes/role/external-secrets-flex-auth-envelope-signing`, SA `flex-auth-envelope-signing-eso` in `flex-auth`, audience `openbao`, 15m, no default policy |
|
||||
| ESO projection | `docs/credential-lane-designs/flex-auth-envelope-signing-native-projection.yaml.proposed` (seed property only) |
|
||||
| Writer | `scripts/flex_auth_signer_native.py` + `scripts/flex_auth_signer_custody.py` (`sha256:f169ad12…110c`, as pinned in the native plan) |
|
||||
| Route | `warden access openbao-platform-admin-login --exec -- <reviewed-command>`; routing receipt `docs/evidence/2026-10-21-flex-auth-signer-warden-route.json` (`sha256:ad7d6a1829de53678b008b23627475e7570c71cf50f9f2ad5301635022a7f467`, lane `openbao-platform-admin-login`, verdict `founder_required`, act `oidc_login`) |
|
||||
| Private receipt dir | `/home/worsch/.local/state/railiance-platform/flex-auth-envelope-signing` (0700, files 0600) |
|
||||
|
||||
The 2026-10-16 routing blocker (warden selected `openbao-structure-survey`) no
|
||||
longer reproduces: the 2026-10-21 plan query selects the correct lane.
|
||||
|
||||
## 0. Preconditions (all must hold; any miss = stop)
|
||||
|
||||
1. Five dispositions on CCR-2026-0050 recorded in `review.comments`:
|
||||
founder, railiance-platform-owner, access-engine-owner, secrets-engine-owner,
|
||||
cluster-runtime-storage-owner (railiance-cluster).
|
||||
2. Founder decision on the hub (see RPF-WP-0035-T14) resolved with
|
||||
`APPROVE: CCR-2026-0050 ...`; then a platform session, not the requester,
|
||||
runs `make credential-change-sync-decision CREDENTIAL_CHANGE=CCR-2026-0050`.
|
||||
3. Access (FLEX-WP-0024-T06) has the retained deployment
|
||||
`flex-auth/flex-auth-secrets-engine` on the immutable candidate image
|
||||
`forgejo.coulomb.social/coulomb/flex-auth@sha256:09a83b27…981f` **stopped**:
|
||||
replicas 0, no owned ReplicaSet replicas, no pods using the signer SA or
|
||||
mounting the seed, no HPA. Protected consumers (secrets-engine) fenced.
|
||||
GitOps/Helm writers for the release frozen for the window.
|
||||
4. Cluster owner has reviewed the outbox PVC (1Gi local-path) and PV Retain.
|
||||
5. Secrets owner is ready to admit the public receipt through
|
||||
`secrets-engine/docs/founder-admission.md` (SECRETS-WP-0014-T04,
|
||||
decision e4eee965).
|
||||
6. Local tree is clean on the reviewed commit; tests pass:
|
||||
`uv run python -m pytest -q tests/test_flex_auth_signer_native.py tests/test_flex_auth_signer_custody.py`.
|
||||
|
||||
## 1. Read lane: policy and role (founder go #1)
|
||||
|
||||
```bash
|
||||
make credential-change-status CREDENTIAL_CHANGE=CCR-2026-0050 # expect status approved
|
||||
make credential-change-applier-dry-run CREDENTIAL_CHANGE=CCR-2026-0050
|
||||
make credential-change-applier-apply-plan CREDENTIAL_CHANGE=CCR-2026-0050
|
||||
# founder go, then:
|
||||
warden access openbao-platform-admin-login --exec -- \
|
||||
python3 scripts/credential-change.py applier-apply CCR-2026-0050 \
|
||||
--actor founder --record-state-hub
|
||||
# the founder types the confirmation phrase the tool prompts for
|
||||
```
|
||||
|
||||
Then verify native readback of the bound claims (no JWT or Secret printed) and
|
||||
record it: `python3 scripts/credential-change.py confirm-binding CCR-2026-0050
|
||||
--reviewer railiance-platform-owner --comment "<readback summary>"`.
|
||||
|
||||
Rollback: delete role `external-secrets-flex-auth-envelope-signing`, then
|
||||
policy `workload-kv-read-flex-auth-envelope-signing`. No KV data exists yet.
|
||||
|
||||
Negatives (record with `record-evidence`): login with a wrong SA, namespace and
|
||||
audience is refused; with the right identity, sibling path read, `list`,
|
||||
`metadata` read, write and delete are denied.
|
||||
|
||||
## 2. Seed creation (founder go #2; single attended window)
|
||||
|
||||
Do this inside one window of at most 120 seconds after building the admission.
|
||||
|
||||
1. Founder builds the admission file (owner-private, 0600, outside Git) in the
|
||||
schema `railiance-platform.signer-native-admission.v1` with
|
||||
`action=bootstrap`, the kid above, the routing receipt digest above, the
|
||||
immutable image, `caller_binding` and the five `owner_reviews`. Each review
|
||||
binds `review_scope_digest(admission)`, which excludes `owner_reviews` and
|
||||
`expires_at`, so reviewers can approve the exact scope ahead of the window.
|
||||
Set `expires_at` to now + 90 s last.
|
||||
2. Run, in the founder's terminal only:
|
||||
|
||||
```bash
|
||||
warden access openbao-platform-admin-login --exec -- \
|
||||
python3 scripts/flex_auth_signer_native.py \
|
||||
--admission <abs-path-admission.json> --admission-sha256 sha256:<hex> \
|
||||
--receipt-directory /home/worsch/.local/state/railiance-platform/flex-auth-envelope-signing
|
||||
```
|
||||
|
||||
The child checks the cluster ID, unseal, non-root platform-admin entity, audit
|
||||
enabled, read policy/role readback and the stop fence (rechecked before
|
||||
metadata setup and before CAS). It requires metadata absence (HTTP 404), sets the
|
||||
metadata contract, generates the seed in memory, writes with CAS 0, reads back
|
||||
version 1, and writes a receipt that holds public fields only. It is silent; the
|
||||
outcome is the receipt `status`:
|
||||
|
||||
- `custody-verified-pending-independent-public-admission`: success.
|
||||
- anything else, or no receipt: **unknown**. Keep everything fenced. Do not
|
||||
rerun bootstrap. Use the read-only `recover` action with a fresh admission
|
||||
that binds the original receipt digest.
|
||||
|
||||
Rollback before CAS: abort; nothing private was written. After CAS: no restore
|
||||
and no automatic retry. Forward-only recovery under a newly reviewed action.
|
||||
|
||||
## 3. Public receipt for secrets-engine (no private read)
|
||||
|
||||
Derive the consumer receipt from the writer receipt, never from a KV read (the
|
||||
KV document also holds the seed and reads are not field-filtered):
|
||||
|
||||
```bash
|
||||
R=/home/worsch/.local/state/railiance-platform/flex-auth-envelope-signing/<operation_id>.json
|
||||
jq '{kid, public_key, public_fingerprint, kv_version, writer_sha256,
|
||||
image_sha256: .bindings.image_sha256, policy_sha256: .bindings.policy_sha256,
|
||||
executed_revision_sha256: .bindings.executed_revision_sha256,
|
||||
deployment_sha256: .bindings.deployment_sha256, proposal_sha256: .bindings.proposal_sha256}' "$R" \
|
||||
> flex-auth-envelope-signing-public-receipt.json
|
||||
```
|
||||
|
||||
Then add the policy pin fields secrets-engine requires (`evaluator`, `mode`,
|
||||
`policy_package`, `policy_version`, `policy_package_digest`) from Access's
|
||||
published pin for the candidate release; these are not in the writer receipt.
|
||||
`public_key` is unpadded base64url, 43 characters. `public_fingerprint` is
|
||||
`sha256:` + hex SHA-256 of that ASCII string, not of the raw bytes. The founder
|
||||
delivers the file to the secrets-engine owner over an authenticated channel and
|
||||
signs the consumer trust file per `secrets-engine/docs/founder-admission.md`.
|
||||
|
||||
## 4. Delivery and signer start (founder go #3, Access-owned)
|
||||
|
||||
1. Access/GitOps applies the reviewed ESO projection (SA, SecretStore,
|
||||
ExternalSecret). Do not use client-side apply on Secrets.
|
||||
2. Check readiness with the safe helpers only:
|
||||
`scripts/eso_adoption_readiness.py` and
|
||||
`scripts/secret_annotation_maintenance.py` (inspect mode). Never run
|
||||
go-template or jsonpath against the Secret.
|
||||
3. Access restarts the single signer replica. Verify kid/source/image, a signed
|
||||
non-effect lifecycle allow and deny, and independent consumer verification
|
||||
before reopening protected consumers.
|
||||
|
||||
Negatives: unknown or old kid, wrong policy, tampered, expired or unsigned
|
||||
envelope, wrong caller and missing seed are all refused. No taskpilot enablement.
|
||||
|
|
@ -72,6 +72,14 @@ def parsed(raw):
|
|||
except Exception:raise Refused('invalid closed JSON input') from None
|
||||
|
||||
|
||||
def review_scope_digest(value):
|
||||
"""Owner reviews bind the exact action scope minus the reviews themselves and the
|
||||
invocation-time expiry. The 5..120s expiry stays enforced separately; binding it
|
||||
into the reviewed digest made five asynchronous reviews impossible to collect
|
||||
inside the attended window (2026-10-21 build-mode fix, close-down checklist)."""
|
||||
return digest(encoded({k:v for k,v in value.items() if k not in {'owner_reviews','expires_at'}}))
|
||||
|
||||
|
||||
def validate_admission(value):
|
||||
fields={'schema','action','operation_id','kid','expires_at','founder_entity_id','ccr_sha256','source_bundle','bindings',
|
||||
'producer_image','caller_binding','deployment_projection_sha256','authority','routing','owner_reviews',
|
||||
|
|
@ -93,7 +101,7 @@ def validate_admission(value):
|
|||
is_digest(review['approved_admission_sha256']) and type(review['approval_ref']) is str and
|
||||
0<len(review['approval_ref'])<=200,'exact external review required')
|
||||
# Dispositions bind a claim-free scope digest, avoiding self-referential JSON.
|
||||
scope={k:v for k,v in value.items() if k!='owner_reviews'};scope_digest=digest(encoded(scope))
|
||||
scope_digest=review_scope_digest(value)
|
||||
require(all(x['approved_admission_sha256']==scope_digest for x in reviews.values()),'owner review scope mismatch')
|
||||
require(type(value['source_bundle']) is dict and set(value['source_bundle'])==SOURCE_FILES and
|
||||
all(is_digest(x) for x in value['source_bundle'].values()),'exact execution source bundle required')
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ def native(bao_dev,tmp_path,monkeypatch):
|
|||
if value['action']=='recover' and value['original_execution'] is None:
|
||||
old=json.loads((directory/(c['operation_id']+'.json')).read_bytes())
|
||||
value['original_execution']={key:deepcopy(old[key]) for key in ['bindings','writer_sha256','source_ccr_sha256']}
|
||||
scope=m.digest(m.encoded({k:v for k,v in value.items() if k!='owner_reviews'}))
|
||||
scope=m.review_scope_digest(value)
|
||||
value['owner_reviews']={role:{'approved_admission_sha256':scope,'approval_ref':'synthetic-fixture-'+role} for role in m.REVIEWS}
|
||||
return value
|
||||
approve(c)
|
||||
|
|
@ -333,3 +333,14 @@ def test_exact_runtime_storage_owner_slot_replaces_conflated_role(native):
|
|||
with pytest.raises(Refused,match='distinct owner reviews'):
|
||||
m.validate_admission(extra)
|
||||
assert io.calls==[]
|
||||
|
||||
|
||||
def test_owner_reviews_survive_fresh_expiry_but_not_scope_change(native):
|
||||
c,io,directory,call,approve,source=native
|
||||
reviewed=m.review_scope_digest(c)
|
||||
c['expires_at']=(datetime.now(timezone.utc)+timedelta(seconds=90)).isoformat()
|
||||
assert m.review_scope_digest(c)==reviewed
|
||||
m.validate_admission(c)
|
||||
changed=deepcopy(c);changed['kid']='other-native-kid'
|
||||
assert m.review_scope_digest(changed)!=reviewed
|
||||
with pytest.raises(m.Refused):m.validate_admission(changed)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ status: blocked
|
|||
flavor: implementation
|
||||
owner: codex
|
||||
created: "2026-09-05"
|
||||
updated: "2026-10-13"
|
||||
updated: "2026-10-21"
|
||||
related:
|
||||
- RPF-WP-0032
|
||||
- RPF-WP-0033
|
||||
|
|
@ -1405,3 +1405,41 @@ eso-token-renewer stay unchanged. Exact CCR read grant and one-use custody write
|
|||
remain separate. Actual CCR/founder/entity/expiry/window/fence, native ESO/readback,
|
||||
independent Secrets public trust and Access/cluster runtime proofs remain gates.
|
||||
No authority/admission field changes; T12 remains progress.
|
||||
|
||||
|
||||
## Founder approval of the flex-auth envelope signing key custody scope (CCR-2026-0050)
|
||||
|
||||
```task
|
||||
id: RPF-WP-0035-T14
|
||||
status: wait
|
||||
priority: high
|
||||
needs_human: true
|
||||
depends_on: [RPF-WP-0035-T12]
|
||||
decision_id: 18731e84-a6ab-4ac5-bf0e-7e7c3a9c4508
|
||||
```
|
||||
|
||||
Human gate for custody route `flex-auth-decision-envelope-signing-key`. The
|
||||
founder resolves hub decision `18731e84-a6ab-4ac5-bf0e-7e7c3a9c4508`, which
|
||||
states the exact new scope: KV document
|
||||
`platform/data/workloads/flex-auth/envelope-signing` (seed, public key, kid;
|
||||
CAS-required, max 2 versions), one attended CAS0 bootstrap with kid
|
||||
`flex-auth-lifecycle-20261016-r1`, read policy
|
||||
`workload-kv-read-flex-auth-envelope-signing` and Kubernetes role
|
||||
`external-secrets-flex-auth-envelope-signing` (SA `flex-auth-envelope-signing-eso`,
|
||||
namespace `flex-auth`, audience `openbao`, 15m). Approval is scope only; each
|
||||
live step in `docs/runbooks/flex-auth-envelope-signing-attended-creation.md`
|
||||
still needs the founder's go at the time.
|
||||
|
||||
2026-10-21 state: railiance-platform-owner approved (runbook review);
|
||||
secrets-engine-owner approved with two receipt conditions (hub message
|
||||
e73c9ffc, recorded in the CCR); access-engine-owner disposition awaited;
|
||||
cluster-runtime-storage-owner (railiance-cluster) review requested in hub
|
||||
message f8b4b229. The warden routing defect from 2026-10-16 no longer
|
||||
reproduces (`docs/evidence/2026-10-21-flex-auth-signer-warden-route.json`).
|
||||
The native adapter's owner-review digest no longer binds `expires_at`, so
|
||||
reviews can be given ahead of the 120 s attended window; the expiry check is
|
||||
unchanged. Recorded as a build-mode change in the-custodian
|
||||
`docs/security-close-down-checklist.md`. Nothing generated, written or applied.
|
||||
|
||||
Done when: the decision is resolved, `sync-decision` copies it into the CCR,
|
||||
all five dispositions are recorded, and the runbook preconditions hold.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue