You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[security] driver-turso remote face: find / count / update / delete / create apply no tenant scope (only distinct() refuses), where the local face scopes every door by DriverOptions.tenantId #21226
Filing gate: ① a defect with named landing sites, under the reach exception for possible data disclosure. ⚠️ Classes and positions only. The claim's first step is measuring the reach (see below), before any fix.
Filed by domain:engine#1 (seat post #6367, session_017xfMoEjKUuSh2xYB8sCozp) from #21185's os-dev-report, out_of_scope_findings[0]. Reader who acts: triage grades and routes; driver-turso is this lane's. ⛔ Not a claim.
The positions (read at origin/main)
packages/drivers/driver-turso/src/turso-driver.ts: the remote branches of find, findOne, count, update, delete, updateMany and deleteMany hand RemoteTransport no DriverOptions, so options.tenantId never reaches the remote statement. The local face routes every one of these doors through SqlDriver.applyTenantScope.
packages/drivers/driver-turso/src/remote-transport.ts: the remote update and delete compile a WHERE on the primary key only.
The source already states the gap for one door. The distinct() arm of turso-driver.ts refuses a tenant-scoped call because "no remote read here applies [the tenant scope], so an answer would list every organization's values". The other doors answer instead of refusing.
Contract
ADR-0131 D8 (accepted): the engine 「threads the same value to Layer 0 (computeTenantLayer0Filter) and to every driver」.
Whether the engine's Layer 0 tenant filter already narrows these reads and writes end to end on a remote-mode, tenant-scoped deployment, so that the driver-level scope is defence in depth rather than the only fence. Measure it through a public door: GET / PATCH / DELETE /api/v1/data/:object as a member of one organization, on a remote-mode datasource holding another organization's rows.
Whether any hosted remote database holds more than one organization's rows, or each organization has its own database.
If (1) shows a cross-organization answer at a public door, this card is p0 by the same rule #21185 carries. If (1) holds and (2) is one organization per database, it is defence in depth, and the grade drops accordingly.
Dedupe
mcp__github__search_issues, repo-scoped, open and closed: "driver-turso remote transport tenant scope tenantId ignored find update delete create organization remote face". 21 hits, none on this gap. The nearest:
Filing gate: ① a defect with named landing sites, under the reach exception for possible data disclosure.⚠️ Classes and positions only. The claim's first step is measuring the reach (see below), before any fix.
Filed by
domain:engine#1(seat post #6367,session_017xfMoEjKUuSh2xYB8sCozp) from #21185'sos-dev-report,out_of_scope_findings[0]. Reader who acts: triage grades and routes;driver-tursois this lane's. ⛔ Not a claim.The positions (read at
origin/main)packages/drivers/driver-turso/src/turso-driver.ts: the remote branches offind,findOne,count,update,delete,updateManyanddeleteManyhandRemoteTransportnoDriverOptions, sooptions.tenantIdnever reaches the remote statement. The local face routes every one of these doors throughSqlDriver.applyTenantScope.packages/drivers/driver-turso/src/remote-transport.ts: the remoteupdateanddeletecompile aWHEREon the primary key only.createdoes not stamp the caller's organization (injectTenantOnInsert). PR fix(driver-sql,driver-turso)!: refuse an upsert whose conflict lands on another organization's row (#21185) #21225 ([security] driver upsert: a tenant-scoped upsert keyed on a globally-unique business column can merge into, and re-parent, another tenant's row #21185) adds that stamp for theupsertdoor only.distinct()arm ofturso-driver.tsrefuses a tenant-scoped call because "no remote read here applies [the tenant scope], so an answer would list every organization's values". The other doors answer instead of refusing.Contract
ADR-0131 D8 (accepted): the engine 「threads the same value to Layer 0 (
computeTenantLayer0Filter) and to every driver」.Seam:
spec:DriverOptions.tenantId → runtime:TursoDriver remote branches (find, count, update, delete, create) | consumer: the remote libSQL transport.What decides the real reach (measure first)
GET/PATCH/DELETE /api/v1/data/:objectas a member of one organization, on a remote-mode datasource holding another organization's rows.If (1) shows a cross-organization answer at a public door, this card is p0 by the same rule #21185 carries. If (1) holds and (2) is one organization per database, it is defence in depth, and the grade drops accordingly.
Dedupe
mcp__github__search_issues, repo-scoped, open and closed: "driver-turso remote transport tenant scope tenantId ignored find update delete create organization remote face". 21 hits, none on this gap. The nearest:SqlDrivermethods the remote face does not override answer from the placeholder:memory:Knex database —introspectSchema()returns no tables,distinct()a 500,findWithWindowFunctions()a raw SQLite error #20055 (closed): the inherited methods answering from the placeholder database, wheredistinct()gained its refusal.upsertdoor, being fixed in PR fix(driver-sql,driver-turso)!: refuse an upsert whose conflict lands on another organization's row (#21185) #21225.Dedupe words:
remote face tenant scope·TursoDriver tenantId ignored·remote create organization stamp·RemoteTransport update where idGenerated by Claude Code