RISK-WP-0001 T01-T06,T08: the four instruments, the index, and the first grading
Severity (impact x likelihood, fidelity modifier for controls that lie, headline-vs-constraint, build-mode double grade, the floor), disclosure (publish/embargoed/restricted, and the build-mode deferral re-taken and narrowed with RISK-F-0001 in hand), escalation (the five INTENT triggers settled plus an ordering-hazard trigger the RISK-F-0002 case forced; proposed, awaiting the custodian), review (intervals, what a review is, what missing one produces, the production re-score). Then applied: RISK-F-0001 critical/embargoed/escalated, RISK-F-0002 medium with a high constraint on RISK-F-0001's remediation, filed as a peer and escalated only on the ordering, RISK-F-0003 high/embargoed/no escalation. No unset field remains. REGISTER.md is generated; make check reports overdue, stalled, ungraded and unanswered escalations without changing anything. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
e268259f94
commit
d5a3953f2e
15 changed files with 1334 additions and 14 deletions
225
docs/rulings/2026-08-19-first-grading.md
Normal file
225
docs/rulings/2026-08-19-first-grading.md
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
---
|
||||
id: RISK-RULING-2026-08-19
|
||||
type: ruling
|
||||
title: "First grading: RISK-F-0001, RISK-F-0002, RISK-F-0003"
|
||||
status: recorded
|
||||
owner: risk-nexus
|
||||
date: "2026-08-19"
|
||||
workplan: RISK-WP-0001-T06
|
||||
---
|
||||
|
||||
# First grading — 2026-08-19
|
||||
|
||||
The first application of `docs/method/`. Three findings, graded together
|
||||
because the instruments were written for them and a scale that has never been
|
||||
used is a draft.
|
||||
|
||||
Where a grading changed what an owning repo should do, it went back as a
|
||||
message. No owning repo's files were edited.
|
||||
|
||||
## RISK-F-0001 — flex-auth /v1/check authenticates no caller
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Impact | `I4` |
|
||||
| Likelihood | `L3` |
|
||||
| Fidelity modifier | no |
|
||||
| **Severity** | **critical** |
|
||||
| At production | critical |
|
||||
| Disclosure | embargoed |
|
||||
| Escalation | yes — trigger 1 |
|
||||
| Review by | 2026-08-26 |
|
||||
|
||||
**Impact `I4`.** `flex-auth` is the estate's authorization oracle. A forged
|
||||
allow does not stay in `flex-auth`; it is the answer other services act on,
|
||||
and `tenant-engine` has separately stated that direct authority over its rows
|
||||
means privilege escalation across NetKingdom rather than tampering confined to
|
||||
one store. That is the definition of `I4` — what is compromised here
|
||||
propagates to everything that trusts it.
|
||||
|
||||
**Likelihood `L3`, not `L4`.** Any workload with cluster reach can assert any
|
||||
subject and any tenant. That is the normal working set with no additional
|
||||
step. It is not `L4` only because reach is inside the cluster rather than open.
|
||||
|
||||
The register follows the reporter in **not** assuming a default-deny
|
||||
NetworkPolicy exists, and equally in not assuming its absence proves wider
|
||||
exposure. `flex-auth` did not state it either way. This is the single fact
|
||||
that would most change the grade, so it is the first question at review — see
|
||||
"Asks" below.
|
||||
|
||||
**No fidelity modifier.** The endpoint answers honestly about a caller it
|
||||
never checked; it makes no attestation of its own. The false-record hazard
|
||||
belongs to `RISK-F-0002`'s constraint, where a *consumer* of this endpoint
|
||||
would start signing records that assert an authorization was made.
|
||||
|
||||
**Production.** Unchanged. Impact is already estate-wide and likelihood does
|
||||
not depend on there being users.
|
||||
|
||||
**Disclosure: embargoed** until `FLEX-WP-0015-T02` ships to production. This
|
||||
is the finding that forced the deferral to be re-taken
|
||||
(`docs/method/disclosure.md`): it names an unauthenticated decision surface
|
||||
and the service carrying it, which shortens the path for exactly one kind of
|
||||
reader. Publish on fix.
|
||||
|
||||
**Escalation: yes, trigger 1.** `INTENT.md` asked whether governing access to
|
||||
tenant data counts as exposing it. Ruled: it does. An authorization oracle
|
||||
that can be forged is not one step removed from the data, it is the step.
|
||||
|
||||
**Nothing further is asked of `flex-auth`.** They own it, classify it as their
|
||||
only urgent follow-up, and are shipping through staged promotion.
|
||||
|
||||
## RISK-F-0002 — ops-warden signs SSH certificates with no authorization decision
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Impact | `I3` |
|
||||
| Likelihood | `L2` |
|
||||
| Fidelity modifier | no (headline) |
|
||||
| **Severity** | **medium** |
|
||||
| Constraint severity | **high** |
|
||||
| At production | medium |
|
||||
| Disclosure | embargoed |
|
||||
| Escalation | via trigger 6 only, jointly with RISK-F-0001 |
|
||||
| Review by | 2026-11-17 |
|
||||
|
||||
`RISK-F-0002` asked this repo three questions. All three are answered here.
|
||||
|
||||
### 1. Severity — which state is scored
|
||||
|
||||
The headline scores **today**: the gate is off, and that is a missing control
|
||||
honestly represented. `I3` — SSH certificates into production hosts cross a
|
||||
trust boundary. `L2` — the caller must already hold a scoped `VAULT_TOKEN` and
|
||||
the actor must exist in `inventory.yaml`; TTLs are enforced and every issuance
|
||||
is logged. Possession of the signing token is the whole authorization model,
|
||||
which is thin, but it is not nothing and it is not `L3`.
|
||||
|
||||
**The reporter's argument is accepted in full**: the two states are not equally
|
||||
bad, and the second is the one worth a severity. It is recorded as a
|
||||
constraint, not as the headline, because the register describes the estate as
|
||||
it is and the second state does not exist yet.
|
||||
|
||||
> **Constraint (severity `high`).** Enabling `policy.enabled` while
|
||||
> `flex-auth`'s `/v1/check` answers unauthenticated callers converts an absent
|
||||
> control into a false attestation: an attacker with ClusterIP reach obtains a
|
||||
> genuine `allow`, and the signature log carries a `policy_decision_id`
|
||||
> asserting the issuance was authorized. `I3 + fidelity → I4`, `L2` → `high`.
|
||||
|
||||
The constraint attaches to `RISK-F-0001`'s remediation, and the ordering is
|
||||
recorded on both findings:
|
||||
|
||||
```
|
||||
flex-auth warn-only -> ops-warden gate presents its SA token -> logs clean
|
||||
-> flex-auth fail-closed -> ops-warden policy.enabled: true
|
||||
```
|
||||
|
||||
The headline being lower than the constraint is exactly the case
|
||||
`docs/method/severity.md` was written to handle. A reader must not come away
|
||||
with "medium" and miss the high one.
|
||||
|
||||
### 2. Peer or consequence — **peer**
|
||||
|
||||
Filed as its own finding, as `ops-warden` filed it. Two reasons, both from
|
||||
`INTENT.md`'s routing rule: the fix owner differs, and the "off" state has
|
||||
standing regardless of how `RISK-F-0001` resolves. If `RISK-F-0001` were
|
||||
withdrawn tomorrow, `ops-warden` would still be signing certificates with no
|
||||
per-request judgement.
|
||||
|
||||
What is *not* independent is the ordering, and that is carried as a constraint
|
||||
on both rather than by collapsing one finding into the other.
|
||||
|
||||
### 3. Escalation — the register disagrees with the reporter, narrowly
|
||||
|
||||
`ops-warden` judged this does not need the operator: known, owned, and its
|
||||
dangerous failure mode written down in both repos. On triggers 1-5 the
|
||||
register agrees — no real tenant data, no obligation, no spend, no ownership
|
||||
dispute, no stall.
|
||||
|
||||
But the reasoning "it is written down in both repos" is the argument the
|
||||
register cannot accept on its own, because `RISK-F-0002` is itself the
|
||||
evidence against it: its own blocker was written down, filed away, and
|
||||
invalidated in a day with nothing re-checking it. Written down is not the same
|
||||
as held.
|
||||
|
||||
So **trigger 6 fires once** — an ordering hazard whose wrong sequence creates
|
||||
a false attestation. One acknowledgement from the operator that the ordering
|
||||
exists, then the register carries it. Not a standing supervision request.
|
||||
|
||||
This is the disagreement the escalation rule was worth writing to surface, and
|
||||
it is the reason trigger 6 exists at all.
|
||||
|
||||
**Disclosure: embargoed** until the ordering completes — `FLEX-WP-0015-T02`
|
||||
shipped *and* `policy.enabled: true` in production. Publishing "production SSH
|
||||
signing performs no authorization decision" while true shortens the path.
|
||||
|
||||
## RISK-F-0003 — agent read-boundary does not fire on ungraded catalog lanes
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Impact | `I4` |
|
||||
| Likelihood | `L2` |
|
||||
| Fidelity modifier | no (see below) |
|
||||
| **Severity** | **high** |
|
||||
| At production | high |
|
||||
| Disclosure | embargoed |
|
||||
| Escalation | no |
|
||||
| Review by | 2026-09-18 |
|
||||
|
||||
**Impact `I4`, driven by one lane.** Four of the five `exec_capable` ungraded
|
||||
lanes are `I3`-shaped — a publish token, an OIDC login, an ingestion key, a
|
||||
hub write token, each bad within its own system. `openbao-api-key` is not:
|
||||
it vends access to the store the estate's other secrets live in, and a
|
||||
disclosure there propagates past every boundary the others respect. The
|
||||
finding is graded on its worst lane.
|
||||
|
||||
**Likelihood `L2`.** Requires an agent session with `WARDEN_AGENT_ID` set —
|
||||
a foothold the estate does grant. `ops-warden` states the exposed population
|
||||
is not established and should not be assumed zero or large, and the register
|
||||
holds that line: `L2` is what the stated facts support. The unverified OpenBao
|
||||
`agent-high-risk-boundary` coverage would lower it if confirmed, and is a
|
||||
review question rather than an assumption.
|
||||
|
||||
**No fidelity modifier, deliberately, and it was close.** `ADR-0004` reads as
|
||||
a categorical rule while the implementation is an opt-in list, so the estate's
|
||||
*documentation* asserts a boundary that does not exist for 14 lanes. That is
|
||||
documentation drift, and the modifier in `docs/method/severity.md` is scoped
|
||||
to attestations a system produces at runtime. 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.
|
||||
|
||||
**Escalation: no.** Known, owned, tracked (`WARDEN-WP-0032-T05` for the five
|
||||
lanes, `WARDEN-WP-0032-T06` for the structural fix), and moving. No trigger
|
||||
fires. Severity alone deliberately does not escalate.
|
||||
|
||||
**The operator's maturity-context direction is noted, not re-decided.** The
|
||||
finding records that an absent grade should resolve from maturity context —
|
||||
tolerable in early or experimental contexts, `high` or `critical` in
|
||||
production ones — and that the durable form waits on the zone model
|
||||
(`ZONE-WP-0001-T03`). The register's only remark is the one the finding
|
||||
already makes and this repo confirms from its own registration work today:
|
||||
`.repo-classification.yaml` `category` cannot carry that signal.
|
||||
`railiance-platform` runs production OpenBao and owns three of the five lanes
|
||||
while classified `tooling`, and this repo has just classified itself with the
|
||||
same vocabulary. The maturity ladder needs its own field.
|
||||
|
||||
**Disclosure: embargoed** until the five lanes are graded under
|
||||
`WARDEN-WP-0032-T05`. It names five live lanes that vend real values without
|
||||
the boundary firing.
|
||||
|
||||
## What this grading asks of other repos
|
||||
|
||||
Sent as messages, not as edits.
|
||||
|
||||
| Repo | Ask |
|
||||
| --- | --- |
|
||||
| `flex-auth` | Confirm whether a default-deny NetworkPolicy fronts the `/v1/check` Service. It is the single fact that most changes a `critical` grade, and only they can answer it. |
|
||||
| `ops-warden` | Confirm the OpenBao `agent-high-risk-boundary` policy's coverage of the five `exec_capable` lanes. |
|
||||
| both | The ordering constraint is recorded and carried by this register. Neither repo needs to re-derive it. |
|
||||
|
||||
## What this grading proved about the instruments
|
||||
|
||||
The scale earned two of its features on first use: the fidelity modifier
|
||||
(needed by `RISK-F-0002`, and correctly *not* applied to `RISK-F-0003`), and
|
||||
the headline-versus-constraint split (needed the moment a finding described
|
||||
two states). The floor was not exercised here — all three findings clear it
|
||||
easily — and gets its real test in `RISK-WP-0001-T07`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue