From 7f1424dbcffa280e78a0c3dc2f846d662432ba14 Mon Sep 17 00:00:00 2001 From: tegwick Date: Tue, 1 Sep 2026 02:41:32 +0200 Subject: [PATCH] Sweep risk inbox and reconcile findings Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663 --- REGISTER.md | 26 +++---- docs/regulatory/audit-retention-basis.md | 11 ++- docs/rulings/2026-09-01-inbox-sweep.md | 78 +++++++++++++++++++ .../RISK-F-0002-ops-warden-sign-ungated.md | 42 +++++++--- ...ops-warden-read-boundary-ungraded-lanes.md | 43 +++++++--- ...004-tenant-engine-unfiltered-event-read.md | 40 +++++++--- ...-F-0005-audit-core-unfiltered-read-path.md | 37 ++++++--- ...ISK-F-0006-apps-pg-no-backup-configured.md | 10 ++- .../RISK-F-0007-unverified-tenant-boundary.md | 51 ++++++++---- ...008-audit-retention-legal-basis-assumed.md | 8 +- ...y-set-covers-a-third-of-high-risk-lanes.md | 50 ++++++++---- ...-0010-embedded-backup-webdav-credential.md | 63 +++++++++++++++ 12 files changed, 363 insertions(+), 96 deletions(-) create mode 100644 docs/rulings/2026-09-01-inbox-sweep.md diff --git a/REGISTER.md b/REGISTER.md index 8fddd4d..1a4ab84 100644 --- a/REGISTER.md +++ b/REGISTER.md @@ -2,21 +2,21 @@ Generated by `tools/register_index.py` from `findings/`. Do not edit by hand. Last built 2026-09-01. -8 live of 10 findings; 3 notes below the floor. +2 live of 10 findings; 3 notes below the floor. ## Findings | ID | Finding | System | Severity | Disclosure | Escalation | Fix owner | Status | Cadence | Next check | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| [RISK-F-0010](findings/RISK-F-0010-embedded-backup-webdav-credential.md) | Forgejo backup source embeds a WebDAV credential default | railiance-platform | unset | unset | unset | railiance-platform | open | instant (0) | — | -| [RISK-F-0009](findings/RISK-F-0009-openbao-deny-set-covers-a-third-of-high-risk-lanes.md) | agent-high-risk-boundary denies 6 of 17 high-risk lanes; the direct bao path is unprotected for the rest | railiance-platform | **high** | embargoed | none | railiance-platform | open | instant (0) | **due** | +| [RISK-F-0010](findings/RISK-F-0010-embedded-backup-webdav-credential.md) | Forgejo backup source embeds a WebDAV credential default | railiance-platform | low | embargoed | none | railiance-platform | open | instant (0) | **due** | +| [RISK-F-0009](findings/RISK-F-0009-openbao-deny-set-covers-a-third-of-high-risk-lanes.md) | agent-high-risk-boundary denies 6 of 17 high-risk lanes; the direct bao path is unprotected for the rest | railiance-platform | **high** | public | none | railiance-platform | fixed | instant (0) | **due** | | [RISK-F-0008](findings/RISK-F-0008-audit-retention-legal-basis-assumed.md) | The legal basis for retaining audit facts against an erasure request has been assumed, never established | audit-core | medium | public | **answered** (t2, answered) | risk-nexus | accepted | instant (0) | **due** | -| [RISK-F-0007](findings/RISK-F-0007-unverified-tenant-boundary.md) | No consumer's tenant boundary is verified anywhere | estate | **high** | embargoed | **answered** (t4, assigned) | per-consumer, on request | accepted | 1h (1) | **due** | +| [RISK-F-0007](findings/RISK-F-0007-unverified-tenant-boundary.md) | No consumer's tenant boundary is verified anywhere | estate | **high** | public | **answered** (t4, assigned) | per-consumer, on request | fixed | instant (0) | **due** | | [RISK-F-0006](findings/RISK-F-0006-apps-pg-no-backup-configured.md) | apps-pg has no backup configured at all: R0 means no recovery | railiance-platform | **high** | public | **answered** (t3, answered) | railiance-platform | fixed | instant (0) | **due** | -| [RISK-F-0005](findings/RISK-F-0005-audit-core-unfiltered-read-path.md) | audit-core read path applies no tenant filter; the bound is deployment, not code | audit-core | medium | public | none | audit-core | mitigated | instant (0) | **due** | -| [RISK-F-0004](findings/RISK-F-0004-tenant-engine-unfiltered-event-read.md) | tenant-engine events() returns the entire event log unfiltered | tenant-engine | medium | embargoed | none | tenant-engine | open | instant (0) | **due** | -| [RISK-F-0003](findings/RISK-F-0003-ops-warden-read-boundary-ungraded-lanes.md) | ops-warden agent read-boundary does not fire on ungraded catalog lanes | ops-warden | medium | embargoed | none | ops-warden | mitigated | 8h (2) | **due** | -| [RISK-F-0002](findings/RISK-F-0002-ops-warden-sign-ungated.md) | ops-warden signs SSH certificates with no authorization decision, and its unblock is now unsafe | ops-warden | medium | embargoed | **withdrawn** (t6, withdrawn-hazard-window-closed) | ops-warden | open | instant (0) | **due** | +| [RISK-F-0005](findings/RISK-F-0005-audit-core-unfiltered-read-path.md) | audit-core read path applies no tenant filter; the bound is deployment, not code | audit-core | medium | public | none | audit-core | fixed | instant (0) | **due** | +| [RISK-F-0004](findings/RISK-F-0004-tenant-engine-unfiltered-event-read.md) | tenant-engine events() returns the entire event log unfiltered | tenant-engine | medium | public | none | tenant-engine | fixed | instant (0) | **due** | +| [RISK-F-0003](findings/RISK-F-0003-ops-warden-read-boundary-ungraded-lanes.md) | ops-warden agent read-boundary does not fire on ungraded catalog lanes | ops-warden | medium | public | none | ops-warden | fixed | instant (0) | **due** | +| [RISK-F-0002](findings/RISK-F-0002-ops-warden-sign-ungated.md) | ops-warden signs SSH certificates with no authorization decision, and its unblock is now unsafe | ops-warden | medium | public | **withdrawn** (t6, withdrawn-hazard-window-closed) | ops-warden | fixed | instant (0) | **due** | | [RISK-F-0001](findings/RISK-F-0001-flex-auth-unauthenticated-check.md) | flex-auth /v1/check authenticates no caller | flex-auth | **high** | public | **withdrawn** (t1, withdrawn-before-sending) | flex-auth | fixed | instant (0) | **due** | ## Constraints @@ -34,10 +34,8 @@ Silence never buys a softer grade — see `docs/method/dependencies.md`. | Finding | Who | What would change | Default if silent | On | | --- | --- | --- | --- | --- | -| RISK-F-0009 | railiance-platform | embargo lifts on coverage; live verification would refine the grade but is not required for it | the eight uncovered paths stand as recorded and the finding is re-raised | 2026-09-03 | +| RISK-F-0010 | railiance-platform | the finding becomes fixed and the embargo lifts | the low grade and embargo stand; missing fix tracking is recorded as a stalled remediation | 2026-09-15 | | RISK-F-0008 | audit-core | a working keyed commitment narrows RISK-REG-0001 to retained-by-obligation categories only | encrypt-then-hash recorded as the only known route, and the retention period recorded as unstateable | 2026-11-17 | -| RISK-F-0007 | user-engine | 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-F-0005 | audit-core | likelihood rises to L3 if any other production credential carries may_read | graded on the sender alone, as stated; the wider question is recorded as unanswered | 2026-09-19 | ## Embargoes @@ -45,11 +43,7 @@ Held from publication with a stated condition. A hold with no moving condition i | Finding | Since | Lifts when | Re-decided | | --- | --- | --- | --- | -| RISK-F-0009 | 2026-08-20 | railiance-platform reports the deny set covers every high-risk lane with a KV path (live verification refines the grade, it is not the condition) | — | -| RISK-F-0007 | 2026-08-19 | a verification exists for at least one consumer boundary | 2026-09-18 | -| RISK-F-0004 | 2026-08-19 | the read path filters by tenant in code | 2026-09-18 | -| RISK-F-0003 | 2026-08-19 | RISK-F-0009 resolved — the OpenBao deny set covers every high-risk lane with a KV path | 2026-09-18 | -| RISK-F-0002 | 2026-08-19 | FLEX-WP-0015-T02 shipped and ops-warden policy.enabled true in production | 2026-11-17 | +| RISK-F-0010 | 2026-09-01 | the provider credential is revoked or invalidated and the literal source default is removed | 2026-09-15 | ## Notes (below the floor) diff --git a/docs/regulatory/audit-retention-basis.md b/docs/regulatory/audit-retention-basis.md index cee7903..105e722 100644 --- a/docs/regulatory/audit-retention-basis.md +++ b/docs/regulatory/audit-retention-basis.md @@ -8,10 +8,11 @@ determined: "2026-08-20" finding: RISK-F-0008 sources_read: "GDPR Arts 5, 6, 17, 21, 32; Recitals 49, 65; HGB §257; AO §147" external_review: none -last_checked: "2026-08-20T10:02:42Z" -next_check: "2026-08-20T11:02:42Z" -cadence: 1h -clean_streak: 1 +last_checked: "2026-09-01T00:38:53Z" +next_check: "2026-09-01T00:38:53Z" +cadence: instant +clean_streak: 0 +checked_by: "codex/risk-nexus" --- # RISK-REG-0001 — the retention basis, written down @@ -176,3 +177,5 @@ table as a compliance claim. Default if none of these arrives by 2026-11-17: this table stands as the estate's stated position, with the achieved-versus-target gap recorded as unresolved. + +- **2026-09-01** — not clean: the dated review found that the 2026-08-20 target-period amendment had never advanced this record's check state. The targets now stand explicitly; achievement under the shared backup horizon and keyed-commitment feasibility remain open. Cadence 1h → instant; checked again immediately. diff --git a/docs/rulings/2026-09-01-inbox-sweep.md b/docs/rulings/2026-09-01-inbox-sweep.md new file mode 100644 index 0000000..863ae09 --- /dev/null +++ b/docs/rulings/2026-09-01-inbox-sweep.md @@ -0,0 +1,78 @@ +--- +id: RISK-RULING-2026-09-01-A +type: ruling +title: "Inbox sweep: tenant boundaries, the agent read boundary, and an embedded backup credential" +status: adopted +owner: risk-nexus +adopted: "2026-09-01" +review_interval: 6m +disclosure: embargoed +embargo_condition: "RISK-F-0010's provider credential is revoked or invalidated and the literal source default is removed" +embargo_since: "2026-09-01" +embargo_review: "2026-09-15" +revision: "adopted-1" +last_reviewed: "2026-09-01" +--- + +# Inbox sweep — 2026-09-01 + +One unread owner reply triggered this review. Reading the dependent owner +records then showed that six findings were being carried in states older than +their evidence, while one filed finding had never been graded. + +## Decisions + +| Finding | Prior state | Ruling | Evidence that changes it | +| --- | --- | --- | --- | +| `RISK-F-0002` | open, embargoed | fixed, public | zone-aware signing gate complete; authenticated live decision; focused Warden suite passes | +| `RISK-F-0003` | mitigated, embargoed | fixed, public | absent/unknown grade fails safe; explicit grade required in CI; dependent OpenBao layer fixed | +| `RISK-F-0004` | open, embargoed | fixed, public | broad `events()` removed from production protocol; three tenant-scope tests pass | +| `RISK-F-0005` | mitigated, public | fixed, public | bounded production E2 isolation run plus sixty current focused tests | +| `RISK-F-0007` | accepted, embargoed | fixed, public | the zero-verification claim is disproved by Audit, Tenant, and User Engine evidence | +| `RISK-F-0009` | open, embargoed | fixed, public | generated source/live deny coverage is total for concrete paths; dedicated identity proved deny-wins | +| `RISK-F-0010` | open, ungraded | low, embargoed | embedded provider credential remains in source; endpoint evidence limits impact to the write-only backup lane | + +The historical grades of fixed findings remain on their records. A fix changes +the status and disclosure decision; it does not rewrite how serious the defect +was while live. + +## Cross-tenant boundary ruling + +`RISK-F-0007` said **no** consumer boundary was verified anywhere. That exact +claim is now false. Audit Core supplies the strongest evidence: a bounded +production run against three calibrated cross-tenant attacks, with safe custody +and cleanup. Tenant Engine supplies a dedicated scoped-store suite, and User +Engine supplies negative unit and integrated scenarios. These records do not +prove every consumer correct. They close the estate-wide absence; a future +consumer-specific defect is filed under that owner rather than kept alive under +a sentence no longer true. + +The current focused checks run by Risk Nexus are: + +- ops-warden: 137 passed; +- audit-core: 60 passed; +- tenant-engine: 3 passed; +- user-engine: 18 passed; +- railiance-platform high-risk boundary invariant: 19 lanes, 14 concrete + entries, 5 non-concrete/non-KV, 0 uncovered, 0 errors. + +## Embedded credential ruling + +`RISK-F-0010` is `I2` because the observed endpoint is a write-only file drop, +the stored material is ciphertext, and the recovery key is separate. It is +`L2` because the literal is recoverable from granted repository or log access. +That yields `low`. The current value is not probed: testing an exposed +credential would expand the action beyond safe triage and is unnecessary to +grade the stated facts. + +The disclosure state is embargoed because announcing the recoverable credential +while its validity is unknown and its literal remains in source shortens the +route to the defect. The embargo lifts after two observable events: provider +revocation or invalidation, and removal of the source default. Restore evidence +is requested as closure evidence for the governed replacement, but its absence +does not justify reproducing or testing the old value. + +No escalation trigger fires today. Railiance Platform owns the fix; there is no +known use, disclosure, legal duty, new spend, ownership dispute, or fourteen-day +stall. The dated wait makes that last statement expire rather than persist as +prose. diff --git a/findings/RISK-F-0002-ops-warden-sign-ungated.md b/findings/RISK-F-0002-ops-warden-sign-ungated.md index 0e877e5..4fb6ee1 100644 --- a/findings/RISK-F-0002-ops-warden-sign-ungated.md +++ b/findings/RISK-F-0002-ops-warden-sign-ungated.md @@ -2,7 +2,8 @@ id: RISK-F-0002 type: finding title: "ops-warden signs SSH certificates with no authorization decision, and its unblock is now unsafe" -status: open +status: fixed +owner: risk-nexus reported_by: ops-warden reported_via: ops-warden routed_by: ops-warden @@ -10,7 +11,7 @@ date_reported: "2026-08-18" system: ops-warden environment: production fix_owner: ops-warden -fix_tracking: ZONE-WP-0001 / WARDEN-WP-0032 (successor; the original framing is superseded) +fix_tracking: ZONE-WP-0001 / WARDEN-WP-0032-T02 (finished 2026-08-22) fix_tracking_superseded: "WARDEN-WP-0007 (archived 2026-07-08) / FLEX-WP-0007 (finished 2026-06-29)" related: [RISK-F-0001] # Graded by risk-nexus 2026-08-19 — docs/rulings/2026-08-19-first-grading.md @@ -23,20 +24,27 @@ production_rescore: false constraint_on: RISK-F-0001 constraint_severity: lifted constraint: "LIFTED 2026-08-19 — flex-auth /v1/check now authenticates callers (RISK-F-0001 fixed). Enabling policy.enabled is now an availability question for ops-warden, no longer an attestation hazard." -disclosure: embargoed -embargo_condition: "FLEX-WP-0015-T02 shipped and ops-warden policy.enabled true in production" -embargo_since: "2026-08-19" -embargo_review: "2026-11-17" +disclosure: public +publication: pending-handover +publication_id: risk-f-0002-ops-warden-signing-authorization-gap +publication_path: "findings/ops-warden-signing-authorization-gap/v1/index.html" +publication_subtitle: "Production SSH signing once had no per-request authorization decision; the retired global switch is now replaced by an enforced zone-aware gate." +revision: "fixed-1" +last_reviewed: "2026-09-01" +review_interval: 6m +embargo_lifted: "2026-08-22 — zone-aware authorization replaced the retired global gate and passed the live authenticated-caller check" +embargo_was_since: "2026-08-19" escalation: withdrawn escalation_trigger: 6 escalation_status: withdrawn-hazard-window-closed -last_checked: "2026-08-21T07:32:09Z" -next_check: "2026-08-21T07:32:09Z" +date_fixed: "2026-08-22" +last_checked: "2026-09-01T00:32:44Z" +next_check: "2026-09-01T00:32:44Z" cadence: instant clean_streak: 0 graded_by: risk-nexus ruling: RISK-RULING-2026-08-19 -checked_by: "risk-nexus" +checked_by: "codex/risk-nexus" --- # RISK-F-0002 — the SSH signing gate is off, and turning it on is now the more dangerous move @@ -381,3 +389,19 @@ whatever staleness convention this register settles rather than inventing a second one. That is worth answering properly and is recorded as an open item for the next round. - **2026-08-21** — not clean: owner replied; see the dated check section Cadence instant → instant; checked again immediately. + +## Closure — 2026-09-01: the successor control is live + +`WARDEN-WP-0032-T02` is done. The production configuration rejects the retired +global `policy.enabled` and `policy.fail_closed` switches; the signing PEP now +uses compiled security-zone membership, the stance returned by `flex-auth`, and +a local per-zone failure mode. The owner re-ran the authenticated caller path +against the migrated operator configuration and received a live allow decision +with decision id `decision:f3f7c88f9585582a`. + +Risk Nexus also ran the current policy, configuration, routing, and read-boundary +regressions: **137 passed**. The defect this finding carried—production signing +proceeding with no per-request authorization decision—is gone. The finding is +`fixed`; the embargo lifts and publication is handed over. + +- **2026-09-01** — not clean: the zone-aware successor is implemented and live-verified; status fixed and embargo lifted. Cadence instant → instant; checked again immediately. diff --git a/findings/RISK-F-0003-ops-warden-read-boundary-ungraded-lanes.md b/findings/RISK-F-0003-ops-warden-read-boundary-ungraded-lanes.md index 75b1e82..c451e3a 100644 --- a/findings/RISK-F-0003-ops-warden-read-boundary-ungraded-lanes.md +++ b/findings/RISK-F-0003-ops-warden-read-boundary-ungraded-lanes.md @@ -2,7 +2,8 @@ id: RISK-F-0003 type: finding title: "ops-warden agent read-boundary does not fire on ungraded catalog lanes" -status: mitigated +status: fixed +owner: risk-nexus reported_by: ops-warden reported_via: ops-warden routed_by: ops-warden @@ -10,7 +11,7 @@ date_reported: "2026-08-19" system: ops-warden environment: production fix_owner: ops-warden -fix_tracking: WARDEN-WP-0032-T05 (done) / T06 (structural) +fix_tracking: WARDEN-WP-0032-T05 / T06 (done 2026-08-22) # Graded by risk-nexus 2026-08-19 — docs/rulings/2026-08-19-first-grading.md severity: medium severity_at_production: medium @@ -19,18 +20,25 @@ impact: I4 likelihood: L2 fidelity_modifier: false production_rescore: false -disclosure: embargoed -embargo_condition: "RISK-F-0009 resolved — the OpenBao deny set covers every high-risk lane with a KV path" -embargo_since: "2026-08-19" -embargo_review: "2026-09-18" +disclosure: public +publication: pending-handover +publication_id: risk-f-0003-ops-warden-agent-read-boundary-blind-spot +publication_path: "findings/ops-warden-agent-read-boundary-blind-spot/v1/index.html" +publication_subtitle: "An omitted catalog grade silently bypassed the agent credential boundary; omission now fails safe and CI rejects it." +revision: "fixed-1" +last_reviewed: "2026-09-01" +review_interval: 6m +embargo_lifted: "2026-08-22 — catalog omission fails safe, CI requires explicit grades, and RISK-F-0009's direct-OpenBao layer is fixed" +embargo_was_since: "2026-08-19" escalation: none -last_checked: "2026-08-21T06:32:10Z" -next_check: "2026-08-21T14:32:10Z" -cadence: 8h -clean_streak: 2 +date_fixed: "2026-08-22" +last_checked: "2026-09-01T00:32:44Z" +next_check: "2026-09-01T00:32:44Z" +cadence: instant +clean_streak: 0 graded_by: risk-nexus ruling: RISK-RULING-2026-08-19 -checked_by: "worsch" +checked_by: "codex/risk-nexus" --- # RISK-F-0003 — the agent read-boundary has a fourteen-lane blind spot @@ -228,3 +236,16 @@ finding's own fix has landed. is expired, which is also why `RISK-F-0009` rests on a file comparison. - **2026-08-20** — clean check: checked against the inbox and the owner's record; nothing moved. Cadence instant → 1h (1 clean in a row); next check 2026-08-20 11:02Z. - **2026-08-21** — clean check: fix state read from the owner's file: WARDEN-WP-0032-T05 done; nothing else moved. Cadence 1h → 8h (2 clean in a row); next check 2026-08-21 14:32Z. + +## Closure — 2026-09-01: omission is no longer permissive + +The remaining structural task is done. `RouteEntry` now resolves an absent or +unknown grade fail-safe, `is_graded` exposes the distinction, and CI rejects a +catalog lane without an explicit grade. The current focused Warden regression +set passes (**137 tests**), including the omission and OpenBao coverage checks. + +The dependent direct-OpenBao gap is also fixed under `RISK-F-0009`. There is no +remaining live or structural part of this finding, so it moves from `mitigated` +to `fixed` and its embargo lifts. + +- **2026-09-01** — not clean: WARDEN-WP-0032-T06 and the dependent OpenBao coverage are complete; status fixed and embargo lifted. Cadence 8h → instant; checked again immediately. diff --git a/findings/RISK-F-0004-tenant-engine-unfiltered-event-read.md b/findings/RISK-F-0004-tenant-engine-unfiltered-event-read.md index 6143e73..94dcc9d 100644 --- a/findings/RISK-F-0004-tenant-engine-unfiltered-event-read.md +++ b/findings/RISK-F-0004-tenant-engine-unfiltered-event-read.md @@ -2,7 +2,8 @@ id: RISK-F-0004 type: finding title: "tenant-engine events() returns the entire event log unfiltered" -status: open +status: fixed +owner: risk-nexus reported_by: tenant-engine reported_via: flex-auth routed_by: risk-nexus @@ -11,7 +12,7 @@ date_filed: "2026-08-19" system: tenant-engine environment: production fix_owner: tenant-engine -fix_tracking: TEN-IN-0002 +fix_tracking: TEN-WP-0011-T05 (finished 2026-08-29) related: [RISK-F-0001] # Graded by risk-nexus 2026-08-19 — docs/rulings/2026-08-19-second-grading.md severity: medium @@ -21,18 +22,25 @@ impact: I3 likelihood: L1 fidelity_modifier: false production_rescore: true -disclosure: embargoed -embargo_condition: "the read path filters by tenant in code" -embargo_since: "2026-08-19" -embargo_review: "2026-09-18" +disclosure: public +publication: pending-handover +publication_id: risk-f-0004-tenant-engine-unfiltered-event-read +publication_path: "findings/tenant-engine-unfiltered-event-read/v1/index.html" +publication_subtitle: "Tenant Engine's production store protocol exposed an unfiltered event-list method; it now exposes tenant-scoped reads only." +revision: "fixed-1" +last_reviewed: "2026-09-01" +review_interval: 6m +embargo_lifted: "2026-08-29 — unfiltered events() removed from the production protocol and tenant-scoped negative tests landed" +embargo_was_since: "2026-08-19" escalation: none -last_checked: "2026-08-21T07:32:09Z" -next_check: "2026-08-21T07:32:09Z" +date_fixed: "2026-08-29" +last_checked: "2026-09-01T00:32:44Z" +next_check: "2026-09-01T00:32:44Z" cadence: instant clean_streak: 0 graded_by: risk-nexus ruling: RISK-RULING-2026-08-19-B -checked_by: "risk-nexus" +checked_by: "codex/risk-nexus" --- # RISK-F-0004 — the tenant event log is readable across tenants @@ -122,3 +130,17 @@ The correction is the useful part of the exchange, and it is the direction reporters are usually reluctant to push: this register had overstated their exposure for two days, in public-facing language, and they said so plainly. - **2026-08-21** — not clean: owner replied; see the dated check section Cadence 1h → instant; checked again immediately. + +## Closure — 2026-09-01: the broad method is gone + +Tenant Engine reports `TEN-WP-0011-T05` complete: `TenantStore.events()` was +removed from the production protocol and replaced by `events_for(tenant_id)`. +Risk Nexus read the current in-memory, SQLite, and PostgreSQL implementations, +confirmed that all resolve and query by tenant, and ran the dedicated negative +suite: **3 passed**, including absence of the broad method and cross-tenant +isolation. + +That is concrete source and regression evidence for the precise defect. The +finding is `fixed`; the embargo condition is met and publication is handed over. + +- **2026-09-01** — not clean: TEN-WP-0011-T05 removed the broad protocol method and the focused tenant-scope suite passes; status fixed and embargo lifted. Cadence instant → instant; checked again immediately. diff --git a/findings/RISK-F-0005-audit-core-unfiltered-read-path.md b/findings/RISK-F-0005-audit-core-unfiltered-read-path.md index 39dd6cc..47bad83 100644 --- a/findings/RISK-F-0005-audit-core-unfiltered-read-path.md +++ b/findings/RISK-F-0005-audit-core-unfiltered-read-path.md @@ -2,7 +2,8 @@ id: RISK-F-0005 type: finding title: "audit-core read path applies no tenant filter; the bound is deployment, not code" -status: mitigated +status: fixed +owner: risk-nexus reported_by: audit-core reported_via: flex-auth routed_by: risk-nexus @@ -22,23 +23,24 @@ fidelity_modifier: false production_rescore: true disclosure: public publication: pending-handover +publication_id: risk-f-0005-audit-core-unfiltered-read-path +publication_path: "findings/audit-core-unfiltered-read-path/v1/index.html" +publication_subtitle: "Audit Core once relied on a read flag rather than tenant filtering; scoped code and a bounded adversarial production run now enforce the boundary." +revision: "fixed-1" +last_reviewed: "2026-09-01" +review_interval: 6m embargo_lifted: "2026-08-18 — AUDIT-WP-0008-T04 reads done in audit-core's workplan" embargo_was_since: "2026-08-19" escalation: none -last_checked: "2026-08-21T06:29:38Z" -next_check: "2026-08-21T06:29:38Z" +date_fixed: "2026-08-22" +last_checked: "2026-09-01T00:32:44Z" +next_check: "2026-09-01T00:32:44Z" cadence: instant clean_streak: 0 -waiting_on: - - who: audit-core - what: "is may_read false on every production credential, or only on the sender" - since: "2026-08-19" - would_change: "likelihood rises to L3 if any other production credential carries may_read" - default: "graded on the sender alone, as stated; the wider question is recorded as unanswered" - default_at: "2026-09-19" graded_by: risk-nexus ruling: RISK-RULING-2026-08-19-B +checked_by: "codex/risk-nexus" --- # RISK-F-0005 — the audit read path is bounded by a flag, not by code @@ -123,3 +125,18 @@ The `may_read` question — is it false on every production credential, or only on the sender — stays open and matters less now that the bound is in code rather than in a flag. - **2026-08-21** — not clean: AUDIT-WP-0008-T04 reads done in audit-core's workplan since 2026-08-18; embargo condition met, status mitigated. Cadence 1h → instant; checked again immediately. + +## Closure — 2026-09-01: scoped code and adversarial evidence + +The two reasons this remained `mitigated` are now resolved. `AUDIT-WP-0008-T05` +is done and records a bounded production E2 run in which a tenant-A identity +could neither fetch tenant B's event, observe tenant B's correlation slice, nor +append an event as tenant B. Cleanup completed before credential expiry and the +sanitized report records no limitations beyond the attacks attempted. + +Risk Nexus read that artifact and ran the current focused ingestion and sender +suite: **60 passed**. Because tenant scope is enforced in code, the old question +about which credential carries `may_read` no longer changes this finding's +likelihood and its wait is removed. The finding is `fixed`. + +- **2026-09-01** — not clean: the production E2 artifact and current focused tests establish the tenant filter; status fixed. Cadence instant → instant; checked again immediately. diff --git a/findings/RISK-F-0006-apps-pg-no-backup-configured.md b/findings/RISK-F-0006-apps-pg-no-backup-configured.md index 10e03ad..e2bda44 100644 --- a/findings/RISK-F-0006-apps-pg-no-backup-configured.md +++ b/findings/RISK-F-0006-apps-pg-no-backup-configured.md @@ -3,6 +3,7 @@ id: RISK-F-0006 type: finding title: "apps-pg has no backup configured at all: R0 means no recovery" status: fixed +owner: risk-nexus reported_by: railiance-platform reported_via: flex-auth routed_by: risk-nexus @@ -22,9 +23,14 @@ fidelity_modifier: false production_rescore: true disclosure: public publication: pending-handover +publication_id: risk-f-0006-apps-pg-no-backup +publication_path: "findings/apps-pg-no-backup/v1/index.html" +publication_subtitle: "A shared production database had no backup or recovery path; encrypted off-host backup and a demonstrated restore closed the gap." +revision: "fixed-1" +last_reviewed: "2026-08-21" +review_interval: 6m embargo_lifted: "2026-08-20 — backup live, restore demonstrated with matching row counts" -embargo_since: "2026-08-19" -embargo_review: "2026-09-18" +embargo_was_since: "2026-08-19" escalation: answered escalation_trigger: 3 escalation_status: answered diff --git a/findings/RISK-F-0007-unverified-tenant-boundary.md b/findings/RISK-F-0007-unverified-tenant-boundary.md index c3c2b18..61ed2e5 100644 --- a/findings/RISK-F-0007-unverified-tenant-boundary.md +++ b/findings/RISK-F-0007-unverified-tenant-boundary.md @@ -2,7 +2,8 @@ id: RISK-F-0007 type: finding title: "No consumer's tenant boundary is verified anywhere" -status: accepted +status: fixed +owner: risk-nexus reported_by: net-kingdom reported_via: risk-nexus routed_by: risk-nexus @@ -20,10 +21,16 @@ 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" +disclosure: public +publication: pending-handover +publication_id: risk-f-0007-unverified-tenant-boundaries +publication_path: "findings/unverified-tenant-boundaries/v1/index.html" +publication_subtitle: "No consumer tenant boundary had ever been verified; three independent consumers now carry negative boundary evidence." +revision: "fixed-1" +last_reviewed: "2026-09-01" +review_interval: 6m +embargo_lifted: "2026-08-22 — Audit Core completed a bounded adversarial E2 tenant-isolation run; additional Tenant and User Engine tests corroborate the control class" +embargo_was_since: "2026-08-19" escalation: answered escalation_trigger: 4 escalation_status: assigned @@ -34,20 +41,14 @@ 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_checked: "2026-08-21T07:32:10Z" -next_check: "2026-08-21T08:32:10Z" -cadence: 1h -clean_streak: 1 -waiting_on: - - who: user-engine - what: "does anything verify that a caller for tenant A cannot reach tenant B (RISK-V-0002)" - since: "2026-08-20" - would_change: "likelihood falls for user-engine if a verification exists; a defect becomes its own finding if not" - default: "the on-request path is recorded as having produced no answer, which makes the acceptance itself unsupported and is escalated" - default_at: "2026-09-03" +date_fixed: "2026-08-22" +last_checked: "2026-09-01T00:32:44Z" +next_check: "2026-09-01T00:32:44Z" +cadence: instant +clean_streak: 0 graded_by: risk-nexus ruling: RISK-RULING-2026-08-19-B -checked_by: "risk-nexus" +checked_by: "codex/risk-nexus" --- # RISK-F-0007 — nothing checks that tenants stay apart @@ -184,3 +185,19 @@ 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. + +## Closure — 2026-09-01: the zero-verification claim is no longer true + +The embargo and the finding were deliberately phrased around one observable +condition: a verification existing for at least one consumer boundary. Audit +Core now has stronger evidence than that minimum—a bounded adversarial +production E2 run—and its current focused suite passes 60 tests. Tenant Engine's +dedicated scoped-event suite passes 3 tests, and User Engine's current +multi-tenancy, access-profile, and integrated-scenario suites pass 18 tests. + +This does not assert that every consumer boundary is correct. It closes the +precise estate-wide absence this finding recorded; any consumer-specific gap is +filed separately. The unanswered User Engine wait is replaced by direct current +evidence, status moves from accepted to `fixed`, and the embargo lifts. + +- **2026-09-01** — not clean: three consumer boundaries now carry current negative evidence, including one production E2 artifact; status fixed and embargo lifted. Cadence 1h → instant; checked again immediately. diff --git a/findings/RISK-F-0008-audit-retention-legal-basis-assumed.md b/findings/RISK-F-0008-audit-retention-legal-basis-assumed.md index eef8247..5899e2a 100644 --- a/findings/RISK-F-0008-audit-retention-legal-basis-assumed.md +++ b/findings/RISK-F-0008-audit-retention-legal-basis-assumed.md @@ -42,10 +42,10 @@ escalation_answered: "2026-08-20" escalation_answered_by: the-custodian escalation_act: rule decision: "identity in audit records: opaque subject ids preferred, agent identifiers where possible, operator credentials only where necessary, policy decisions tracked to the responsible party; zone-level privacy guarantees may raise the floor" -outstanding: "a defensible retention period per category (waits on audit-core's co-residency horizon), and the trigger list for buying an external answer" +outstanding: "whether the stated target periods are achievable under platform-pg co-residency, and whether a keyed commitment restores erasability" determination: RISK-REG-0001 -last_checked: "2026-08-20T21:36:44Z" -next_check: "2026-08-20T21:36:44Z" +last_checked: "2026-09-01T00:38:53Z" +next_check: "2026-09-01T00:38:53Z" cadence: instant clean_streak: 0 waiting_on: @@ -57,6 +57,7 @@ waiting_on: default_at: "2026-11-17" graded_by: risk-nexus ruling: RISK-RULING-2026-08-19-C +checked_by: "codex/risk-nexus" --- # RISK-F-0008 — the exemption nobody has established @@ -362,3 +363,4 @@ on whether a keyed commitment restores erasability, and the `platform-pg` co-residency horizon that decides whether the stated retention periods are achievable. An accepted risk still gets checked. - **2026-08-20** — not clean: Trigger list ruled: no external determination in build mode; accepted with the legal policy set as the compensating control. Cadence instant → instant; checked again immediately. +- **2026-09-01** — not clean: the regulatory record now states target periods per category; the remaining gap is whether platform-pg co-residency can achieve them, while the keyed-commitment question is unchanged. Grade and acceptance hold. Cadence instant → instant; checked again immediately. diff --git a/findings/RISK-F-0009-openbao-deny-set-covers-a-third-of-high-risk-lanes.md b/findings/RISK-F-0009-openbao-deny-set-covers-a-third-of-high-risk-lanes.md index 4dd62e3..26e2c87 100644 --- a/findings/RISK-F-0009-openbao-deny-set-covers-a-third-of-high-risk-lanes.md +++ b/findings/RISK-F-0009-openbao-deny-set-covers-a-third-of-high-risk-lanes.md @@ -2,7 +2,8 @@ id: RISK-F-0009 type: finding title: "agent-high-risk-boundary denies 6 of 17 high-risk lanes; the direct bao path is unprotected for the rest" -status: open +status: fixed +owner: risk-nexus reported_by: ops-warden reported_via: ops-warden routed_by: ops-warden @@ -10,7 +11,7 @@ date_reported: "2026-08-20" system: railiance-platform environment: production fix_owner: railiance-platform -fix_tracking: unset (railiance-platform) +fix_tracking: RPF-WP-0013 / RAILIANCE-WP-0022 (finished 2026-08-22) filed_as: "RISK-F-0004 by ops-warden; renumbered by risk-nexus 2026-08-20 (id collision)" answers: RISK-F-0003 related: [RISK-F-0003] @@ -21,24 +22,25 @@ impact: I4 likelihood: L2 fidelity_modifier: false production_rescore: false -disclosure: embargoed -embargo_condition: "railiance-platform reports the deny set covers every high-risk lane with a KV path (live verification refines the grade, it is not the condition)" -embargo_since: "2026-08-20" +disclosure: public +publication: pending-handover +publication_id: risk-f-0009-openbao-high-risk-deny-coverage +publication_path: "findings/openbao-high-risk-deny-coverage/v1/index.html" +publication_subtitle: "OpenBao's agent boundary covered only a fraction of high-risk credential lanes; generated source-to-live coverage and deny-wins proof now close the gap." +revision: "fixed-1" +last_reviewed: "2026-09-01" +review_interval: 6m +embargo_lifted: "2026-08-22 — every concrete high-risk KV path is generated into the live deny policy and a dedicated agent identity proved deny-wins" +embargo_was_since: "2026-08-20" escalation: none -last_checked: "2026-08-21T07:32:09Z" -next_check: "2026-08-21T07:32:09Z" +date_fixed: "2026-08-22" +last_checked: "2026-09-01T00:32:44Z" +next_check: "2026-09-01T00:32:44Z" cadence: instant clean_streak: 0 -waiting_on: - - who: railiance-platform - what: "report whether the deny set covers every high-risk lane with a KV path" - since: "2026-08-20" - would_change: "embargo lifts on coverage; live verification would refine the grade but is not required for it" - default: "the eight uncovered paths stand as recorded and the finding is re-raised" - default_at: "2026-09-03" graded_by: risk-nexus ruling: RISK-RULING-2026-08-20 -checked_by: "risk-nexus" +checked_by: "codex/risk-nexus" --- # RISK-F-0009 — the OpenBao half of the agent read-boundary covers a third of the lanes @@ -282,3 +284,21 @@ grade this register makes off a checkout**, including its own method. inference, which is a different thing. `ops-warden` put the correction to them directly and said so. - **2026-08-21** — not clean: owner replied; see the dated check section Cadence 1h → instant; checked again immediately. + +## Closure — 2026-09-01: generated coverage and live deny-wins proof + +`RPF-WP-0013` and `RAILIANCE-WP-0022` consumed the Warden-generated high-risk +path artifact and deployed the result. The source and live readback cover all +**14 concrete entries across 19 high-risk lanes**, with 5 non-concrete or +non-KV lanes correctly classified and **0 uncovered**. A dedicated +`coding-agent-railiance-platform` AppRole carrying the boundary plus one +workload read policy proved deny-wins: data read was denied while metadata +remained readable; the single-use identity was revoked and no secret value was +read. + +Risk Nexus re-ran the current platform invariant on 2026-09-01; it reports +`ok: true`, 19 lanes, 14 concrete entries, and zero errors or uncovered paths. +The condition is met with both generated-source and live-state evidence. The +finding is `fixed`, its wait is removed, and its embargo lifts. + +- **2026-09-01** — not clean: generated and live coverage now span every concrete high-risk KV path with deny-wins evidence; status fixed and embargo lifted. Cadence instant → instant; checked again immediately. diff --git a/findings/RISK-F-0010-embedded-backup-webdav-credential.md b/findings/RISK-F-0010-embedded-backup-webdav-credential.md index dc7dc36..631d691 100644 --- a/findings/RISK-F-0010-embedded-backup-webdav-credential.md +++ b/findings/RISK-F-0010-embedded-backup-webdav-credential.md @@ -3,13 +3,42 @@ id: RISK-F-0010 type: finding title: "Forgejo backup source embeds a WebDAV credential default" status: open +owner: risk-nexus reported_by: railiance-platform reported_via: railiance-platform +routed_by: risk-nexus date_reported: "2026-08-23" +date_filed: "2026-08-23" system: railiance-platform environment: production fix_owner: railiance-platform fix_tracking: unset +# Graded by risk-nexus 2026-09-01 — docs/rulings/2026-09-01-inbox-sweep.md +severity: low +severity_at_production: low +impact: I2 +likelihood: L2 +fidelity_modifier: false +production_rescore: false +disclosure: embargoed +embargo_condition: "the provider credential is revoked or invalidated and the literal source default is removed" +embargo_since: "2026-09-01" +embargo_review: "2026-09-15" +escalation: none +last_checked: "2026-09-01T00:32:44Z" +next_check: "2026-09-01T00:32:44Z" +cadence: instant +clean_streak: 0 +waiting_on: + - who: railiance-platform + what: "revoke or invalidate the provider credential, remove the source default, name fix tracking, and demonstrate governed ciphertext upload plus restore" + since: "2026-09-01" + would_change: "the finding becomes fixed and the embargo lifts" + default: "the low grade and embargo stand; missing fix tracking is recorded as a stalled remediation" + default_at: "2026-09-15" +graded_by: risk-nexus +ruling: RISK-RULING-2026-09-01-A +checked_by: "codex/risk-nexus" --- # RISK-F-0010 — Forgejo backup source embeds a WebDAV credential default @@ -58,3 +87,37 @@ Suggestion, owned by `railiance-platform`: Risk Nexus owns severity, disclosure, escalation, and review cadence. This report intentionally does not assign them. + +## Register ruling — 2026-09-01 + +`low` (`I2` × `L2`), embargoed, no escalation. + +**`I2`: limited to one backup lane on the facts established.** If the embedded +value remains valid, it can authorize an ungoverned write or storage injection +at the Nextcloud file-drop endpoint. Metadata listing and reads were denied, +backup content is ciphertext, and the age recovery private key is separate. +Nothing here establishes disclosure of an existing backup or estate-wide +credential reach. + +**`L2`: recoverable through access the estate does grant.** The value is in Git +history and appeared in captured agent output, so a repository clone or retained +log is a sufficient foothold. Current validity is unknown and is not tested by +this register; unknown is not treated as either live or revoked. + +**Embargoed.** While the source default remains and validity is unresolved, +publishing that a recoverable provider credential exists materially shortens the +path beyond reading the private repository. The hold lifts only when revocation +or invalidation and removal of the literal are both observable. The credential +value, fingerprint, and shape remain excluded from every record and message. + +**No escalation.** There is no evidence of a read, loss, real-person data +exposure, legal notification duty, new spend, ownership dispute, or a stalled +remediation yet. Railiance Platform owns both the source and provider action. +Silence defaults on 2026-09-15 to the existing grade and a recorded stall; it +does not soften the assessment. + +Reasoning: `docs/rulings/2026-09-01-inbox-sweep.md`. + +## Reviews + +- **2026-09-01** — graded from the filed report and a redacted current-source check. The literal default remains; no fix record was found. Cadence starts at instant.