Reject non-null wrap_info (a wrapping token survives token revoke -self), non-empty data, empty client_token, and leading whitespace before the OIDC stderr prompt. Fail-closed and hand-off tests now run through the CLI and assert sentinel absence from both audit files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 680842@bnt-lap001 Assistant-Session: 54eb9e8e-7d6b-4f0c-b7a6-a6db62075883
5.7 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|
| WARDEN-WP-0036 | workplan | Accept contained OpenBao login output only after helper persistence | infotech | ops-warden | finished | codex | attended-login-openbao-output | 2026-09-01 | 2026-10-14 | d844c96e-152d-53fa-bff6-e072125ef66c |
Repair attended-login handoff
id: WARDEN-WP-0036-T01
status: done
priority: high
state_hub_task_id: "7eb8b9c9-1285-5ada-a17b-1d5bfbb8ba59"
Allow a successful OpenBao login to proceed when its output is fully contained and the private mode-0600 token helper is populated. Continue failing closed on non-zero login, missing persistence, child output, revocation failure, or cleanup failure.
Verify live contained operation
id: WARDEN-WP-0036-T02
status: done
priority: high
state_hub_task_id: "d22bab05-c38b-561f-95de-6c146ce7c6cf"
Run the proxy regression suite, reinstall the CLI, and complete one governed OpenBao platform-admin operation with deterministic self-revocation.
Completed 2026-09-01. The installed CLI completed the governed Policy Nexus Forgejo source bootstrap with all child output contained, then revoked and removed its isolated helper session.
2026-09-28 contained-result correction (existing T01/T02)
Addressed the September 21 attended-login failure/audit report under the existing handoff repair and verification tasks. Failed envelopes now use distinct non-zero codes 10–14 for login, child failure, child output, unconfirmed revocation and cleanup failure. Both audit files retain the actual Warden exit code and phase outcome. Any child bytes, including whitespace, fail closed; the access advisory now states the silent-child requirement and the playbook documents codes, retry limits and the WSL tunnel/browser requirements.
The pre-change checkout already raised exit 5 on ProxyError, so the reported historical exit-zero failure was not reproduced here. The actual reproduced defect was unconditional success auditing; the new CLI regression covers failed login with returncode zero but missing persistence as well as non-zero login, start failures, child output/failure, revocation and cleanup. Revocation still checks revoke-self's exit status; it does not misinterpret an arbitrary failed lookup as proof. The September 23 platform return confirms revoke-self is already granted.
Validation: focused proxy suite 48 passed; full suite 483 passed, 4 integration tests deselected by repository default; changed Python files pass Ruff. No live OIDC, credential read or production operation was used. The earlier September 1 live operation remains historical evidence, not a live validation of this change. Automated endpoint/browser preflight and OIDC URL presentation remain optional inbox suggestions, outside these completed handoff acceptance criteria.
2026-10-14 login-output fail-closed regression and fix (existing T01)
railiance-platform's RPF-WP-0017 re-acceptance review
(railiance-platform/reviews/RPF-WP-0017-ops-warden-reacceptance-2026-10-14.json,
decision reject) found that T01's commit b4c1d39 (2026-09-01) dropped
login_output.strip() from the login fail-closed condition. From then until this
fix, a login that exited 0 with a populated helper proceeded to the child whatever
it wrote to stdout/stderr. Output stayed contained (criterion 3 held) but
criterion 4 (non-allowlisted output fails closed with self-revocation) and the
criterion 5 unexpected-output coverage regressed; the existing unexpected-output
test passed only through the empty-helper persistence path.
Fix: login output is still captured and never forwarded, and is now accepted only when allowlisted by structure (values are never logged, returned, stored, or put in exceptions/audit):
- stdout: empty, or exactly one JSON object with an
authobject containingclient_token; top-level keys limited torequest_id, lease_id, lease_duration, renewable, data, warnings, wrap_info, mount_type, auth, auth keys toclient_token, accessor, policies, token_policies, identity_policies, metadata, orphan, entity_id, lease_duration, renewable, mfa_requirement, num_uses, each type-checked; duplicate keys rejected. - stderr: empty, or exactly the OpenBao OIDC CLI prompt ("Complete the login via
your OIDC provider. Launching browser to:" or "... Open the following link in
your browser:", one
https://URL, optional "Waiting for OIDC authentication to complete..."). These prompt strings were confirmed present in the localbaobinary; this stderr allowlist entry is an ops-warden proposal pending railiance-platform review under RPF-WP-0017.
Anything else (extra text, other stderr, multiple objects, unexpected keys or
types, parse/decoding failure) fails closed: self-revocation through the existing
path, helper cleanup, exit 10 / login_failed, no retry. Added a parametrized
populated-helper test for 13 non-allowlisted shapes and an allowlisted hand-off
test; the success test now uses a full JSON shape plus the OIDC prompt. The
September 1 T02 live operation was recorded in 9770d6a (00:51 +0200), after
b4c1d39 (00:13 +0200) and 8f01eef (00:24 +0200); proxy.py at that time
contained the relaxed check (the installed CLI's exact revision was not recorded). No live OIDC, OpenBao call, or credential read was used for this fix.
Tightened the same day after an independent re-review (containment gap): stdout
wrap_info must be null or absent (a wrapping token would survive token revoke -self), data null, absent or {}, and auth.client_token a non-empty string;
the stderr OIDC prompt must start at the first byte (no leading whitespace;
trailing newlines remain fine). The fail-closed and hand-off tests now run through
the CLI and assert sentinel absence from both access-audit.log and audit.jsonl.