RISK-WP-0004-T05: establish what this register can verify, by trying it
Cluster reads work from this host; OpenBao returns 403, the same wall ops-warden hit. So the register can check what the cluster admits and cannot check what the secret store permits, and every grade touching an OpenBao policy is a grade on a document. That asymmetry is recorded rather than closed: a risk register holding production secret-store access would have traded a verification problem for a worse one. RISK-V-0001 is the first verification. It confirms RISK-F-0001's ingress claim against the live cluster — the first grade here standing on evidence this repo gathered — contradicts the 'egress: []' claim, which live shows as 443/6443 to anywhere, and surfaces a third policy created the day of the fix whose Ingress policyType carries no rules, which bears on whether enabling ops-warden's gate would fail closed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
ff74a60af4
commit
97fcc56a4d
3 changed files with 185 additions and 1 deletions
84
docs/method/verification.md
Normal file
84
docs/method/verification.md
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
---
|
||||||
|
id: RISK-METHOD-VERIFICATION
|
||||||
|
type: method
|
||||||
|
title: "What this register may verify for itself, and what it must take from owners"
|
||||||
|
status: adopted
|
||||||
|
owner: risk-nexus
|
||||||
|
adopted: "2026-08-20"
|
||||||
|
workplan: RISK-WP-0004-T05
|
||||||
|
review_interval: 180d
|
||||||
|
---
|
||||||
|
|
||||||
|
# Verification
|
||||||
|
|
||||||
|
`RISK-WP-0004-T05` asked what this repo can legitimately establish itself,
|
||||||
|
because two gradings were resting on file comparison. The answer was found by
|
||||||
|
trying, on 2026-08-20, rather than by reasoning about it.
|
||||||
|
|
||||||
|
## The rule
|
||||||
|
|
||||||
|
**A register may look. It may not touch, and it may not conclude on a system's
|
||||||
|
behalf.**
|
||||||
|
|
||||||
|
Verification here means: running a read-only command a reporter has already
|
||||||
|
named, or that answers a question the register itself wrote down as open, and
|
||||||
|
recording exactly what came back.
|
||||||
|
|
||||||
|
Permitted:
|
||||||
|
|
||||||
|
- read-only reads of live state (`kubectl get`, `bao policy read`, an HTTP
|
||||||
|
probe of a documented endpoint);
|
||||||
|
- comparing what is deployed against what a repo said is deployed;
|
||||||
|
- recording the discrepancy and routing it as a **question**.
|
||||||
|
|
||||||
|
Not permitted:
|
||||||
|
|
||||||
|
- any write, apply, patch, restart or rotation — including one that would
|
||||||
|
obviously improve things;
|
||||||
|
- concluding what a defect means for a system this repo does not own. The
|
||||||
|
system stays authoritative about itself (`INTENT.md`);
|
||||||
|
- verifying instead of asking. The owner is asked first; verification settles
|
||||||
|
what an owner cannot see or has invited someone to check.
|
||||||
|
|
||||||
|
`rapp-postgres` declined to check the NetworkPolicy on `flex-auth`'s behalf,
|
||||||
|
saying that would be reporting on a system they do not own. That was right
|
||||||
|
**for a reporter**. This register is the downstream party whose grade depended
|
||||||
|
on the answer, and `flex-auth` explicitly named the command and asked for
|
||||||
|
someone with credentials to run it. Those two positions are compatible.
|
||||||
|
|
||||||
|
## What this host can actually reach — established 2026-08-20
|
||||||
|
|
||||||
|
| Target | Result | Consequence |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Kubernetes (`railiance01`) | **reads work** — `kubectl get ns`, `get networkpolicy -o json` | Live cluster state is verifiable by this register |
|
||||||
|
| OpenBao (`bao.coulomb.social`) | **403 permission denied** on `token lookup` and `policy read` | Policy claims are not verifiable here; `RISK-F-0009` rests on file comparison |
|
||||||
|
|
||||||
|
The asymmetry is worth stating plainly: **the register can check what the
|
||||||
|
cluster admits, and cannot check what the secret store permits.** Every grade
|
||||||
|
touching an OpenBao policy is therefore a grade on a document, and says so.
|
||||||
|
|
||||||
|
That is not a gap to close by acquiring credentials. A risk register holding
|
||||||
|
production secret-store access has traded a verification problem for a much
|
||||||
|
worse one. If OpenBao claims need verifying, the right answer is for the owner
|
||||||
|
to run the read and report it, which is what `ops-warden` did — the obstacle
|
||||||
|
there was an expired token, not the arrangement.
|
||||||
|
|
||||||
|
## Recording a verification
|
||||||
|
|
||||||
|
One file per verification in `docs/verifications/`, `RISK-V-NNNN`, stating the
|
||||||
|
command, the raw result, what it confirms, what it contradicts, and what it
|
||||||
|
does not establish. It names the findings it bears on, and those findings link
|
||||||
|
back.
|
||||||
|
|
||||||
|
A verification is evidence, not a ruling. It can move a grade; it does not
|
||||||
|
close a finding on its own, and it never speaks for the owning repo.
|
||||||
|
|
||||||
|
## Verification and the cadence ladder
|
||||||
|
|
||||||
|
A verification that contradicts something is a check that is **not clean**: the
|
||||||
|
affected findings reset to `instant`. A verification that confirms what was
|
||||||
|
already recorded is clean, and may be exactly the evidence a rung is built on.
|
||||||
|
|
||||||
|
The first one (`RISK-V-0001`) did both — it confirmed the ingress claim
|
||||||
|
`RISK-F-0001` was graded on, contradicted the egress claim in the same message,
|
||||||
|
and surfaced a third policy nobody had mentioned that bears on `RISK-F-0002`.
|
||||||
100
docs/verifications/2026-08-20-flex-auth-networkpolicy.md
Normal file
100
docs/verifications/2026-08-20-flex-auth-networkpolicy.md
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
---
|
||||||
|
id: RISK-V-0001
|
||||||
|
type: verification
|
||||||
|
title: "flex-auth NetworkPolicy, verified against the live cluster"
|
||||||
|
date: "2026-08-20"
|
||||||
|
verified_by: risk-nexus
|
||||||
|
method: "read-only kubectl against railiance01"
|
||||||
|
findings: [RISK-F-0001, RISK-F-0002]
|
||||||
|
result: "ingress claim confirmed; egress claim contradicted; one policy not previously reported"
|
||||||
|
---
|
||||||
|
|
||||||
|
# RISK-V-0001 — the NetworkPolicy, actually looked at
|
||||||
|
|
||||||
|
`RISK-F-0001` was graded twice on a fact nobody had checked. `flex-auth` said
|
||||||
|
so honestly — "I can tell you what is specified, not what is admitted" — and
|
||||||
|
named the command that would settle it. This register ran that command.
|
||||||
|
|
||||||
|
```
|
||||||
|
kubectl -n flex-auth get networkpolicy -o json
|
||||||
|
```
|
||||||
|
|
||||||
|
## What is confirmed
|
||||||
|
|
||||||
|
**The ingress claim is exactly right**, and now rests on the live cluster
|
||||||
|
rather than a manifest:
|
||||||
|
|
||||||
|
| Policy | Ingress from | Port |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `flex-auth-user-engine` | `namespaceSelector: user-engine` **and** `podSelector: user-engine` | 8080/TCP |
|
||||||
|
| `flex-auth-tenant-engine` | `namespaceSelector: tenant-engine` **and** `podSelector: tenant-engine` | 8080/TCP |
|
||||||
|
|
||||||
|
Created 2026-08-09 and 2026-08-08 respectively — eleven days old, predating the
|
||||||
|
caller-authentication work, as `flex-auth` said. The reachable set during the
|
||||||
|
`A0` period was one workload per Deployment, not the cluster.
|
||||||
|
|
||||||
|
`RISK-F-0001`'s `L2` grade is therefore **verified**, not inferred. That is the
|
||||||
|
first grade in this register standing on evidence this repo gathered itself.
|
||||||
|
|
||||||
|
## What is contradicted
|
||||||
|
|
||||||
|
`flex-auth` stated `egress: []` — "empty, i.e. none at all". **Live, all three
|
||||||
|
policies permit egress to any destination on TCP 443 and 6443**, with no `to`
|
||||||
|
selector.
|
||||||
|
|
||||||
|
```json
|
||||||
|
"egress": [{"ports": [{"port": 443, "protocol": "TCP"},
|
||||||
|
{"port": 6443, "protocol": "TCP"}]}]
|
||||||
|
```
|
||||||
|
|
||||||
|
6443 is the Kubernetes API server, which ADR-0004's TokenReview needs, so its
|
||||||
|
presence is unsurprising. 443 to anywhere is a different statement from "none
|
||||||
|
at all".
|
||||||
|
|
||||||
|
This does **not** change `RISK-F-0001`'s grade — the finding is about who can
|
||||||
|
reach the decision surface, and ingress is what governs that. It does change
|
||||||
|
the evidence base, and it matters because the same sentence has been repeated
|
||||||
|
into two records.
|
||||||
|
|
||||||
|
Routed to `flex-auth` as a question rather than a correction: does the
|
||||||
|
committed manifest say `egress: []`, in which case the deployed policy differs
|
||||||
|
from the file, or did the message misdescribe the manifest? Only they can say
|
||||||
|
which, and the two answers mean very different things.
|
||||||
|
|
||||||
|
## What was not previously reported
|
||||||
|
|
||||||
|
A **third** policy exists: `flex-auth-ops-warden`, created 2026-08-19T12:47Z —
|
||||||
|
the same day `flex-auth` reported the fix.
|
||||||
|
|
||||||
|
```
|
||||||
|
podSelector: app.kubernetes.io/name=flex-auth-ops-warden
|
||||||
|
policyTypes: [Ingress, Egress]
|
||||||
|
ingress: (no rules)
|
||||||
|
egress: 443, 6443
|
||||||
|
```
|
||||||
|
|
||||||
|
`policyTypes` includes `Ingress` with no ingress rules, which in Kubernetes
|
||||||
|
means **deny all ingress**. On its face, nothing can reach that pin.
|
||||||
|
|
||||||
|
**This bears directly on `RISK-F-0002`.** The remaining question there is
|
||||||
|
whether enabling `policy.enabled` breaks signing on availability grounds now
|
||||||
|
that the attestation hazard has lifted. If the flex-auth pin that `ops-warden`
|
||||||
|
is meant to call admits no ingress, then enabling a `fail_closed` gate against
|
||||||
|
it would fail closed — every `warden sign` would stop.
|
||||||
|
|
||||||
|
The register is **not** concluding that. A policy may be mid-rollout, the pin
|
||||||
|
may not be the one `ops-warden` targets, and a second policy elsewhere may
|
||||||
|
admit the traffic. What the register is doing is putting the observation in
|
||||||
|
front of both owners before either of them flips a switch, which is precisely
|
||||||
|
what `RISK-F-0002` exists to prevent happening blind.
|
||||||
|
|
||||||
|
## Limits of this verification
|
||||||
|
|
||||||
|
- Read-only, and a point-in-time snapshot of 2026-08-20.
|
||||||
|
- It confirms what the API server admits **as specified**. Whether the CNI
|
||||||
|
enforces NetworkPolicy at all is a cluster property this check does not
|
||||||
|
establish, and `flex-auth` was right to flag it.
|
||||||
|
- OpenBao could not be checked: `bao token lookup` and
|
||||||
|
`bao policy read agent-high-risk-boundary` both return **403 permission
|
||||||
|
denied** from this host, the same wall `ops-warden` hit. `RISK-F-0009`
|
||||||
|
therefore still rests on file comparison.
|
||||||
|
|
@ -4,7 +4,7 @@ type: workplan
|
||||||
title: "Run the register: make the cadence actually happen, and close the gaps the first week found"
|
title: "Run the register: make the cadence actually happen, and close the gaps the first week found"
|
||||||
domain: infotech
|
domain: infotech
|
||||||
repo: risk-nexus
|
repo: risk-nexus
|
||||||
status: proposed
|
status: active
|
||||||
owner: the-custodian
|
owner: the-custodian
|
||||||
topic_slug: risk-nexus
|
topic_slug: risk-nexus
|
||||||
created: "2026-08-20"
|
created: "2026-08-20"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue