risk-nexus/findings/RISK-F-0007-unverified-tenant-boundary.md
tegwick 00106ffcdd Operator decisions on RISK-F-0006 and RISK-F-0007
F-0006: backup spend approved, no ceiling stated. Permission is no longer
the blocker; the embargo still needs a demonstrated restore.

F-0007: pragmatic default before production — accepted (not closed, keeps
its severity, review interval and production re-score, stays visible in
the register), with a written on-request path so a named consumer
boundary can be verified when someone asks. The acceptance expires at the
production transition, which is an event and not a date.

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

155 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: RISK-F-0007
type: finding
title: "No consumer's tenant boundary is verified anywhere"
status: accepted
reported_by: net-kingdom
reported_via: risk-nexus
routed_by: risk-nexus
date_reported: "2026-08-19"
date_filed: "2026-08-19"
system: estate
environment: build
fix_owner: per-consumer, on request
fix_tracking: unset
related: [RISK-F-0004, RISK-F-0005]
# Graded by risk-nexus 2026-08-19 — docs/rulings/2026-08-19-second-grading.md
severity: high
severity_at_production: critical
impact: I3
likelihood: L3
fidelity_modifier: false
production_rescore: true
disclosure: embargoed
embargo_condition: "a verification exists for at least one consumer boundary"
embargo_since: "2026-08-19"
embargo_review: "2026-09-18"
escalation: answered
escalation_trigger: 4
escalation_status: assigned
escalation_answered: "2026-08-19"
escalation_answered_by: the-custodian
escalation_act: assign
accepted_by: the-custodian
accepted_on: "2026-08-19"
accepted_until: "production transition (hard expiry, not a date)"
decision: "pragmatic default before production — carried unverified; verification of a named consumer boundary on request"
last_reviewed: "2026-08-19"
review_by: "2026-09-18"
graded_by: risk-nexus
ruling: RISK-RULING-2026-08-19-B
---
# 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` × `L3``critical` — 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` × `L3``critical` — 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.