--- id: ops-warden-adr-0008 type: adr title: "ADR-0008 — A lane's risk grade covers every field its path discloses" domain: infotech repo: ops-warden status: accepted version: "1.0" revision: "1" owner: ops-warden binds: "ops-warden" created: "2026-08-21" updated: "2026-08-21" last_reviewed: "2026-08-21" review_interval: 6m enforced_by: "registry/routing/catalog.yaml fields + risk; tests/test_routing.py::test_high_risk_lanes_classified" supersedes: "" successor: "" --- # ADR-0008 — A lane's risk grade covers every field its path discloses ## Status Accepted 2026-08-21, after `secrets-engine` found two under-graded lanes while reviewing ops-warden's own catalog metadata. ## Context `ADR-0007` requires every catalog lane to carry an explicit `risk` grade. It does not say what the grade is *of*, and the omission turned out to matter. The catalog describes a lane by a single `fetch_command` naming a single field — `bao kv get -field=ISSUE_CORE_API_KEY `. Grading followed that description. But the unit of disclosure is not the field, it is the **path**: `bao kv get` without `-field` returns every key stored there, and an agent session that discloses one field has disclosed all of them. On 2026-08-19, grading all 27 lanes, ops-warden graded `issue-core-ingestion-api-key` and `reuse-surface-hub-write-token` as `standard` — "ordinary internal workload secrets". Both grades read only the headline field. `CCR-2026-0002` records a deliberate decision to keep `GITEA_BACKEND_TOKEN` at the first path; `CCR-2026-0005` declares a dual-consumer webhook HMAC at the second. Neither is recovered by rotating the credential the lane is named after. Three details make this worth a record rather than a fix: - **The evidence was already ours.** The field sets were in the CCRs the catalog already cites as authoritative. This was not missing data; it was unread data. - **A test held the error still.** `test_high_risk_lanes_classified` asserted `issue-core-ingestion-api-key` was *not* high. A first grading pass had marked it high, the test contradicted it, and the test was believed. A test that encodes a judgement defends that judgement from correction. - **Another repo found it.** `secrets-engine` graded both `high` independently while drafting catalog entries whose schema records `fields`. A schema that names the field set makes the right grade obvious; ours did not have one. ## Decision **A lane's `risk` grade is a property of its path, and must cover the union of everything a read of that path would disclose.** 1. Where the field set is known, the catalog records it as `fields`, with the authority it came from. 2. The grade is argued against the most damaging field, not the named one. 3. Where the field set is unknown, that is stated — never assumed to be one field. An unverified field set is a reason to grade conservatively, matching the `inter-hub-bootstrap-ssh` precedent under `ADR-0007`. 4. Establishing a field set must not be done by reading the secret. Use the owning CCR, the owner's catalog, or `bao kv metadata`. `bao kv get` on a high-risk path is the 2026-07-16 vector and is forbidden by `ADR-0004` for agent sessions regardless of intent. ## Consequences `ADR-0007` is unchanged and still governs: every lane carries an explicit grade, and absence fails safe. This record says what that grade must account for. Grading gets more expensive: it now requires knowing what is at a path, not just what the lane is called. That cost is the point — the cheap version produced two wrong answers in one pass and is the reason this exists. A test that asserts a grade is asserting a judgement. When a grade is disputed, re-argue it from evidence before trusting the test that encodes it. ## Related - `ADR-0007` — every lane carries an explicit grade; build-stage permissiveness stops at credential disclosure - `ADR-0004` — high-risk lanes refuse raw value streaming to agent sessions - `ADR-0001` — the catalog is a pointer layer; `fields` records the owner's declared field set with its source, and does not restate their procedure - `WARDEN-WP-0033-T02`; `secrets-engine` `SECRETS-WP-0006` - `history/2026-07-16-credential-disclosure-lessons.md`