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>
225 lines
10 KiB
Markdown
225 lines
10 KiB
Markdown
---
|
|
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`.
|