docs(db): guardrail listInstallations/listRepositories against tenant-facing misuse - #6328
Conversation
…-facing misuse (#4797) Audited every query touching installations, repositories, and repository_settings for query-layer tenant-scoping. Every single-row lookup (getRepositorySettings, getRepository, getInstallation, listInstalledRepoFullNamesForInstallation) is already correctly scoped by an explicit parameter at the SQL WHERE clause. listInstallations/listRepositories have no WHERE clause at all -- every row, every call. Traced all 30+ call sites: every one is internal cross-repo maintenance/sweep machinery or an admin/maintainer/owner- role-gated dashboard route (verified via canSessionAccessPath/ requireAppRole). No live leak exists today, but the isolation is only true because every current caller happens to be admin-gated, not because the query itself can't return cross-tenant data -- exactly the class of risk the issue's problem statement calls out. Added doc-comment guardrails pointing future callers at the correctly-scoped alternatives, so a future Rent-a-Loop customer endpoint reaching for these by habit doesn't leak every tenant's repos/installations.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-16 02:14:26 UTC
Review summary Nits — 6 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionPartially addressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6328 +/- ##
=======================================
Coverage 95.60% 95.60%
=======================================
Files 596 596
Lines 47121 47121
Branches 14999 14999
=======================================
Hits 45049 45049
Misses 1290 1290
Partials 782 782
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Summary
Closes #4797. Audited every query touching
installations,repositories, andrepository_settings— the shared tables Rent-a-Loop's architecture (#4783) reuses — for tenant-scoping at the query layer, not just application logic.Single-row lookups are correctly scoped:
getRepositorySettings,getRepository,getInstallation,listInstalledRepoFullNamesForInstallationall take their scoping key as an explicit function parameter, so the query itself can't return another tenant's row regardless of caller behavior.Bulk queries have a real gap, now guardrailed:
listInstallations/listRepositorieshave no WHERE clause — every row, every call. Traced all 30+ call sites (src/queue/**,src/review/**,src/github/backfill.ts,src/api/routes.ts,src/services/**): every one is internal cross-repo maintenance machinery or an admin/maintainer/owner-role-gated dashboard route (verified viacanSessionAccessPath/requireAppRoleat each API call site — e.g./v1/repos,/v1/installationsall require an authorized admin session). No live leak exists today, but the isolation only holds because every current caller happens to be admin-gated, not because the query itself enforces it — exactly the risk class the issue's problem statement calls out. Added doc-comment guardrails on both functions pointing at the correctly-scoped alternatives, so a future customer-facing endpoint doesn't reach for them by habit.Full audit findings posted on #4797.
Test plan
npx tsc --noEmitcleannpm run test:ci(full local gate incl. drift checks, coverage, engine parity, MCP/miner packs, UI build): green, verified via literal captured exit codenode_modules/@loopover/*copies exist in this checkout that could mask a real failureorigin/main, no conflicts