risk-nexus/findings/RISK-F-0007-unverified-tenant-boundary.md
tegwick e482423523 Five owner replies worked through: one fix closed, two grades corrected, one control retired
RISK-F-0006 fixed and public — railiance-platform's restore evidence was
read, not taken: 56s restore, all 13 coulomb_social row counts matching,
plus the BestEffort QoS this register had graded on, plus a failed first
WAL attempt recorded alongside the successful one.

RISK-F-0004 high -> medium. tenant-engine corrected in both directions:
payloads are returned (worse than graded) but there is no HTTP event-read
route, so the live network-reachable read this register wrote down does
not exist. L3 was a reachability claim inherited from a summary and never
tested.

RISK-F-0002: reading (c) confirmed — nothing blocks policy.enabled, it is
off by decision. ADR-0006 retires it in favour of zone-scoped
enforcement. Ruled: the framing is superseded, the risk is not. A control
retired before its replacement exists is still an absent control. The
successor's blocker is 26 of 27 lanes having no identifiable workload,
which is RISK-N-0004 with a number on it.

RISK-F-0009: uncovered count 8 -> 6, corrected by the reporter against
themselves; the token was never expired; and the deployed policy differs
from the file, which moves 'a file is not a safe proxy for the server'
from suspicion to evidence and amends verification.md — including the
admission that fix_tracker.py reads records, and a record can be stale.

RISK-V-0001 reconciled: ops-warden reaches the pin from the node through
a tunnel, so a podSelector ingress rule does not constrain it. The
observation was right and the inference was not.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 09:32:32 +02:00

8.1 KiB
Raw Blame History

id type title status reported_by reported_via routed_by date_reported date_filed system environment fix_owner fix_tracking related severity severity_at_production impact likelihood fidelity_modifier production_rescore disclosure embargo_condition embargo_since embargo_review escalation escalation_trigger escalation_status escalation_answered escalation_answered_by escalation_act accepted_by accepted_on accepted_until decision last_checked next_check cadence clean_streak waiting_on graded_by ruling checked_by
RISK-F-0007 finding No consumer's tenant boundary is verified anywhere accepted net-kingdom risk-nexus risk-nexus 2026-08-19 2026-08-19 estate build per-consumer, on request unset
RISK-F-0004
RISK-F-0005
high critical I3 L3 false true embargoed a verification exists for at least one consumer boundary 2026-08-19 2026-09-18 answered 4 assigned 2026-08-19 the-custodian assign the-custodian 2026-08-19 production transition (hard expiry, not a date) pragmatic default before production — carried unverified; verification of a named consumer boundary on request 2026-08-21T07:32:10Z 2026-08-21T08:32:10Z 1h 1
who what since would_change default default_at
user-engine does anything verify that a caller for tenant A cannot reach tenant B (RISK-V-0002) 2026-08-20 likelihood falls for user-engine if a verification exists; a defect becomes its own finding if not the on-request path is recorded as having produced no answer, which makes the acceptance itself unsupported and is escalated 2026-09-03
risk-nexus RISK-RULING-2026-08-19-B risk-nexus

RISK-F-0007 — nothing checks that tenants stay apart

What is true

No consumer's tenant boundary is verified anywhere in the estate. This is Broken Object Level Authorization, first on the OWASP API Security Top 10 since that list launched.

It is currently open question 3 in NetKingdom's Tenancy Posture, which is a draft and not a register — which is precisely why INTENT.md names it as the thing that had nowhere to live. Filing it here does not amend that standard, does not ratify it, and does not settle the question it poses. A finding may say a standard is wrong; it cannot change one.

Why it is a finding and not a research note

The floor asks whether an owner could act and whether recording it changes a decision. Both are yes, and the second is now demonstrable rather than asserted: every time a repo has looked at its own boundary this month, it has found a defect. RISK-F-0004 (tenant-engine, unfiltered event read) and RISK-F-0005 (audit-core, no tenant filter on read) are two instances found by two repos in one round.

An absent verification is not the same as an absent boundary. But the sample so far is two for two, and the register does not get to assume the unexamined cases are better than the examined ones.

What is not established

  • Whether any consumer boundary is in fact correct. Nobody has checked; that is the finding.
  • Who owns the fix. fix_owner is unset deliberately — see the escalation.

Register ruling — 2026-08-19

high today (I3 × L3), critical at production, embargoed, escalated on trigger 4 (ownership).

Today's impact is I3 and not I4 because there is no real tenant data behind the unverified boundary yet; the consequence of one occurrence is bounded by what the estate is currently holding. L3: no additional step is needed by anything already inside, and the two confirmed instances say the reach is real rather than theoretical.

production_rescore: true, and this is the finding that matters most on that day: at production the same defect is I4 × L3critical — and the re-score is not optional.

Escalation, trigger 4. This is the ownership case the trigger was written for, in its purest form: the defect is estate-wide, no repo owns "every consumer's boundary", and a routing exchange cannot settle it because there is nobody to route it to. Only the operator can say who verifies tenant boundaries — a repo, a test suite, a review obligation on each consumer — or that the estate deliberately carries it unverified until production.

Until that is answered, fix_owner stays unset rather than being assigned to a repo that has not accepted it. An unowned finding with an honest unset is better than a routed one nobody agreed to.

Reviews

  • 2026-08-19 — filed and graded. Open at review: has an owner been named; have any further instances been found; is the Tenancy Posture question still open.

Operator decision — 2026-08-19: pragmatic default, tighter control on request

The custodian ruled: before production, carry it. Verifying every consumer's tenant boundary is not attempted as a programme now; a named boundary is verified when someone asks for it.

The finding moves to accepted — which in this register is not closed. It keeps its severity, its review interval and its production re-score, and it stays in REGISTER.md where an accepted risk is supposed to be visible while it is being carried.

The acceptance expires at the production transition, and that is an event, not a date. production_rescore is true: at production the same defect is I4 × L3critical — and the acceptance does not survive it. Nobody has to remember; make check lists it under what is owed at that transition.

The on-request path

So that "on request" is a mechanism and not a sentiment:

  • Who may ask — any repo that consumes or is consumed by another, the operator, or an outside counterparty through the operator.
  • What they get — verification scoped to one named consumer boundary, not a general audit. The request names the consumer and what would have to be true.
  • Who does it — the owning repo of that consumer. This register scopes and records; it does not verify, and it does not fix.
  • What it produces — a dated verification record here. If the boundary holds, that is evidence and this finding's likelihood falls for that consumer. If it does not, that is a finding of its own with its own owner, filed normally.

Requests arrive as a message to risk-nexus and appear in the register within one review cycle.

What the register keeps saying while this is carried

The two-for-two record stands: every repo that has looked at its own boundary this month found a defect (RISK-F-0004, RISK-F-0005). The acceptance does not make that less true, and this finding is the place it stays visible. If a third instance arrives, the pragmatic default is worth re-taking before production rather than at it.

Reviews

  • 2026-08-19 — escalation answered, accepted until production with verification on request. Open at review: any request received; any further instances found; whether production is close enough to re-take the default.

Check — 2026-08-20: the on-request path has been walked once

RISK-V-0002 — verification of user-engine's tenant boundary, requested through the documented path on 2026-08-20.

user-engine was chosen because they are a consumer with a boundary who is not already carrying a finding about one. Using tenant-engine (RISK-F-0004) or audit-core (RISK-F-0005) would have tested the path against systems already known to fail it, which would have proved nothing about the path.

The acceptance recorded here rests on that path working. Until 2026-08-20 it had never been used, which made it a plan rather than a route. All three outcomes are informative and the least comfortable one is the most useful: if nothing comes back, the estate learns that it is carrying this finding on an assumption that asking works.

Grade unchanged. Nothing about the boundary itself has moved.

  • 2026-08-20 — not clean: On-request verification walked for the first time: RISK-V-0002 asks user-engine. Cadence instant → instant; checked again immediately.
  • 2026-08-21 — clean check: no answer yet from user-engine; nothing about the boundary moved. Cadence instant → 1h (1 clean in a row); next check 2026-08-21 08:32Z.