ops-warden/workplans/WARDEN-WP-0039-explicit-policy-refusal.md
tegwick 7d4381e887
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
WARDEN: separate fetch evaluator URL for secret-read checks (CUST-WP-0075)
check_fetch_policy now posts only to policy.fetch_flex_auth_url (access-engine
pin flex-auth-ops-warden-fetch, workstation 127.0.0.1:19091). Signing keeps
policy.flex_auth_url. Unset or unreachable fetch evaluator fails closed with a
message naming it; no fallback to the signing pin or to allow. warden access
advisory output names the fetch evaluator. Recorded under WARDEN-WP-0039-T03.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3775@bnt-lap001
Assistant-Session: cfacb6a5-ad5b-4f79-ac67-053e3b0d34a3
2026-10-03 09:18:54 +02:00

7.6 KiB

id type title domain repo status flavor owner topic_slug created updated origin origin_ref state_hub_workstream_id
WARDEN-WP-0039 workplan Preserve explicit policy caller refusals before credential and CA effects infotech ops-warden blocked residual codex custodian 2026-09-08 2026-10-03 residual HFACT-WP-0001 ae44a935-6fca-514c-a385-4550dd2b1fe8

The factory critical-path review reproduced a live HTTP 403 from the reachable PDP for the configured ops-warden caller and a railiance-platform secret read. check_fetch_policy treated it as evaluator unavailability and used unknown-zone fail-open. Caller-auth rejection is an explicit refusal, not a transport outage.

Preserve explicit authentication and binding refusals

id: WARDEN-WP-0039-T01
status: done
flavor: residual
priority: high
assignee: the-custodian
state_hub_task_id: "eaad08d9-ae47-5f50-8278-ea402a0e2869"

HTTP 401 and 403 stop signing and credential fetch irrespective of the outage profile. Do not expose response bodies or alter system identity to bypass the refusal. Preserve configured behavior for genuine evaluator failures. Prove both permissive and closed outage profiles and refusal before child execution.

Verify and publish the correction

id: WARDEN-WP-0039-T02
status: done
flavor: residual
priority: high
assignee: the-custodian
state_hub_task_id: "ac85cf00-391c-5c63-b8f4-ed5bd57684e5"

Run the policy and proxy suites, retain a value-free live refusal receipt, publish the reviewed source, and verify the installed CLI refuses before any credential transport. A refusal is not a successful credential-read admission.

The owner installer initially reused a cached wheel despite --force, leaving the pre-fix policy code installed. Both Makefile installation targets now use --reinstall-package ops-warden to refresh this package from the reviewed source. Verify the installed module as well as the checkout before the live refusal test.

Resolve the credential proxy's admitted policy binding

id: WARDEN-WP-0039-T03
status: wait
flavor: residual
priority: high
assignee: the-custodian
needs_human: true
blocking_reason: "Code side done 2026-10-03 (policy.fetch_flex_auth_url). Waits on founder go: deploy access-engine pin flex-auth-ops-warden-fetch, add tunnel flex-auth-ops-warden-fetch-railiance01, set the key in live warden.yaml, then record positive and wrong-owner evidence."
state_hub_task_id: "8ca28b63-2e04-5333-b635-011b124c1806"

Consume the existing native-lane handoff (WARDEN-WP-0033 / SECRETS-WP-0006) and flex-auth caller contract. Establish whether this interim transport needs an admitted dedicated policy route or must finish its native handoff. Retain the refusal until that contract yields positive and wrong-caller/owner/tenant negative evidence. No credential read, secret generation, or policy grant is authorized by this workplan alone. HFACT-WP-0001-T03 consumes this return.

Validation: 429 tests passed (4 integration tests deselected by the repository default); Ruff passed for changed Python files. Full tests used the declared phase-memory source and an isolated temporary memory store. The focused policy/proxy suite passed 69 tests. The existing authenticated SSH policy probe still returns HTTP 200/ALLOW, decision:f3f7c88f9585582a; the credential-owner request returns 403. No CA issue or credential read was performed by these probes.

Installed verification: source guard present after refreshed owner installation (19bb75c). warden access forgejo-admin-api-token --exec --field API_TOKEN -- true exits 4 with explicit HTTP 403 before credential transport or child execution. The previous fail-open warning is absent. The probe requested no output value; no credential was fetched. T01/T02 are complete; T03 owns the remaining exact policy-binding admission.

T03 routed 2026-09-09. Asked flex-auth whether an admitted contract exists for a delegated credential read where the caller (ops-warden) and the resource owner differ, since that is exactly the shape drawing the live 403. Three outcomes were named as equally acceptable answers, with no preference stated between the first two: an existing contract to conform to; no contract yet, making this a design question they should raise rather than one ops-warden invents a shape for; or that there should be no such contract — the interim proxy transport is itself the defect and the answer is to finish the native handoff (WARDEN-WP-0033 / SECRETS-WP-0006).

The third is a real possibility and was not argued against. Eleven catalog lanes are ops-warden proxies with a named intended owner precisely because no owner front door exists; if delegated reads should not be made policy-admissible, that shortens WP-0033 rather than blocking it.

Two fixes were explicitly ruled out in the message rather than left unmentioned: broadening the ops-warden caller binding so it may read other systems' resources, and relabelling resource.system as ops-warden so the existing binding matches. The second is worse — it would make the audit trail assert ops-warden owns credentials it deliberately does not, which is the claim ADR-0002 exists to prevent, achieved by editing a field instead of making an argument.

The refusal stays in place until an answer yields positive evidence plus wrong-caller, wrong-owner and wrong-tenant negatives. No grant was requested. secrets-engine was told this bears on SECRETS-WP-0007-T04 and on how many lanes stay proxied; gate-house was told it may reach how the signing lane's approval-consume is built (GH-DEC-2026-005).

2026-09-28 loose-end review

T03 remains wait and the workplan remains blocked. Re-read the owner's finished FLEX-WP-0026: no admitted delegated-read binding exists, and its native OpenRouter contract explicitly does not close WARDEN-WP-0039-T03. FLEX-DEC-2026-015 also confirms resource.system is runtime policy vocabulary, not a repository rename. Retain the explicit refusal. A native owner route's success does not grant this interim proxy general delegated-read authority; exact positive and caller/owner/ tenant negative evidence is still required for the route that replaces it.

T03 code side done 2026-10-03 (CUST-WP-0075, founder build-mode directive). access-engine answered the contract question with a dedicated fetch evaluator: pin flex-auth-ops-warden-fetch (access-engine 02b15a7, values/ops-warden-fetch.yaml), same caller (ops-warden SA, audience flex-auth), owner systems bound per lane, request shape unchanged. ops-warden now sends check_fetch_policy only to the new key policy.fetch_flex_auth_url; signing keeps policy.flex_auth_url. An unset or unreachable fetch evaluator fails closed with a message naming it, with no fallback to the signing pin and no fail-open. 401/403 keep the existing refusal text. warden access <need> names the fetch evaluator on its gate (or policy) line. Tests: tests/test_policy_fetch_evaluator.py, plus updated proxy and refusal tests. Full suite: 494 passed, 4 deselected. Docs: wiki/OpsWardenConfig.md ("Two evaluators", tunnel example), wiki/CredentialRouting.md, production example.

Still open (founder go, needs_human): deploy the pin (access-engine ADHOC-2026-10-03-T02), add the ops-bridge tunnel (local 19091 → the pin's Service ClusterIP:8080), set fetch_flex_auth_url: http://127.0.0.1:19091 in the live ~/.config/warden/warden.yaml, then record exact positive evidence and wrong-owner/caller negative evidence before T03 closes. Until the key is set, every proxied fetch refuses with "secret-read evaluator not configured". Before that change, those fetches got a 403 from the signing pin.