ops-warden/workplans/WARDEN-WP-0036-attended-login-openbao-output.md
tegwick d2cd3fa940
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
fix: contain attended login diagnostics and OpenBao recovery
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a137ca-5c77-7a71-b9ae-23ad9b0b5684
2026-10-15 04:25:05 +02:00

6.8 KiB
Raw Blame History

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-15 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 auth object containing client_token; top-level keys limited to request_id, lease_id, lease_duration, renewable, data, warnings, wrap_info, mount_type, auth, auth keys to client_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 local bao binary; 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.

2026-10-15 CUST81 dependency correction (existing T01/T02)

Prepared source correction after the two CUST81 attended platform-admin attempts failed before child handoff. The strict login-output allowlist remains unchanged. Synthesized format flags now precede auth data; the recovery-only matcher handles OpenBao s. tokens; failure messages expose only fixed categories, client exit code and helper/output-shape booleans. No credential bytes or URLs are surfaced.

Do not attribute the observed 121-second failure to the argv order: Bao 2.5.5 scans global format throughout argv. Actual callback/auth failure remains unknown. Browser profile initialization was verified from metadata only; server revocation remains unconfirmed and the failed attempts are retained. No login, admin token read, policy application or provisioning was performed by this correction.

Source verification is distinct from live verification. The already-approved CUST81 execution scope and its open attended gate remain with CUST-WP-0081-T02. Owner evidence: docs/evidence/2026-10-15-cust81-attended-dependency-repair-r1.json.