Adds the consumer custody packet for KEY-WP-0037-T02 / RPF-WP-0035-T02, strict value-free client-secret file checks with a check-secret-file CLI, synthetic tests, and SECRETS-WP-0012 tracking founder decisions and the attended delivery as needs_human wait tasks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 132360@bnt-lap001 Assistant-Session: 769b1afd-4330-4c86-96b2-e510e26db42b
48 lines
2.6 KiB
Markdown
48 lines
2.6 KiB
Markdown
# KeyCape service-auth consumer boundary
|
||
|
||
secrets-engine now implements the consumer half of KeyCape's accepted
|
||
`secrets-engine-openbao` service-auth contract. It performs one explicit HTTPS
|
||
`client_credentials` exchange, keeps the resulting JWT in memory, and validates
|
||
the non-cryptographic contract before any future OpenBao login:
|
||
|
||
- subject `service:secrets-engine`, audience/client `secrets-engine-openbao`;
|
||
- service principal in `tenant:platform` (platform infrastructure, tenant zero), role `secrets-engine`;
|
||
- exact `openbao:login` scope and KeyCape AAL1 client-secret assurance;
|
||
- RS256 declaration, bounded issue/expiry timestamps, maximum 15-minute life,
|
||
and renewal when no more than three minutes remain;
|
||
- no ID token, refresh token, implicit retry provider, or fallback identity.
|
||
|
||
The confidential-client secret must be an explicitly selected mode-0600 file
|
||
outside every Git worktree. It is sent with HTTP Basic authentication and never
|
||
placed in a request body, command argument, evidence record, or object
|
||
representation.
|
||
|
||
Since 2026-10-06 the file must also be a canonical regular file (no symlink
|
||
component) owned by the running user, in a parent directory owned by that
|
||
user with mode 0700, and hold exactly one token.
|
||
`secrets-engine service-auth check-secret-file [--path P] [--json]` reports
|
||
those checks without the value. Consumer host, path, delivery and lifecycle
|
||
coordinates: [keycape-openbao-consumer-custody.md](keycape-openbao-consumer-custody.md).
|
||
|
||
JWT payload parsing does not prove a signature. OpenBao must verify RS256
|
||
against the configured issuer before issuing a token. railiance-platform owns
|
||
the exact OpenBao JWT auth mount/role, issuer keys, claim bindings, token
|
||
policy, TTL/use limits, and cryptographic verification.
|
||
|
||
When `SECRETS_ENGINE_OPENBAO_JWT_LOGIN` names that contract, the CLI selects
|
||
`service-jwt` and logs in for one command, then self-revokes the OpenBao
|
||
token. Failure of that path never falls back to `--bootstrap-token-file`,
|
||
`BAO_TOKEN`, or AppRole. Until the contract is published, `--auth auto` keeps
|
||
those named providers and `--auth service-jwt` fail-closes. See
|
||
[openbao-jwt-login.md](openbao-jwt-login.md).
|
||
|
||
Canonical provider contract:
|
||
`key-cape/docs/openbao-service-auth-contract.md` (reviewed 2026-08-23).
|
||
|
||
## Approval identity is separate
|
||
|
||
[Approval service authentication](approval-service-auth.md) uses its own
|
||
client-secret input, resource audience, exact tenant:platform and per-request
|
||
read/consume scopes. Never put that credential into the OpenBao provider.
|
||
Both providers now validate KeyCape’s actual `level`/`methods` assurance shape;
|
||
the old `aal`/`method` fixture was incompatible with the issuer.
|