Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1046b-5629-7f52-badd-f718eadb6042
152 lines
8.7 KiB
Markdown
152 lines
8.7 KiB
Markdown
# Secrets-engine service JWT login
|
|
|
|
Status: proposed, not provisioned. Owner: railiance-platform, RPF-WP-0035-T02 (design origin 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; issuer `https://kc.coulomb.social`, JWKS `https://kc.coulomb.social/jwks`; public discovery rechecked 2026-09-27; live registration remains unverified |
|
|
| Role type / user claim | `jwt` / `sub` |
|
|
| Audience | `secrets-engine-openbao` |
|
|
| Subject | `service:secrets-engine` |
|
|
| Bound claims, string matching | `principal_type=service`, `tenant=tenant:platform`, 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):
|
|
|
|
```yaml
|
|
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](https://openbao.org/docs/auth/jwt/) describes
|
|
signature verification and claim binding; its [role API](https://openbao.org/docs/2.4.x/api/auth/jwt/)
|
|
defines token TTL/use limits and the explicit maximum. These are mechanism
|
|
references, not evidence of this cluster's installed configuration.
|
|
|
|
## Prepared source return — 2026-09-27
|
|
|
|
The exact proposed bundle is `openbao/auth/keycape-services-config.json`,
|
|
`openbao/auth/secrets-engine-jwt-role.json` and
|
|
`openbao/policies/secrets-engine-login-self.hcl`. These files are non-secret
|
|
inputs for the existing attended platform procedure, not an applied receipt.
|
|
The discovery document advertises `/token` and `client_credentials`.
|
|
|
|
The operator clarified that platform infrastructure belongs to tenant zero,
|
|
`tenant:platform`. Coulomb is a workload tenant; its DNS domain is not ownership.
|
|
The former `tenant:coulomb` service registration and consumer preflight were
|
|
consistent but incorrectly scoped. The corrected source uses `tenant:platform`
|
|
for both OpenBao infrastructure clients and the existing approval clients.
|
|
|
|
Before writing: survey mounts/roles, confirm exact live client registration and
|
|
protected client-side custody, review this bundle and obtain the scoped attended
|
|
window via `warden access openbao-platform-admin-login --exec -- <reviewed-command>`.
|
|
Do not execute a placeholder command. The reviewed child must install only this
|
|
isolated mount/config, self policy and role, compare effective policy metadata,
|
|
then perform the positive/negative/expiry/use-limit/revocation checks above.
|
|
Do not print login responses. Publish the consumer contract only after those
|
|
checks pass. A conflicting existing mount/role requires review, not overwrite.
|
|
No service-client secret is created, moved or requested by this source return.
|
|
|
|
## Gate check — 2026-10-03 (CUST-WP-0075)
|
|
|
|
Still proposed. SECRETS-WP-0007-T04 is done (2026-09-27), so the gate named
|
|
above is open, but the "before writing" preconditions are not: KeyCape has not
|
|
claimed a live registration of `secrets-engine-openbao`, and its client-credential
|
|
custody has no owning task (KeyCape contract: "a separate approved custody
|
|
action"). No reviewed child is written. RPF-WP-0035-T02 waits on key-cape naming
|
|
that task.
|
|
|
|
## Owner return and blocked dependency contract — 2026-10-04
|
|
|
|
KEY-WP-0037-T02 now owns separately approved protected custody, T03 the actual
|
|
deployment-owned registration operation, and T04 native issuance evidence.
|
|
`key-cape/docs/secrets-engine-openbao-owner-packet.md` supplies the candidate
|
|
issuer path and exact registration contract. Platform prepared proposed
|
|
CCR-2026-0033 and exact-path issuer reader policy/auth/ESO/receipt artifacts;
|
|
source generation does not allocate a value or establish registration.
|
|
|
|
secrets-engine must accept the actual consumer host/file owner/path, mode-0600
|
|
delivery mechanism and rotation/revocation ownership before the bounded custody
|
|
child is finalized. Issuer-side ESO is a separate copy. An owner source acceptance
|
|
receipt, independent of full live service login completion, supplies this gate.
|
|
KeyCape's current exact-primary receipt remains pending scoped repair of an
|
|
existing grandfathered ADHOC task identity. Do not infer synchronization from
|
|
its source contract or local managed IDs.
|
|
|
|
`docs/provisioning-windows/2026-10-04-1000/dependency-requirements.md` names all
|
|
source/acceptance/reopen boundaries. RPF-WP-0035-T02 remains wait; its workplan
|
|
is blocked on those real dependencies and separate attended execution approval.
|