Prepare reviewed service JWT boundary verification and retain execution adoption gates
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
parent
443c2698c3
commit
4378ec1fc2
6 changed files with 551 additions and 7 deletions
|
|
@ -18,6 +18,12 @@ 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.
|
||||
railiance-platform published the exact consumer file on 2026-10-10 at
|
||||
`docs/contracts/secrets-engine-openbao-jwt-login.yaml` (mount `keycape-services`,
|
||||
role `secrets-engine-openbao`, issuer `https://kc.coulomb.social`). When configured,
|
||||
`--auth auto` selects service-jwt; without a contract it keeps named bootstrap/env
|
||||
providers. Explicit service-jwt fails closed when configuration is missing.
|
||||
The current service token is login-self-only and cannot perform protected lane
|
||||
operations. T06 also requires a reviewed task-scoped execution entitlement and
|
||||
functional steady-state adoption; see [final acceptance](service-jwt-final-acceptance.md).
|
||||
A service-jwt selection never reads `--bootstrap-token-file` or `BAO_TOKEN`.
|
||||
|
|
|
|||
|
|
@ -36,8 +36,10 @@ 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
|
||||
`BAO_TOKEN`, or AppRole. The platform contract was published 2026-10-10. Configured `--auth auto`
|
||||
selects service-jwt; without that configuration it keeps bootstrap/env. The
|
||||
current login-self-only token cannot perform protected lane operations;
|
||||
functional adoption and task-scoped execution entitlement remain T06. See
|
||||
[openbao-jwt-login.md](openbao-jwt-login.md).
|
||||
|
||||
Canonical provider contract:
|
||||
|
|
|
|||
111
docs/service-jwt-final-acceptance.md
Normal file
111
docs/service-jwt-final-acceptance.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# Service-JWT final acceptance — SECRETS-WP-0008-T06
|
||||
|
||||
Prepared 2026-10-11; source preparation only. T06 remains wait. This packet
|
||||
neither grants live authority nor provides owner acknowledgment.
|
||||
|
||||
## Delivered producer and consumer work
|
||||
|
||||
SECRETS-WP-0012 is finished: protected in-memory client-secret acquisition,
|
||||
operator cleanup, KeyCape exchange, service JWT login and service cleanup passed
|
||||
in `docs/evidence/2026-10-10-keycape-openbao-probe.json`. The platform applied
|
||||
CCR-2026-0038 on October 8 and published
|
||||
`railiance-platform/docs/contracts/secrets-engine-openbao-jwt-login.yaml` on
|
||||
October 10. Mount `keycape-services`, role `secrets-engine-openbao`, issuer
|
||||
`https://kc.coulomb.social` are published. An unpublished-mount or
|
||||
unprovisioned-registration wait is obsolete.
|
||||
|
||||
The consumer no-fallback receipt
|
||||
`docs/evidence/2026-10-10-service-jwt-no-fallback.json` proves synthetic selection
|
||||
and real Bao CLI header behavior against a loopback listener. It is not native
|
||||
claim rejection evidence. KEY-WP-0039-T01 is source acceptance done; T02 owns the
|
||||
attended actual negative-token session. RPF-WP-0035-T02 retains native claims,
|
||||
effective policy/capability denials, and MASON-WP-0009-T05 return.
|
||||
|
||||
WP0007 is six of seven complete with native per-lane adoption outstanding.
|
||||
WP0009 credential apply/verify/delivery/revocation passed in the September 27
|
||||
attended receipts, but its task cannot finish: held EUR 10 reservation still
|
||||
needs accounting reconciliation, replacement runtime admission and separate
|
||||
retry authority. These are existing live tasks; this packet closes neither.
|
||||
|
||||
## Executable missing identity-boundary check
|
||||
|
||||
`tools/verify_service_jwt_boundary.py` defaults to backend-free preparation.
|
||||
It checks exact applied CCR, published mount/role and issuer, client-secret-file
|
||||
refusal and exact guarded paths. Preparation cannot produce a passing native
|
||||
receipt. After explicit authorization for the attended metadata check, add
|
||||
`--execute` to the same command:
|
||||
|
||||
```bash
|
||||
env -u BAO_TOKEN -u VAULT_TOKEN -u SECRETS_ENGINE_KEYCAPE_CLIENT_SECRET_FILE \
|
||||
BAO_ADDR=http://127.0.0.1:18200 \
|
||||
SECRETS_ENGINE_KEYCAPE_TOKEN_URL=https://kc.coulomb.social/token \
|
||||
SECRETS_ENGINE_KEYCAPE_ISSUER=https://kc.coulomb.social \
|
||||
SECRETS_ENGINE_OPENBAO_JWT_LOGIN=/home/worsch/railiance-platform/docs/contracts/secrets-engine-openbao-jwt-login.yaml \
|
||||
uv run python tools/verify_service_jwt_boundary.py \
|
||||
--ccr /home/worsch/railiance-platform/credential-change-requests/CCR-2026-0038-secrets-engine-service-jwt-login.yaml
|
||||
```
|
||||
|
||||
Live mode uses existing attended custody and performs two service-token metadata
|
||||
requests: lookup-self and one batch capabilities-self. The batch checks both
|
||||
client-secret guarded paths, `sys/policies/acl/*`, `auth/*/role/*` and
|
||||
`auth/token/create`; it never reads their values or attempts writes. Cleanup
|
||||
runs even on failed verification. Two metadata calls reserve room for cleanup
|
||||
within the service token's eight-use budget. Passing requires exactly the
|
||||
self policy, no identity-policy additions, deny on every requested path and
|
||||
both operator and service revocation success. Output contains hashes, capability
|
||||
booleans and session fingerprints. No backend response/error body is printed.
|
||||
Transport fixes bind each request to the configured OpenBao origin, disable
|
||||
environment proxies and refuse all redirects including relative redirects.
|
||||
Only HTTP 200 application/json with a bounded 64 KiB body and object data is
|
||||
accepted. Errors and response bodies are suppressed. Session evidence is
|
||||
restricted to the contract whitelist with strict boolean types, the fixed
|
||||
source name, and twelve-hex session handles. Native acceptance requires every
|
||||
contract field (established, source, both fingerprints and attempted/succeeded
|
||||
cleanup flags), a normally returned cleanup call, and no verification failure.
|
||||
Stale true evidence cannot override a cleanup exception. HTTP JSON with an
|
||||
errors member is refused even when a data member also exists. Synthetic/local-loopback tests
|
||||
cover redirects, proxy environment, size/status/content/shape failures, absent
|
||||
responses, unknown exceptions and unknown evidence fields with cleanup.
|
||||
This does not prove expiry/use exhaustion, native claim negatives or adoption.
|
||||
Platform retains those native test obligations and owner review of this tool.
|
||||
|
||||
## Protected-operation adoption is a distinct missing contract
|
||||
|
||||
INTENT requires task-bounded authority and a functional Lifecycle API. The
|
||||
platform design explicitly says this login policy is insufficient for native
|
||||
lanes; future execution entitlement requires a separately reviewed CCR type and
|
||||
backend-enforced scope. No standing wildcard policy is accepted.
|
||||
|
||||
Actual CLI flow (`cli._require_lane_approval`, `_open_backend`, `cmd_apply`) is
|
||||
claim → validated PDP Check → approval CAS consume → select provider → OpenBao
|
||||
operation. `_open_backend` supplies the login-only service token directly.
|
||||
There is no per-action delegated grant or scoped backend exchange in that path.
|
||||
Consequently a service-jwt default flip would consume a real approval then fail
|
||||
the protected operation. Configured `auto` chooses service-jwt; unconfigured
|
||||
`auto` still chooses bootstrap/env. Neither selection proves steady-state
|
||||
adoption. Keep existing service policy and provider defaults until the execution
|
||||
contract exists; failed JWT never switches provider.
|
||||
|
||||
Founder/owner choice needed: retain login-self-only and implement a separately
|
||||
owned task-scoped delegation contract (recommended), or explicitly redesign
|
||||
backend execution mediation with platform enforcement. Both must preserve
|
||||
claim/PDP/CAS binding, exact action/lane/target/expiry/principal scope, failure
|
||||
closed, revocation and audit evidence; neither means granting broad standing
|
||||
ACLs. Retaining attended bootstrap/env as a transition leaves T06 open.
|
||||
|
||||
Concrete missing owner obligation: secrets-engine and railiance-platform must
|
||||
agree the execution entitlement's owner and CCR schema, implementation endpoint,
|
||||
backend policy enforcement, exact request binding, TTL/use budget and revocation,
|
||||
then wire it after successful consume. KeyCape supplies identity, not authority.
|
||||
Existing native AppRole delivery sessions are short-lived workload read sessions,
|
||||
not an engine administrative entitlement. Existing native lane cutover requires
|
||||
scoped attended platform authority but does not implement this exchange.
|
||||
|
||||
T06 closes only after native KEY39/CCR negative/expiry/use/cleanup evidence and
|
||||
MASON return, a reviewed implemented execution entitlement, and a selected real
|
||||
protected action through service identity plus delegated authority: exact bound
|
||||
PDP/CAS evidence, intended backend result, unauthorized target/action/expired or
|
||||
replayed request refusal, cleanup on success and failure, no standing engine
|
||||
credential, and steady-state invocation/default migration evidence. Do not use
|
||||
`apply` or any other protected live command to discover the missing entitlement.
|
||||
All of this remains in T06 and owner tasks; no residual is silently finished.
|
||||
Loading…
Add table
Add a link
Reference in a new issue