ops-warden/docs/adr/ADR-0007-build-stage-stops-at-credential-disclosure.md

101 lines
4.4 KiB
Markdown
Raw Normal View History

---
id: ops-warden-adr-0007
type: adr
title: "ADR-0007 — Build-stage permissiveness stops at credential disclosure"
domain: infotech
repo: ops-warden
status: accepted
version: "1.0"
revision: "1"
owner: ops-warden
binds: "ops-warden"
created: "2026-08-19"
updated: "2026-08-19"
last_reviewed: "2026-08-19"
review_interval: 6m
enforced_by: "registry/routing/catalog.yaml risk grades; src/warden/cli.py agent read-boundary; WARDEN-WP-0032-T06"
supersedes: ""
successor: ""
---
# ADR-0007 — Build-stage permissiveness stops at credential disclosure
## Status
Accepted 2026-08-19, alongside grading the last 14 ungraded catalog lanes.
## Context
`ADR-0006` deferred a global fail-closed authorization gate because uniform
enforcement across an estate under deep refactor hardens the access needed to
perform the refactor. The organization's declared posture is `build`
(WP-0029), and the operator has confirmed the estate need not be tight yet.
That is correct, and it is also the kind of principle that quietly generalises
past its warrant. Read loosely, "we are in build stage" argues for relaxing
every control, including the ones that stop a credential landing in a logged
agent transcript. Those are not the same class of control, and the difference
is not severity — it is **cost**.
`RISK-F-0003` made the distinction concrete. `ADR-0004` reads as a categorical
rule: high-risk lanes refuse raw value streaming to agent sessions. The
implementation was `risk == "high"` against an **optional** field, so 14 of 27
lanes never reached the control at all — five of them `exec_capable`. The
control had not been relaxed by anyone's decision. It had simply never been
reached, which is worse, because nothing announced it.
## Decision
**Build-stage permissiveness applies to controls that gate work. It does not
apply to controls that prevent credential disclosure.**
The test is friction, not severity:
- A control that can **block a legitimate operation** — a fail-closed
authorization gate, an enforcement stance — is a candidate for relaxation
while the organization is in `build`, and `ADR-0006` scopes that relaxation
to zones.
- A control that **redirects how a value moves without preventing the work**
the agent read-boundary, which refuses raw stdout but leaves `--out`,
`--exec`, `--wrap` and `--fingerprint` fully available — is not relaxed by
build posture, because relaxing it buys nothing. Nobody is unblocked by it.
The asymmetry that settles it: a blocked operation is recovered by retrying.
A credential written into a logged transcript is not recovered by rotation —
rotation limits the damage, it does not unwrite the log. The 2026-07-16
disclosure is the case in point.
**Therefore, regardless of `organization_posture`:**
1. Every catalog lane carries an explicit `risk` grade. **Absence is not a
grade**, and a lane that omits it is a defect, not a default.
2. Grading is done on merit, per lane. This decision is not licence to grade
everything `high` — an over-broad grade is its own inaccuracy, and
`tenancy-posture` §6's *accuracy, not altitude* applies to this field too.
3. Minimum credential-handling standards — the read-boundary, the safe fetch
transports, the no-secret audit guard — hold in every posture.
## Consequences
**We accept** the grading cost, now and on every new lane. That is the point:
`WARDEN-WP-0032-T06` makes an ungraded lane impossible rather than merely
discouraged, because a rule enforced by remembering is not enforced.
**We reject** "build stage" as a general argument in credential-handling
discussions. It is a real and useful argument about *gating*, and citing it
against a disclosure control is a category error this record exists to name.
**We note what this decision is not.** It does not set severity for
`RISK-F-0003` — that is `risk-nexus`'s. It does not make ops-warden the judge of
other repos' controls. And it does not survive contact with a zone model that
says otherwise: when `zone-engine` defines admission standards, a zone may
legitimately require *more* than this floor. It may not require less.
## Related
- `ADR-0004` — high-risk lanes refuse raw value streaming to agent sessions
- `ADR-0006` — enforcement is zone-scoped, never a global flag
- `RISK-F-0003` — the read-boundary blind spot that prompted this
- `WARDEN-WP-0032-T05` / `T06` — the grading, and making absence impossible
- `zone-engine` `ZONE-WP-0001` — where admission standards will be defined