Add response-wrapped operator handoff
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

secrets-engine wrap writes a single-use OpenBao wrap token to a mode-0600
out-of-repo file and never prints it. KV reads and AppRole secret_ids are
wrapped with a 15m TTL cap. Unwrapped secret payloads fail closed.
Production wrap remains fail-closed.

Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
This commit is contained in:
tegwick 2026-09-02 08:12:42 +02:00
parent 2278cefbb3
commit afd1c8e593
12 changed files with 387 additions and 8 deletions

View file

@ -55,6 +55,7 @@ secrets-engine apply <ref> --stage <stage> [--dry-run] [--bootstrap-token-file F
secrets-engine provision <catalog-id> --stage <stage> --field NAME (--from-file F | --generate)
secrets-engine verify <catalog-id> [--field NAME] [--positive] [--negative] [--negative-token-file F]
secrets-engine handoff <catalog-id> --stage <stage> --role-id-file F --secret-id-file F
secrets-engine wrap <catalog-id> --out F [--ttl 15m]
secrets-engine exec --catalog <catalog-id> [--field NAME] [--mode auto|npm-config|exec-env] -- CMD...
secrets-engine policy publication <catalog-id>
secrets-engine route <catalog-id> [--json]
@ -80,6 +81,10 @@ local decision is accepted for a prod-labeled lane only with
`SECRETS_ENGINE_UNSAFE_DEMO=1`, an empty Hub URL, and loopback OpenBao; the demo
scripts set those three conditions themselves.
`wrap` writes a single-use OpenBao response-wrap token to `--out` (mode 0600,
outside Git) and never prints it. KV lanes wrap a path read; auth-capability
lanes wrap a secret_id. TTL max 15m. Production live wrap stays fail-closed.
`handoff` is for `kind: auth-capability` lanes such as `warden-sign`. It mints a
fresh AppRole `secret_id` and writes `role_id` plus `secret_id` to caller-chosen
mode-0600 files outside Git worktrees. It never prints the `secret_id`; use the