Harden secret provisioning and lifecycle controls
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0217e-8c4c-7383-be6b-f50a6e485306
This commit is contained in:
tegwick 2026-08-23 12:05:58 +02:00
parent 0617923ff1
commit 3a1bd4f1c8
23 changed files with 1369 additions and 162 deletions

View file

@ -48,25 +48,24 @@ provider, credential broker, or general secrets API.
- Imports one declared field from a mode-0600 file outside Git worktrees.
- Generates random values only for non-production lanes.
- Keeps values out of CLI output and evidence records.
This is a bootstrap/pilot primitive, not a safe general updater for existing
multi-field production paths. The current adapter invokes `bao kv put` with one
field and can replace sibling fields at that KV path; it also places the value
in the local `bao` subprocess argument vector. Do not use it for the admitted
shared multi-field lanes until merge-safe, non-argv provisioning is implemented.
- Uses a CAS-aware create/patch primitive. Secret data is passed through a
mode-0600 temporary JSON input reference that is removed in a `finally` path,
never as a raw subprocess argument. Existing-path updates preserve unmentioned
sibling fields and stale-version writes fail closed.
### Verification
- KV positive verification logs in through the lane AppRole and reports whether
one declared field is present, without printing the field value.
- KV positive verification logs in through the lane AppRole and reports field
presence without printing values. With no `--field`, it checks every declared
field; an explicit `--field` narrows the check.
- KV negative verification checks that a fixed invalid token cannot read the
path.
- Auth-capability verification checks the AppRole token's capabilities on exact
allowlisted and denial-probe paths.
These are bounded policy/presence probes. They do not yet prove denial for a
real unrelated workload identity, validate every field by default, exercise a
provider operation, or produce OpenBao audit-request correlation.
real unrelated workload identity, exercise a provider operation, or produce
OpenBao audit-request correlation.
### Exec-time delivery
@ -82,8 +81,10 @@ provider operation, or produce OpenBao audit-request correlation.
The OpenBao KV response is parsed in the parent process, so every field stored
at the path crosses that process boundary even though only the selected field is
injected. Scoped AppRole tokens rely on configured TTL/use limits; exec and
verification do not explicitly revoke them after use.
injected. Exec and verification use scoped AppRole sessions that explicitly
self-revoke in a `finally` path. Non-secret evidence contains only an accessor
fingerprint and establishment/revocation outcome; TTL/use limits remain cleanup
backstops.
### Auth-capability handoff
@ -100,24 +101,34 @@ cannot be recovered through that AppRole.
### Routing and evidence
- `route` returns a non-secret pointer containing lane ownership, decision
status, metadata/value-presence booleans, readiness, and a safe next command.
status, metadata/value-presence booleans, missing declared field names,
readiness, and a safe next command. Every declared field must be present.
- Records scrubbed local JSONL evidence and posts a minimal State Hub progress
event on a best-effort basis.
- Keeps OpenBao audit logs as the backend source of truth.
Route readiness checks only the first declared KV field, and State Hub evidence
delivery is not durable or transactional. Treat route output as operational
guidance, not complete attestation for multi-field or high-risk lanes.
State Hub evidence delivery is not durable or transactional, and route does not
replace authorization or unrelated-identity denial evidence. Treat route output
as operational guidance, not complete attestation for high-risk lanes.
### Revocation currently available
- For `auth-capability` lanes, live `revoke` deletes the AppRole and policy.
- For KV lanes, live `revoke` deletes all KV metadata/versions at the path.
- For engine-managed native auth, live `revoke` deletes the AppRole and policy.
- For KV lanes, ordinary revoke explicitly preserves all KV metadata/versions.
- Externally managed delivery auth and workload delivery are reported as
preserved and are not mutated.
- `lifecycle suspend` removes only the managed AppRole and preserves its policy
for reviewed re-apply.
- `lifecycle deactivate` removes managed native AppRole/policy objects while
preserving KV custody.
- `lifecycle destroy --dry-run` renders managed-auth removal plus irreversible
KV metadata deletion. Live destroy is currently disabled even with exact
catalog-id confirmation; it will remain closed until the canonical
exact-action approval contract in `SECRETS-WP-0007-T04` is enforced.
KV revoke is destructive decommissioning, not soft deactivation: it currently
leaves the KV lane's consumer AppRole and policy in place. There is no general
lease/accessor revoke, rotation command, compromised state, or reversible lane
state machine.
These operations do not manage external workload delivery. There is currently
no general lease/accessor operator command, rotation command, compromised state,
or persistent/reversible lane state machine.
## CLI Surface
@ -133,6 +144,7 @@ secrets-engine exec
secrets-engine policy publication
secrets-engine route
secrets-engine revoke [--dry-run]
secrets-engine lifecycle suspend|deactivate|destroy
```
The implemented exec adapters are `exec-env` and `npm-config`. `read-check` is
@ -156,9 +168,10 @@ verification, `approle-login` is auth-capability handoff metadata, and
- A service API, daemon, UI, queue, scheduler, or remote multi-user service.
- OpenBao OIDC/service-auth login for steady-state secrets-engine operation.
- Native `exec-file` or response-wrapped delivery.
- Merge-safe multi-field KV updates or provider-side rotation.
- First-class rotate, compromise, suspend, reactivate, lease-status, or audit
report commands.
- Provider-side rotation or coordinated multi-consumer rollout.
- First-class rotate, compromise, reactivate, lease-status, or audit report
commands; lifecycle operations currently execute plans without persistent
lane state.
- Dual-control enforcement beyond accepting the catalog label.
- Direct flex-auth evaluation, claim validation, or identity authentication.
- Runtime tenancy isolation; `org`, `repo`, consumers, and stages are catalog
@ -194,9 +207,10 @@ Canonical boundary:
for a new production auth surface.
- Never mutate an existing shared mount or replace workload delivery by
implication.
- Never use current single-field provisioning on a shared multi-field path.
- Never call KV `revoke` unless destructive deletion of all path versions is the
explicitly approved intent.
- Never add KV destruction back to ordinary `revoke`; irreversible custody
destruction requires `lifecycle destroy`, exact confirmation, and a distinct
approved action. The live path remains disabled until that approval contract
exists.
- Keep bootstrap and handoff material outside repositories with mode 0600 and
explicit expiry/revocation handling.
@ -222,8 +236,9 @@ keywords: [secrets, openbao, policy, approle, catalog, decision, stage, least-pr
type: security
title: AppRole-scoped exec delivery
description: Fetches one declared KV field through a lane AppRole and injects it into a child
process using exec-env or a temporary npm config, with output redaction and cleanup. This is
CLI-local delivery; exec-file, wrapping, service delivery, and explicit token revocation are absent.
process using exec-env or a temporary npm config, with output redaction, explicit scoped-token
self-revocation, and non-secret cleanup evidence. This is CLI-local delivery; exec-file, wrapping,
and service delivery are absent.
keywords: [secrets, delivery, exec, npm, injection, redaction, openbao]
```
@ -239,6 +254,7 @@ keywords: [openbao, approle, auth-capability, handoff, least-privilege]
type: governance
title: Non-secret routing and evidence pointers
description: Reports decision/readiness metadata and records scrubbed local and best-effort State Hub
evidence without returning secret values. It is not a durable audit store or complete multi-field attestation.
evidence without returning secret values. Readiness covers every declared field, but this is not a
durable audit store or a real-unrelated-identity denial attestation.
keywords: [routing, evidence, state-hub, audit, secrets]
```