Add named engine auth and accessor-file session revoke
Select service-jwt, bootstrap, or env exclusively: JWT login uses a JSON file, self-revokes, and never falls back to bootstrap or BAO_TOKEN. The platform JWT mount/role is still unpublished, so auto keeps named bootstrap/env providers. session revoke --accessor-file revokes an already-issued token with fingerprint-only evidence. Production remains fail-closed. Assistant: grok Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
This commit is contained in:
parent
a94003de4f
commit
3abee434df
18 changed files with 698 additions and 135 deletions
|
|
@ -34,11 +34,15 @@ secrets-engine --version
|
|||
| Var | Default | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `BAO_ADDR` | `http://127.0.0.1:8200` | OpenBao address |
|
||||
| `BAO_TOKEN` | _(unset)_ | OpenBao token (or use `--bootstrap-token-file`) |
|
||||
| `BAO_TOKEN` | _(unset)_ | Named `env` OpenBao token; never a fallback from `service-jwt` |
|
||||
| `SECRETS_ENGINE_HUB_URL` | `http://127.0.0.1:8000` | State Hub for decisions + evidence (empty to disable) |
|
||||
| `SECRETS_ENGINE_CATALOG` | `./catalog` | catalog directory |
|
||||
| `SECRETS_ENGINE_EVIDENCE` | `./.evidence` | local non-secret evidence log |
|
||||
| `SECRETS_ENGINE_UNSAFE_DEMO` | _(unset)_ | allow a prod-labeled lane only when Hub is disabled and OpenBao is loopback; throwaway demos only |
|
||||
| `SECRETS_ENGINE_KEYCAPE_TOKEN_URL` | _(unset)_ | KeyCape token endpoint for `service-jwt` |
|
||||
| `SECRETS_ENGINE_KEYCAPE_ISSUER` | _(unset)_ | KeyCape issuer; must match the JWT login contract |
|
||||
| `SECRETS_ENGINE_KEYCAPE_CLIENT_SECRET_FILE` | _(unset)_ | mode-0600 out-of-repo client secret |
|
||||
| `SECRETS_ENGINE_OPENBAO_JWT_LOGIN` | _(unset)_ | platform JWT mount/role contract YAML |
|
||||
|
||||
## Commands
|
||||
|
||||
|
|
@ -55,6 +59,7 @@ secrets-engine exec --catalog <catalog-id> [--field NAME] [--mode auto|npm-confi
|
|||
secrets-engine policy publication <catalog-id>
|
||||
secrets-engine route <catalog-id> [--json]
|
||||
secrets-engine revoke <catalog-id> [--dry-run]
|
||||
secrets-engine session revoke --accessor-file F [--stage stage]
|
||||
secrets-engine lifecycle suspend <catalog-id> [--dry-run]
|
||||
secrets-engine lifecycle deactivate <catalog-id> [--dry-run]
|
||||
secrets-engine lifecycle destroy <catalog-id> [--dry-run] [--confirm-destroy <catalog-id>]
|
||||
|
|
|
|||
|
|
@ -34,11 +34,15 @@ contents in this repo.
|
|||
- Implemented consumer scaffold: exact KeyCape client-credentials exchange,
|
||||
claim/lifetime preflight, strict client-secret file input, renewal boundary,
|
||||
and no implicit fallback.
|
||||
- Implemented named providers (`service-jwt`, `bootstrap`, `env`) with no
|
||||
JWT→bootstrap/env fallback. JWT login uses a JSON file, never argv, and
|
||||
self-revokes the issued OpenBao token.
|
||||
- Remaining: railiance-platform stands up the exact-bound OpenBao JWT auth
|
||||
mount/role and publishes its non-secret connection contract.
|
||||
- secrets-engine logs in via that method instead of reading a token file.
|
||||
- Remove `--bootstrap-token-file` from the steady-state path (keep only for true
|
||||
break-glass, heavily audited).
|
||||
mount/role and publishes its non-secret connection contract
|
||||
(`SECRETS_ENGINE_OPENBAO_JWT_LOGIN`). Until then `--auth service-jwt`
|
||||
fail-closes and `--auth auto` keeps named bootstrap/env providers.
|
||||
- `--bootstrap-token-file` is a named break-glass provider with distinct
|
||||
evidence, not an implicit fallback.
|
||||
|
||||
## H2 — Response-wrapped handoff
|
||||
|
||||
|
|
@ -67,9 +71,10 @@ contents in this repo.
|
|||
## H4a — Known-accessor operator command
|
||||
|
||||
- Delivery sessions already self-revoke in `finally` (`SECRETS-WP-0007-T05`).
|
||||
- Residual from T03: no general CLI to revoke an already-issued token or
|
||||
lease by a non-secret accessor the operator already holds.
|
||||
- Do not print accessors. Prefer fingerprint-only evidence.
|
||||
- Implemented: `secrets-engine session revoke --accessor-file F` reads a
|
||||
mode-0600 out-of-repo accessor, calls `token revoke -accessor`, and records
|
||||
only a fingerprint. Production remains fail-closed. Lease-id revoke is still
|
||||
outstanding.
|
||||
|
||||
## H5 — Audit report command
|
||||
|
||||
|
|
|
|||
23
docs/openbao-jwt-login.md
Normal file
23
docs/openbao-jwt-login.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# OpenBao JWT login contract (engine consumer)
|
||||
|
||||
Steady-state engine authentication is the reviewed KeyCape
|
||||
`secrets-engine-openbao` identity plus a **platform-owned** OpenBao JWT auth
|
||||
mount and exact-bound role. This repository does not invent that mount.
|
||||
|
||||
Point `SECRETS_ENGINE_OPENBAO_JWT_LOGIN` at a mode-normal YAML file outside
|
||||
the need to hold a standing OpenBao token:
|
||||
|
||||
```yaml
|
||||
mount: jwt
|
||||
role: secrets-engine
|
||||
bound_issuer: https://<keycape-issuer>
|
||||
```
|
||||
|
||||
`bound_issuer` must equal `SECRETS_ENGINE_KEYCAPE_ISSUER`. The JWT is sent
|
||||
through a temporary JSON file, never argv. The resulting OpenBao token is
|
||||
revoked at the end of the command (`token revoke -self`). Evidence records
|
||||
the provider name and an accessor fingerprint only.
|
||||
|
||||
Until railiance-platform publishes that file, `--auth auto` keeps the named
|
||||
bootstrap-file and `BAO_TOKEN` providers. `--auth service-jwt` fail-closes.
|
||||
A service-jwt selection never reads `--bootstrap-token-file` or `BAO_TOKEN`.
|
||||
|
|
@ -17,12 +17,17 @@ 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.
|
||||
|
||||
This is a scaffold, not a live OpenBao authentication path. JWT payload parsing
|
||||
does not prove a signature. railiance-platform still owns the exact OpenBao JWT
|
||||
auth mount/role, issuer keys, claim bindings, token policy, TTL/use limits, and
|
||||
cryptographic verification. Until that contract is materialized, the provider
|
||||
is not selected by the CLI and bootstrap/AppRole behavior is not used as an
|
||||
implicit fallback.
|
||||
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).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue