risk-nexus/findings/RISK-F-0003-ops-warden-read-boundary-ungraded-lanes.md
tegwick 7f1424dbcf Sweep risk inbox and reconcile findings
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
2026-09-01 02:41:32 +02:00

12 KiB
Raw Blame History

id type title status owner reported_by reported_via routed_by date_reported system environment fix_owner fix_tracking severity severity_at_production severity_superseded impact likelihood fidelity_modifier production_rescore disclosure publication publication_id publication_path publication_subtitle revision last_reviewed review_interval embargo_lifted embargo_was_since escalation date_fixed last_checked next_check cadence clean_streak graded_by ruling checked_by
RISK-F-0003 finding ops-warden agent read-boundary does not fire on ungraded catalog lanes fixed risk-nexus ops-warden ops-warden ops-warden 2026-08-19 ops-warden production ops-warden WARDEN-WP-0032-T05 / T06 (done 2026-08-22) medium medium high (2026-08-19) — the CLI-layer gap is mitigated I4 L2 false false public pending-handover risk-f-0003-ops-warden-agent-read-boundary-blind-spot findings/ops-warden-agent-read-boundary-blind-spot/v1/index.html An omitted catalog grade silently bypassed the agent credential boundary; omission now fails safe and CI rejects it. fixed-1 2026-09-01 6m 2026-08-22 — catalog omission fails safe, CI requires explicit grades, and RISK-F-0009's direct-OpenBao layer is fixed 2026-08-19 none 2026-08-22 2026-09-01T00:32:44Z 2026-09-01T00:32:44Z instant 0 risk-nexus RISK-RULING-2026-08-19 codex/risk-nexus

RISK-F-0003 — the agent read-boundary has a fourteen-lane blind spot

Reporter update 2026-08-19 — exposure closed, structural fix outstanding. All 14 ungraded lanes now carry an explicit risk grade (17 high, 10 standard, 0 ungraded) and the read-boundary fires on them; verified exit 7 with WARDEN_AGENT_ID set. The rule is recorded as ops-warden ADR-0007. Still open: nothing yet prevents a new lane being added ungraded (WARDEN-WP-0032-T06), and it remains unverified whether OpenBao's agent-high-risk-boundary policy covers these paths. status moved to mitigated by the reporter; severity remains risk-nexus's to set.

What is true

ADR-0004 (ops-warden) states that high-risk lanes refuse raw value streaming to agent sessions. It is implemented in src/warden/cli.py:1245:

if raw_value_stream and entry.is_high_risk and agent_id:

and is_high_risk is defined in src/warden/routing/models.py:123 as:

return self.risk == "high"

risk is an optional field on a catalog entry. Of the 27 entries in registry/routing/catalog.yaml, 14 carry no risk value at all. For those, is_high_risk is False, so the boundary never fires regardless of what the lane actually vends.

Five of the fourteen are exec_capable: true, meaning warden access --fetch can proxy a real value for them:

Lane Owner Status
openbao-api-key railiance-platform active
whynot-design-npm-publish railiance-platform active
key-cape-oidc-login key-cape active
issue-core-ingestion-api-key railiance-platform active
reuse-surface-hub-write-token railiance-platform active

For these five, an agent session with WARDEN_AGENT_ID set can stream a secret value to stdout, which is the disclosure pattern of 2026-07-16 that WP-0026 and ADR-0004 were written to prevent. The control is not bypassed; it is simply never reached.

Why it matters beyond these five

The failure mode is omission, not error. Adding a lane without a risk value produces a lane outside the boundary, silently, with no warning at load and nothing in CI that notices. Every future lane inherits this default. The nine other ungraded lanes are not exec_capable today, but exec_capable is itself an editable field.

ADR-0004 reads as a categorical rule. The implementation is an opt-in list.

Exposure — stated only as far as ops-warden can support it

  • ops-warden is the affected system and owns the catalog, the ADR, and the code.
  • WARDEN_AGENT_ID is set by agent harnesses; ops-warden has not enumerated which sessions currently set it, so the population actually exposed is not established and should not be assumed to be zero or large.
  • There is a second, independent layer for OpenBao-backed lanes: the OpenBao policy agent-high-risk-boundary denies data-read for agent tokens on the paths it covers. Whether it covers these five paths has not been verified by ops-warden and should be checked against the live policy rather than inferred — the paths were graded by the same omission this finding is about.
  • No evidence of an actual disclosure through these lanes has been sought or found. This is a control gap, not a known incident.

How it was found

Doing ZONE-WP-0001-T02 (zone-engine) — partitioning the estate for the security-zone model. Grading every lane on risk was a prerequisite for deriving zone membership, and the count of ungraded lanes is what surfaced it.

Suggested direction, not a prescription

Two candidate fixes, both ops-warden's to choose between:

  1. Invert the default. Treat absent risk as high, so a new lane is protected until deliberately graded down. Fails safe; may be noisy.
  2. Make risk required, enforced at catalog load and in CI, so an ungraded lane cannot be committed. Fails loud; requires grading 14 lanes now.

Either way the grading is real work with real judgement in it, and the five exec_capable lanes are the ones that matter first.

Update 2026-08-19 — a third direction, and the one being taken. The operator has directed that the default derive from maturity context: in an early or experimental context an absent grade is tolerable and explicitly accepted; in a production context an absent grade resolves to high, or critical where the context is critical. This validates against the data here — all five exposed lanes are owned by production-serving components, so the rule would have caught every one.

The durable form of that is a zone-model question (ZONE-WP-0001-T03), because the M0-M3 maturity ladder that would drive it has no join to catalog lanes today. That work is months out, so the two are being run separately: the five lanes are graded explicitly now under WARDEN-WP-0032-T05, and the structural fix that makes absence impossible follows under WARDEN-WP-0032-T06.

Note for whoever sets severity: .repo-classification.yaml category is not usable as the maturity signal. railiance-platform, which runs production OpenBao and owns three of the five lanes above, is category: tooling.

  • ops-warden ADR-0004 — high-risk lanes refuse raw value streaming
  • ops-warden WP-0026 — disclosure hygiene, safe fetch transports
  • wiki/playbooks/agent-read-boundary.md
  • RISK-F-0002 — ops-warden sign ungated (same system, different control)
  • zone-engine ZONE-WP-0001-T02 — the work that surfaced this

Register ruling — 2026-08-19

high (I4 × L2), embargoed until the five exec_capable lanes are graded under WARDEN-WP-0032-T05, no escalation.

Graded on its worst lane. Four of the five are I3-shaped — a publish token, an OIDC login, an ingestion key, a hub write token, each bad inside its own system. openbao-api-key is not: it reaches the store the estate's other secrets live in, and a disclosure there propagates past every boundary the others respect.

Likelihood L2 — an agent session with WARDEN_AGENT_ID is a foothold the estate does grant. The register holds the line this finding drew: the exposed population is not established, so it is neither assumed zero nor assumed large, and the unverified OpenBao agent-high-risk-boundary coverage is a review question rather than an assumption in either direction. Confirming that coverage for these five paths would lower the grade.

No fidelity modifier, and it was close. ADR-0004 reads categorical while the implementation is opt-in, so the documentation asserts a boundary that does not exist for 14 lanes. The modifier is scoped to attestations a system produces at runtime, and documentation drift is not that. But if any compliance evidence anywhere cites ADR-0004 as implemented, that is a false attestation and a separate finding. This register has not looked, and says so rather than assuming.

No escalation. Known, owned, tracked (WARDEN-WP-0032-T05 for the five lanes, WARDEN-WP-0032-T06 for the structural fix), and moving. Severity alone deliberately does not reach the operator.

On the maturity-context direction, which is the operator's and not re-decided here: the note that .repo-classification.yaml category cannot carry the signal is confirmed from this repo's own registration work today. railiance-platform runs production OpenBao and owns three of the five lanes while classified tooling; risk-nexus classified itself with the same vocabulary an hour ago. The maturity ladder needs its own field, and that is ZONE-WP-0001-T03's to build.

Reasoning: docs/rulings/2026-08-19-first-grading.md.

Reviews

  • 2026-08-19 — graded. Next review 2026-09-18 (high → 30 days). Open at review: OpenBao policy coverage of the five paths; whether WARDEN-WP-0032-T05 has landed; whether any compliance evidence cites ADR-0004 as implemented.

Check — 2026-08-20: mitigated on one layer, highmedium

ops-warden reports all 17 high-risk lanes now exiting 7 on warden access --fetch with WARDEN_AGENT_ID set, verified under WARDEN-WP-0032-T05/T06. The 14 ungraded lanes are graded; the boundary fires. The live gap this finding described is closed on the CLI layer.

Not clean, so the cadence stays at instant. Something moved, and under the ladder that resets the clock rather than earning a longer one. The next check is the one that can start climbing.

highmedium. What remains is the omission shape rather than the instance: whether a future lane can still be added without a grade. That is WARDEN-WP-0032-T06, and the durable form of the operator's maturity-context rule is zone-engine's (RISK-N-0004). Not low, because "graded by hand once" is not the same as "cannot be ungraded again".

The embargo condition changed rather than being met. The original condition — the five exec_capable lanes graded — is satisfied. But RISK-F-0009 shows the second layer, the OpenBao deny set that protects the direct bao kv get path, covers 6 of 17 high-risk lanes. Publishing this finding now would name lanes that are still reachable by the path this control exists to close. The condition is therefore re-pointed at RISK-F-0009.

That is the disclosure rule working across two findings rather than one: what matters is whether the text shortens a path, not whether this particular finding's own fix has landed.

Verification limit, recorded rather than assumed: the mitigation is ops-warden's report and this register has not probed it. Their operator token is expired, which is also why RISK-F-0009 rests on a file comparison.

  • 2026-08-20 — clean check: checked against the inbox and the owner's record; nothing moved. Cadence instant → 1h (1 clean in a row); next check 2026-08-20 11:02Z.
  • 2026-08-21 — clean check: fix state read from the owner's file: WARDEN-WP-0032-T05 done; nothing else moved. Cadence 1h → 8h (2 clean in a row); next check 2026-08-21 14:32Z.

Closure — 2026-09-01: omission is no longer permissive

The remaining structural task is done. RouteEntry now resolves an absent or unknown grade fail-safe, is_graded exposes the distinction, and CI rejects a catalog lane without an explicit grade. The current focused Warden regression set passes (137 tests), including the omission and OpenBao coverage checks.

The dependent direct-OpenBao gap is also fixed under RISK-F-0009. There is no remaining live or structural part of this finding, so it moves from mitigated to fixed and its embargo lifts.

  • 2026-09-01 — not clean: WARDEN-WP-0032-T06 and the dependent OpenBao coverage are complete; status fixed and embargo lifted. Cadence 8h → instant; checked again immediately.