diff --git a/INTENT.md b/INTENT.md deleted file mode 100644 index 04a631e..0000000 --- a/INTENT.md +++ /dev/null @@ -1,125 +0,0 @@ -# INTENT — risk-nexus - -## Why this repo exists - -`risk-nexus` is where the estate holds what it knows is wrong, what might be -wrong, and what the outside world requires of it — with a severity, an owner, -and a date. It serves `risk.coulomb.social`. - -**Owned by `the-custodian`**, alongside `policy-nexus`. One of its duties is -deciding what must reach the operator personally rather than sitting in a -register. - -Before this repo existed, three things had nowhere to live. - -**Findings landed in whichever document was open.** The estate's largest known -gap — that no consumer's tenant boundary is verified anywhere, which is -Broken Object Level Authorization, top of the OWASP API Security Top 10 since -that list launched — is currently open question 3 in an unratified draft -standard. It was found by research, it has no owner, no severity, and no date. -A finding recorded in the document that happened to discover it is a finding -that disappears when that document is superseded. - -**Disclosure had no mechanism.** In build mode the estate publishes everything, -which is right: there are no users to expose. That stops being right at -production, when the same architecture disclosure a consumer must read becomes -a map for an attacker. There is currently no way to hold a finding while it is -fixed and publish it once it is — only publish-now or forget. - -**Regulation was consulted and discarded.** Whether key destruction satisfies -an erasure obligation, whether the estate is an in-scope entity under a given -regime, what a procurement rule requires — each was researched at the moment -someone needed it and never retained. The same question gets asked twice and -the answer silently expires. - -## What it owns - -- **Finding intake.** Security, architecture, operational and compliance - findings, from any source: research, review, incident, external report. -- **Severity and triage.** What this actually risks, how likely, how bad. -- **Remediation tracking** — not remediation. Who owns the fix, what state it - is in, and whether it has stalled. -- **Disclosure timing.** Whether a finding is publishable now, embargoed until - fixed, or permanently restricted; and the record that a delay was deliberate - rather than a document quietly going missing. -- **Regulatory intake**, scoped to regulation bearing on the estate — rules - constraining data it holds, markets it sells into, or obligations it has - taken on. Moved here from `policy-nexus`, because deciding what a rule - demands of us is a judgement about risk, not an act of publishing. -- **The escalation rule.** What must be discussed with the operator personally - rather than recorded and routed. This is the duty `the-custodian` carries as - owner, and the rule itself must be written down rather than exercised by - instinct. - -## What it does not own - -- **Fixing anything.** A finding is routed to the repo that owns the defect, - which fixes it under its own workplan. A risk service that fixes things - becomes a second engineering team with no boundary. -- **Publication.** `policy-nexus` is the publication surface. This repo decides - *whether and when* something is published; it does not host it. -- **Blocking delivery.** In build mode a finding is information, not a gate. - If that changes it will be a deliberate decision recorded here, not a habit - that accretes. -- **Legal advice.** A regulatory record states what a source said and when. - What the estate must therefore do is the owning repo's decision. -- **Deciding what canon says.** Canon is `the-custodian`'s and NetKingdom's. A - finding may say a standard is wrong; it cannot amend one. - -## The failure this repo must avoid - -A risk register nobody reads is worse than no register, because it converts -"we did not know" into "we knew and did nothing" while changing no behaviour. -Two consequences for design: - -- **Findings must expire or escalate.** A finding that has sat untouched past - its review date is itself a finding. Silence is not resolution. -- **The register must be small enough to read.** Recording everything makes - nothing legible. If a finding would not change anyone's decision, it is a - note, not a risk. - -## The escalation duty - -Most findings should be routed and tracked without the operator's attention. -Some must not be. Deciding which is the substance of the oversight `the- -custodian` holds here, and getting it wrong in either direction is a failure: -escalating everything makes the operator the queue, escalating nothing makes -the register a place where serious things go quiet. - -The rule is not yet written. Candidate triggers, to be settled rather than -assumed: anything exposing real tenant data; anything creating a legal or -regulatory obligation; anything requiring spend; anything where two repos -disagree about who owns the fix; and any finding whose remediation has stalled -past a stated interval. - -## Relationship to the rest of the estate - -`risk-nexus` reads from everywhere, decides severity and timing, and routes -work to the repo that owns it. It publishes through `policy-nexus` and never -directly. Like that repo, it is downstream by construction and must not become -a second source of truth — a finding is a claim about a system, and the system -remains authoritative about itself. - -The register is no longer empty. `RISK-F-0001` arrived on 2026-08-17: a live -authorization bypass in `flex-auth`, self-reported during a framework review. -Three more defects surfaced in the same round and are recorded inside it as -visible-but-unfiled, pending this repo setting the precedent for what warrants -a record of its own. - -**The first finding already tested the deferral.** Controlled disclosure is -recorded above as deferred to production, on the reasoning that build mode has -no users to expose. `RISK-F-0001` is a live authorization bypass in the service -every other service trusts, and today the choice is publish or hold with -nothing in between. That may still be the right deferral — but it is now a -decision taken with a real case in hand rather than a hypothetical one. - -Also waiting: the unverified tenant boundary, the absent noisy-neighbour -characterisation, and the erasure-versus-audit tension — open questions in -NetKingdom's *Tenancy Posture*, which is a draft and not a register. - -## What good looks like - -Nobody is surprised. A gap that was known is recorded with a severity and an -owner, a regulation that applies was found before it was needed, a fix that -stalled was visible while it stalled, and the things that genuinely needed the -operator's judgement reached them without the things that did not. diff --git a/README.md b/README.md index f8d8628..5acbfd3 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,3 @@ # risk-nexus -Risk register and regulatory intake for the estate. Serves -`risk.coulomb.social`. Owned by `the-custodian`. - -Holds findings — security, architecture, operational, compliance — with a -severity, an owner and a date; decides whether and when each is published; and -decides which must reach the operator personally rather than sitting in a -register. - -It does not fix things: findings route to the repo that owns the defect. It -does not host: `policy-nexus` is the publication surface. - -- Intent: `INTENT.md` +A risk management service. \ No newline at end of file diff --git a/findings/RISK-F-0001-flex-auth-unauthenticated-check.md b/findings/RISK-F-0001-flex-auth-unauthenticated-check.md deleted file mode 100644 index 3fa88fd..0000000 --- a/findings/RISK-F-0001-flex-auth-unauthenticated-check.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: RISK-F-0001 -type: finding -title: "flex-auth /v1/check authenticates no caller" -status: open -reported_by: flex-auth -reported_via: rapp-postgres -routed_by: rapp-postgres -date_reported: "2026-08-17" -system: flex-auth -environment: production -fix_owner: flex-auth -fix_tracking: FLEX-WP-0015-T02 -# The three fields below are risk-nexus's, not the reporter's. Left unset -# deliberately: the reporter says what is true, this repo says how bad it is -# and who hears about it (INTENT, "What it does not own"). -severity: unset -disclosure: unset -escalation: unset ---- - -# RISK-F-0001 — flex-auth authenticates no caller on the decision surface - -## What is true - -`POST /v1/check` and `POST /v1/batch_check` authenticate no caller. Any -workload with network reach to the ClusterIP Service can assert any subject and -any tenant and receive an authoritative **allow**. - -`flex-auth` is the estate's authorization oracle. Every service that delegates -a decision to it is relying on an answer that anyone able to reach the pod can -obtain for any identity they care to name. - -Self-reported by `flex-auth` as `A0` on their own inbound surface, in their -Tenancy Posture review. Their words: "flex-auth is the estate's authorization -oracle and it trusts its callers completely." - -## How it was found - -Not by a probe, an incident, or an alert. By `flex-auth` assessing themselves -against the Tenancy Posture A ladder during a review they were asked to do — -and their own note says they did not know they were carrying it. - -That provenance matters for triage: nothing was watching for this, and nothing -would have found it. It has presumably been true for as long as the endpoint -has existed. - -## Exposure, as far as the reporter stated it - -- The Service is `ClusterIP`, so reach requires a workload inside the cluster. -- No claim was made that network policy restricts which workloads can reach it, - and this record does not assume one. **If a default-deny NetworkPolicy fronts - the service, that materially changes the exposure and should be verified - rather than inferred** — `flex-auth` did not state it either way, and I have - not checked, because doing so would be reporting on a system I do not own. - -## What makes it worse than a single service's defect - -A false allow from this endpoint is not confined to `flex-auth`. It is the -answer other services act on. `tenant-engine` separately reports that its own -mutations are authorized by `flex-auth` and that direct authority over its rows -would mean "privilege escalation across NetKingdom rather than data tampering -confined to one store". The same reasoning applies to a forged allow. - -## Owner and state - -`flex-auth` owns the fix and has tracked it as `FLEX-WP-0015-T02`, to ship -through the staged-promotion path rather than a direct apply. They classify it -as the only urgent item of their five follow-ups. Nothing is asked of them by -this record beyond what they have already committed to. - -## What this repo is asked to decide - -1. **Severity.** Not the reporter's to set. -2. **Disclosure.** Build mode is currently public-by-default, and this is - precisely the class of finding where that stops being obviously right — a - live authorization bypass in the service every other service trusts. The - controlled-disclosure scheme this repo anticipates does not exist yet, so - the choice today is publish or hold, with no mechanism between them. -3. **Escalation.** Whether this reaches the operator personally. The candidate - triggers in INTENT include "anything exposing real tenant data" — this - exposes the decision that governs access to it, which may or may not be the - same thing, and that judgement is this repo's. - -## Related, reported at the same time and not yet filed - -Three further defects surfaced from the same review round. They are recorded -here so they are visible, not filed as findings, because filing them was not -asked for: - -- `tenant-engine` — `events()` returns the entire event log unfiltered. A live - cross-tenant read at `E2`. -- `audit-core` — read path applies no tenant filter; a credential with - `may_read` can read any tenant's events. Bounded by deployment (`may_read: - false` on the production sender) and not by code. Tracked `AUDIT-WP-0008-T04`. -- `apps-pg` (`railiance-platform`) — no backup configured at all: no - `barmanObjectStore`, no retention policy, `BestEffort` QoS. `R0` there means - no recovery, not merely no erasure policy. - -All four were found the same way, by repos reading their own code against a -ladder, within a day of each other. That is a fact about the estate's -observability worth carrying into triage: **four live defects, none found by -monitoring.**