Files
OmniRoute/docs
Diego Rodrigues de Sa e Souza e7f9fec251 fix(api): enforce API-key ownership on files and batches — null-owner records and anonymous listing (#13749)
GHSA-2jm2-mpx8-6523 and GHSA-m3hp-hq9g-fpmv, one root cause.

`getApiKeyRequestScope()` never rejects: with the default REQUIRE_API_KEY=false
the client-api policy admits both a missing and an invalid bearer as anonymous,
and the scope comes back `{ apiKeyId: null, isSessionAuth: false }`. The
`/v1/files` and `/v1/batches` routes then treated "null" as permissive in two
different ways:

- GHSA-m3hp — the list routes coerced `apiKeyId || undefined`, and the DB layer
  reads `undefined` as "no owner filter", so an anonymous or invalid-bearer
  caller got every tenant's file and batch metadata, the same unfiltered view as
  the operator's dashboard.
- GHSA-2jm2 — the single-record checks were `record.apiKeyId !== null && …`, so
  a record with no owner short-circuited to "allowed" for any caller: read,
  download raw content, delete, cancel, or use as a batch input. Null-owner
  records are common — every dashboard-session upload, and every batch output
  file inheriting a session batch's owner, which carries model responses.

`api_key_id` has existed since the table was created (migration 028), so a null
owner is not a legacy row; it is an unattributable write. No doc described it
as shared — API_REFERENCE says files are scoped per key — and batch_api.test.ts
pinned the by-id exposure as expected behaviour.

One rule now, in `_helpers/apiKeyScope.ts`:

- `canAccessOwnedRecord(scope, owner)`: a dashboard session is the instance
  operator and may act on any record; an API key acts on its own records only;
  a null owner is denied to every non-session caller. Applied to files
  GET / DELETE / content, batches GET / DELETE / cancel, and the batch-create
  input-file check.
- `resolveListScope(scope)`: an explicit union for list/count reads — scoped to
  the presented key (a key wins even alongside a session cookie), instance-wide
  only for a session without a key, and 401 otherwise, including for a bearer
  that does not resolve to a key. There is no default that widens a read.

This follows the GHSA-wvxc shape already used by the delete-completed sweep.

Behaviour change: the anonymous upload → batch → download flow no longer works
without an API key, because a null owner cannot be attributed.

Subsumes #13683: it moved `scopeCheck` into the shared helper so a session can
cancel any batch — kept, and its test ported — but it also kept null-owner
records open on the premise they predate ownership tracking, which migration
028 contradicts.

Tests are red-first. batch_api's by-id case is flipped to 404 with a negative
assertion; batch-deletion-route-logic now imports the real helper instead of a
local copy that had silently diverged from production; the two integration
tests present a real key, since their subject is limits and rate logging, not
auth.

Co-authored-by: Markus Hartung <mail@hartmark.se>
2026-09-15 13:25:13 -03:00
..
2026-06-29 08:40:06 -03:00

title, version, lastUpdated
title version lastUpdated
OmniRoute Documentation 3.8.40 2026-06-28

OmniRoute Documentation

Navigable index of the OmniRoute documentation set. Topics are grouped by intent so you can find what you need quickly.

Looking for the project overview, install steps, or release notes? See the root README.md, ROADMAP.md, CHANGELOG.md, and CONTRIBUTING.md.


For Non-Tech Users

Simple guides for using OmniRoute — no technical background needed.

getting-started/

guides/


For Tech Users

Technical documentation for developers and contributors.

architecture/

How the system is put together — read these to understand the runtime, code layout, and resilience model.

reference/

Lookup material — API surface, environment variables, CLI flags, provider catalog.

frameworks/

Pluggable subsystems exposed to clients, agents, and operators.

routing/

Combo routing, scoring, and replay.

security/

Guardrails, compliance, stealth, and the mandatory patterns for handling public credentials and error messages.

compression/

Prompt compression engines, rules, and language packs.

providers/

Provider-specific integration guides.

comparison/

ops/

Release, deployment, proxies, tunnels, coverage, database, monitoring.

diagrams/

Mermaid sources and exported SVG/PNG diagrams referenced from the docs above. See diagrams/README.md.

i18n/

Translated mirrors of the documentation in 65 locales (plus the English originals — 66 languages in total). See i18n/README.md for the supported language list.

screenshots/

Static screenshots used by the dashboard and the README. Not part of the doc body.


Auto-generated artifacts

  • reference/PROVIDER_REFERENCE.md is generated by scripts/docs/gen-provider-reference.ts from src/shared/constants/providers.ts. Do not edit by hand.
  • The /docs UI is backed by Fumadocs MDX source generation from the subfolders above.