key-cape/docs/openbao-negative-probe-session-proposal.md

118 lines
7 KiB
Markdown
Raw Normal View History

# Coordinated OpenBao JWT refusal session proposal
Status: prepared, not an execution grant. Proposal ID: KEY-WP-0039-T02/coordinated-negatives-v2.
The current positive service-JWT login and no-fallback results are retained. This
session adds native refusals for CCR-2026-0038 and must not replay registration,
custody minting or accepted provisioning. It leaves the secrets-engine-openbao
registration, custody and OpenBao role/policy unchanged.
## Exact owner re-agreement and execution authority
Railiance-platform must re-agree the packet's two documented departures: all
non-audience probes pin audience secrets-engine-openbao, and the sixth expiry
client has every production claim and therefore is capable of logging in until
removed. The script now exercises that capability as a positive control before
expiry and immediately revokes the resulting self-only OpenBao session. This
change belongs in the exact owner review, rather than being hidden in a test.
NetKingdom owns live registry/env changes and both KeyCape restarts. KeyCape owns
claim isolation and issuance checks. Platform owns refusal interpretation,
effective-policy capability checks and the final CCR receipt. Founder approval
must name the exact revised script and registration packet digests, bounded
session duration, temporary Secret and registration names, and rollback below.
Previous approval of CCR-2026-0038 alone is not approval to add six clients.
No existing coding-agent secret is requested through chat or a repository. If
codex-railiance-platform is not registered and independently available through
its admitted route, that case is inconclusive and requires owner disposition;
it is never silently skipped or replaced by an altered production client.
## Preflight before any mutation
Record only value-free metadata: current KeyCape Deployment image/revision,
registry content digest with secretRefs only, its resourceVersion, admission of
six unique client IDs, a spare restart window, and baseline workload health.
Confirm live JWT issuer, RS256, exact role bindings and current
expiration_leeway. Omitted/zero OpenBao expiration_leeway means the provider
default 150 seconds; a disabled leeway must be normalized to effective zero
before passing --leeway. Record effective leeway in the receipt. Abort if role
bindings differ from CCR-2026-0038, if any temporary client already exists, or
if the registry has an unreviewed revision. No value or Secret object read is
part of this preflight.
The execution packet must provide a private admitted path to the existing
coding-agent token and an attended human login. Issuer discovery must remain
https://kc.coulomb.social and the token endpoint on that origin. The revised
script rejects redirects and mismatched discovery origins.
## Bounded session and proof
Generate six independent secrets in the owner-controlled session. Materialize
one uniquely named transient Kubernetes Secret and precisely six env references;
no OpenBao custody, retained consumer file, or additional persistent copy.
Merge six registrations from docs/openbao-negative-probe-clients.yaml, preserving
all existing clients byte for byte. Restart once and verify Ready and all six
client exchanges. Run the revised script with private stdin and an attended
human token; never print the stdin, claims, bearer tokens, errors or Secret.
The script inspects decoded claim shape only to establish probe isolation; this
is not signature verification. OpenBao remains the verifier. Audience, subject,
tenant, roles and scope probes must differ on exactly their designated claim;
the expiry probe must match all six bound claims and have its one-minute TTL.
The expiry token must first be accepted and successfully self-revoked, then its
JWT is presented after exp + effective leeway + 10 seconds. An unrelated claim
refusal, not-yet-valid error, generic permission denial, transport failure,
malformed response, unexpected acceptance or unconfirmed revocation fails the
proof. Existing human/coding-agent tokens may differ in several claims and prove
only their class's refusal, not isolated principal_type enforcement.
After any unexpected acceptance, successful revoke-self is required; if it
cannot be confirmed, the runner stops further presentations and the owner must abort and escalate that session to the platform owner.
The runner produces a v2 value-free receipt. all_refused means all eight refusal
checks have semantically appropriate classes and the expiry control succeeded;
there is no broad success from HTTP 400/403 alone.
Platform additionally performs sys/capabilities-self with the actual admitted
service session for both guarded KV data/metadata paths plus
`sys/policies/acl/*`, `auth/*/role/*`, and `auth/token/create`, confirms deny for
every CCR-required path, and revokes the session. No data read is needed. The existing no-fallback receipt
is retained unless the provider or consumer revision changed. These checks are
outside the negative runner and remain required by RPF-WP-0035-T02.
## Cleanup and rollback
In a finally path remove all six registrations and exactly six env references,
restore the unchanged baseline registry/config, restart and wait Ready, then
verify client_credentials for each removed client is invalid_client using the
still-private temporary values. Only then remove the transient Secret and any
private human-token file owned by this session. Confirm all six client IDs and
Secret/env refs are absent, service positive behavior and baseline deployment
health restored. Never restore a complete Deployment over concurrent changes;
compare baseline/revision and stop for owner reconciliation if they changed.
Do not destroy or rotate the production secrets-engine credential.
If interrupted after registration, the session remains incomplete until the
same cleanup is verified. A failed login's unconfirmed revocation remains a
failure in the receipt; later successful cleanup does not rewrite that history.
The exposure is at most the attended window plus the final issued JWT's TTL and
any OpenBao 5-minute session lifetime; unexpected issued sessions require
verified revocation. Cleanup evidence is mandatory before KEY-WP-0039 can finish.
## Distinct remaining acceptance
RPF-WP-0035-T02 can finish only after the eight native refusals, effective-policy
deny checks, unchanged no-fallback evidence and cleanup are retained. This does
not finish MASON-WP-0009-T05: its owner-return requirements remain live operator
and ESO token capability checks, a nonmember refusal, and ops-warden activation
of the already proposed pointer after evidence. No mint, operator policy widening
or routing activation is authorized by this proposal.
## Validation
17 runner tests pass, including malformed/ambiguous semantics, exact claim
isolation, valid expiry control, failed revoke, redirect refusal and no retained
credential values. Two semantic tests fail against the original source: it
reported success when the expiry positive control was refused for a subject
mismatch, and it classified not-yet-valid as expired. Native execution has not
been attempted by this preparation.