Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
5.5 KiB
Secrets-engine service JWT login
Status: proposed, not provisioned. Owner: railiance-platform, RPF-WP-0032.
Demand: State Hub message 38b47122-07eb-4a7f-a5df-13a38f50e110.
Contract and ownership
KeyCape's accepted provider contract is
../key-cape/docs/openbao-service-auth-contract.md. The consumer implementation
is ../secrets-engine/src/secrets_engine/engine_auth.py; the existing coding
agent role is openbao/auth/coding-agent-jwt-role.json. The service must have
its own role and identity. It must not acquire the coding-agent role or an
operator's policy set.
Propose an isolated JWT auth mount keycape-services, role
secrets-engine-openbao, and policy secrets-engine-login-self. Survey first:
if an equivalent service mount already exists, the owner may select it in the
approved contract instead. Do not reconfigure the browser netkingdom mount
or the coding-agent mount to introduce this service.
| Setting | Proposed value / evidence required |
|---|---|
| Verification | RS256 only; exact HTTPS issuer and approved discovery/JWKS URL, both pending KeyCape owner confirmation |
| Role type / user claim | jwt / sub |
| Audience | secrets-engine-openbao |
| Subject | service:secrets-engine |
| Bound claims, string matching | principal_type=service, tenant=tenant:coulomb, required roles=secrets-engine, scope=openbao:login |
| Token policy | secrets-engine-login-self only; no default policy |
| Token bounds | service token, TTL/max/explicit max 5m, 8 uses, no periodic token; budget must include cleanup |
| Logging | verbose OIDC logging disabled; no JWT claim dump or token/accessor in receipts |
The self policy permits only auth/token/lookup-self read,
sys/capabilities-self update, and auth/token/revoke-self update. These
explicit self endpoints are necessary because default policy is disabled.
No KV read, policy/auth mutation, SecretID minting, child-token creation or
renewal is granted. Verify the token's effective identity policies too: disabling
default policy alone does not prove that aliases/groups add no permissions.
This is an identity login contract. It is intentionally insufficient to apply
native lanes. ../secrets-engine/docs/native-lane-cutover.md still requires
canonical ActionAuthorization, successful approval-engine consume, scoped
attended production authority and consumer verification per lane. Granting this
service standing wildcard ACL/role-write privileges would let a raw OpenBao
token bypass those application checks. Any future execution entitlement needs
a separate reviewed CCR type and backend-enforced scope. The current
workload-kv-read schema cannot encode this JWT administrative authority.
Publication and custody
After live verification, publish a separate non-secret consumer file with exactly these fields (the template below is deliberately invalid until filled):
mount: keycape-services
role: secrets-engine-openbao
bound_issuer: null # required exact HTTPS KeyCape issuer; do not guess
Point SECRETS_ENGINE_OPENBAO_JWT_LOGIN only at the approved final file. The
consumer requires its issuer to equal SECRETS_ENGINE_KEYCAPE_ISSUER. The client
secret remains in the separately approved KeyCape client custody lane, mounted
as a protected file; the JWT exchange and OpenBao login remain in memory or
private temporary input with cleanup. This design does not establish that client
secret's live path or provision it. --auth service-jwt is the explicit pilot;
failure must never fall back to bootstrap/env authentication.
KeyCape bounds JWT lifetime to 15 minutes and provides no refresh token. OpenBao login is not a one-time consumption guarantee for that JWT: it may be replayed while valid. Disabling issuance does not recall already issued JWTs or OpenBao tokens. In an incident, disable the exact role/client and revoke issued service tokens through owner custody; do not disable a shared mount. Without active revocation, residual access can extend by the OpenBao token TTL after the last accepted JWT login. Renew by a fresh exchange; always self-revoke after use.
Approval and acceptance
KeyCape confirms issuer, verification endpoint, registration and claim types; platform approves the exact mount/config/role/policy and effective policy set; secrets-engine accepts the five-minute token/use budget and login-only scope. The installed OpenBao version must support the reviewed parameters. A metadata survey must show no conflicting role before any write.
Prove correct-service login, exact policy set, expiry/use exhaustion and cleanup. Reject wrong issuer/audience/subject/tenant/principal/role/scope, invalid or expired signatures, and coding-agent credentials. Prove KV read, policy write, SecretID issuance and child-token creation are denied. Separately prove a failed login never consults bootstrap/env providers. Retain only timestamps, public contract revision, capability outcomes and boolean cleanup evidence. First-lane apply remains gated on SECRETS-WP-0007-T04 and its own exact approval.
Rollback disables the role and revokes its tokens; removing an exclusively owned empty mount is a later review. Existing ESO lanes and interim proxies remain available. The login contract is withdrawn until verification is green.
OpenBao's JWT documentation describes signature verification and claim binding; its role API defines token TTL/use limits and the explicit maximum. These are mechanism references, not evidence of this cluster's installed configuration.