docs(custody): record attended KeyCape first-provision authority proof
Assistant: codex Assistant-Model: gpt-5.6-luna Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
a0bbae842c
commit
a94d06dbcf
5 changed files with 204 additions and 0 deletions
|
|
@ -14,6 +14,7 @@
|
|||
| workplan | RPF-WP-0029 | blocked | — | workplans/RPF-WP-0029-backup-credential-default-removal.md |
|
||||
| workplan | RPF-WP-0035 | blocked | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| workplan | RPF-WP-0036 | blocked | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| workplan | RPF-WP-0038 | active | — | workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md |
|
||||
| task | RPF-WP-0015-T01 | done | — | workplans/RPF-WP-0015-audit-core-custody-and-recovery-coordination.md |
|
||||
| task | RPF-WP-0015-T02 | wait | — | workplans/RPF-WP-0015-audit-core-custody-and-recovery-coordination.md |
|
||||
| task | RPF-WP-0015-T03 | wait | — | workplans/RPF-WP-0015-audit-core-custody-and-recovery-coordination.md |
|
||||
|
|
@ -34,6 +35,7 @@
|
|||
| task | RPF-WP-0035-T02 | wait | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T03 | wait | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T04 | done | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0035-T05 | 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 |
|
||||
|
|
@ -41,3 +43,7 @@
|
|||
| task | RPF-WP-0036-T05 | done | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T06 | wait | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T07 | done | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0038-T01 | done | — | workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md |
|
||||
| task | RPF-WP-0038-T02 | done | — | workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md |
|
||||
| task | RPF-WP-0038-T03 | done | — | workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md |
|
||||
| task | RPF-WP-0038-T04 | progress | — | workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md |
|
||||
|
|
|
|||
|
|
@ -156,3 +156,25 @@ platform side; the window needs roughly 60–90 minutes with both owners present
|
|||
(KEY-WP-0009-T04) or to RPF-WP-0035-T02's service-JWT lane.
|
||||
- No approval for `approval:consume` on the operator client, now or by later
|
||||
scope edit. Adding it is a new lane decision.
|
||||
|
||||
|
||||
## Attended authority return — 2026-09-08
|
||||
|
||||
The metadata-only first-provision preflight is now observed on the exact six
|
||||
policy/role/data paths: create/update capabilities are present. The successful
|
||||
session self-revoked and its helper was removed. This settles the availability
|
||||
of the named operator authority, not the CCR approvals or the upstream issuer
|
||||
precondition. See
|
||||
[the receipt](../evidence/2026-09-08-keycape-approval-custody-preflight.json).
|
||||
|
||||
For a repeat after a role/policy change, use the existing contained WSL wrapper:
|
||||
|
||||
```bash
|
||||
python3 scripts/openbao-attended-exec.py -- /usr/bin/python3 \
|
||||
scripts/keycape-approval-custody-preflight.py --receipt /tmp/<new-private-receipt>.json
|
||||
```
|
||||
|
||||
Use an absolute path to the owner command if invoking from another directory.
|
||||
It emits no output or values; inspect its allowlisted capability metadata only
|
||||
after Warden has completed revocation and cleanup. No custody activation or
|
||||
approval is performed by this preflight.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"observed_at": "2026-09-08T20:36:47.042499+00:00",
|
||||
"requests": [
|
||||
"CCR-2026-0017",
|
||||
"CCR-2026-0018"
|
||||
],
|
||||
"operation": "capabilities-self only",
|
||||
"credential_data_read": false,
|
||||
"metadata_applied": false,
|
||||
"custody_activated": false,
|
||||
"upstream_issuer_proven": false,
|
||||
"status": "observed",
|
||||
"capabilities": {
|
||||
"sys/policies/acl/workload-kv-read-keycape-secrets-engine-approval": [
|
||||
"create",
|
||||
"delete",
|
||||
"list",
|
||||
"read",
|
||||
"sudo",
|
||||
"update"
|
||||
],
|
||||
"sys/policies/acl/workload-kv-read-keycape-approval-engine-operator": [
|
||||
"create",
|
||||
"delete",
|
||||
"list",
|
||||
"read",
|
||||
"sudo",
|
||||
"update"
|
||||
],
|
||||
"auth/kubernetes/role/external-secrets-keycape-secrets-engine-approval": [
|
||||
"create",
|
||||
"delete",
|
||||
"list",
|
||||
"read",
|
||||
"sudo",
|
||||
"update"
|
||||
],
|
||||
"auth/kubernetes/role/external-secrets-keycape-approval-engine-operator": [
|
||||
"create",
|
||||
"delete",
|
||||
"list",
|
||||
"read",
|
||||
"sudo",
|
||||
"update"
|
||||
],
|
||||
"platform/data/workloads/secrets-engine/approval-client": [
|
||||
"create",
|
||||
"delete",
|
||||
"list",
|
||||
"read",
|
||||
"update"
|
||||
],
|
||||
"platform/data/workloads/approval-engine/operator-client": [
|
||||
"create",
|
||||
"delete",
|
||||
"list",
|
||||
"read",
|
||||
"update"
|
||||
]
|
||||
},
|
||||
"required_metadata_capabilities_present": true,
|
||||
"paths_verified": 6,
|
||||
"login_lane": "openbao-platform-admin-login",
|
||||
"launcher": "scripts/openbao-attended-exec.py",
|
||||
"command": "scripts/keycape-approval-custody-preflight.py --receipt <new-private-file>",
|
||||
"wrapper_exit": 0,
|
||||
"session_self_revoked": true,
|
||||
"helper_root_removed": true,
|
||||
"attempt_notes": [
|
||||
{
|
||||
"attempt": 1,
|
||||
"result": "direct launcher unavailable; no child handoff; revocation unconfirmed",
|
||||
"credential_data_read": false
|
||||
},
|
||||
{
|
||||
"attempt": 2,
|
||||
"result": "owner wrapper login/self-revocation succeeded; capability command rejected unsupported multiple-path syntax",
|
||||
"credential_data_read": false
|
||||
},
|
||||
{
|
||||
"attempt": 3,
|
||||
"result": "six single-path capability queries succeeded; session self-revoked and helper removed",
|
||||
"credential_data_read": false
|
||||
}
|
||||
]
|
||||
}
|
||||
64
scripts/keycape-approval-custody-preflight.py
Normal file
64
scripts/keycape-approval-custody-preflight.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
"""Read-only, silent owner preflight inside Warden's attended login envelope.
|
||||
|
||||
Queries only token capabilities for the exact two reviewed CCR targets. Reads
|
||||
no secret data, applies no metadata, and does not record an approval. Warden
|
||||
owns the temporary token helper and self-revokes after this command returns.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
PATHS = [
|
||||
'sys/policies/acl/workload-kv-read-keycape-secrets-engine-approval',
|
||||
'sys/policies/acl/workload-kv-read-keycape-approval-engine-operator',
|
||||
'auth/kubernetes/role/external-secrets-keycape-secrets-engine-approval',
|
||||
'auth/kubernetes/role/external-secrets-keycape-approval-engine-operator',
|
||||
'platform/data/workloads/secrets-engine/approval-client',
|
||||
'platform/data/workloads/approval-engine/operator-client',
|
||||
]
|
||||
ALLOWED = {'create', 'read', 'update', 'patch', 'delete', 'list', 'sudo', 'deny', 'root'}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--receipt", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
receipt = {'observed_at': datetime.now(timezone.utc).isoformat(),
|
||||
'requests': ['CCR-2026-0017', 'CCR-2026-0018'],
|
||||
'operation': 'capabilities-self only', 'credential_data_read': False,
|
||||
'metadata_applied': False, 'custody_activated': False,
|
||||
'upstream_issuer_proven': False}
|
||||
caps = {}
|
||||
for path in PATHS:
|
||||
# This installed CLI accepts one PATH. Supplying several positional
|
||||
# arguments selects a different TOKEN/PATH form or refuses the call.
|
||||
result = subprocess.run(['bao', 'token', 'capabilities', '-format=json', path],
|
||||
capture_output=True, text=True, timeout=20)
|
||||
if result.returncode:
|
||||
receipt['status'] = 'capability-query-failed'
|
||||
break
|
||||
payload = json.loads(result.stdout)
|
||||
values = payload if isinstance(payload, list) else payload.get('capabilities')
|
||||
if not isinstance(values, list) or any(v not in ALLOWED for v in values):
|
||||
raise ValueError('unexpected capability response shape')
|
||||
caps[path] = sorted(set(values))
|
||||
else:
|
||||
receipt['status'] = 'observed'
|
||||
receipt['capabilities'] = caps
|
||||
receipt['required_metadata_capabilities_present'] = all(
|
||||
{'create', 'update'}.issubset(values) for values in caps.values())
|
||||
receipt['paths_verified'] = len(caps)
|
||||
fd = os.open(args.receipt, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
||||
with os.fdopen(fd, 'w') as stream:
|
||||
json.dump(receipt, stream, indent=2)
|
||||
stream.write('\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
raise SystemExit(1) from None
|
||||
|
|
@ -147,6 +147,7 @@ closure: `history/2026-09-05-preflight-signing-activation-complete.md`.
|
|||
id: RPF-WP-0035-T05
|
||||
status: wait
|
||||
priority: high
|
||||
state_hub_task_id: "e15d62c9-e5da-5721-a135-87c050f7851c"
|
||||
```
|
||||
|
||||
Answers KEY-WP-0013-T02 (State Hub message
|
||||
|
|
@ -194,3 +195,28 @@ and access-engine Check (SECRETS-WP-0007-T04). Do not carry forward the old loca
|
|||
stub as a blocker. T02 still needs the accepted service issuer/JWKS, claims,
|
||||
audience and consumer binding. T03 still needs confirmed operator group/tenant
|
||||
and consumer semantics; T04 is already complete. No new owner acceptance inferred.
|
||||
|
||||
|
||||
### 2026-09-08 attended capability preflight
|
||||
|
||||
HFACT-WP-0001's continued execution verified the existing first-provision
|
||||
front door without provisioning anything. `warden plan` selected
|
||||
`openbao-platform-admin-login` / founder_required / one oidc_login. The native
|
||||
`scripts/openbao-attended-exec.py` supplied the existing WSL browser launcher;
|
||||
a direct attempt had no launcher and failed before handoff. Its first revocation
|
||||
result was unconfirmed and is preserved in the receipt rather than silently
|
||||
reclassified. The two subsequent contained sessions completed self-revocation
|
||||
and helper cleanup.
|
||||
|
||||
`scripts/keycape-approval-custody-preflight.py --receipt <new-private-file>` is
|
||||
a silent, read-only command for that envelope. The installed Bao CLI supports
|
||||
one path per `token capabilities` call; the final run used six single-path calls.
|
||||
Create/update authority is present on both exact policy paths, both Kubernetes
|
||||
auth-role paths and both KV data paths from CCR-2026-0017/0018. This is authority
|
||||
metadata, not a secret-data read or policy/role/KV mutation. Receipt:
|
||||
`docs/evidence/2026-09-08-keycape-approval-custody-preflight.json`.
|
||||
|
||||
T05 remains wait: both CCRs are still proposed, the actual upstream ID-token
|
||||
issuer precondition remains open, and no verifier-side credential is provisioned.
|
||||
Client-side retrieval and audit-sender custody are still separate owner returns.
|
||||
The capability receipt is not a review approval or service readiness proof.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue