Severity: High (architectural) · Target window: before external pentest
Finding: No RLS anywhere; the app connects via one asyncpg pool on an owner role, so tenant isolation rests entirely on ~184 hand-written WHERE user_id = predicates. One omission = cross-tenant breach of keys/billing/credits/USDC/hosted-agent code+secrets/PII. No confirmed missing filter was found.
Why deferred: Not a one-commit fix — needs either (a) a non-owner per-request DB role + SET LOCAL app.user_id + USING (...) policies on every tenant table, or (b) a centralized tenant-scoping query helper + automated predicate tests. Multi-day, high regression risk.
Cheap risk-closer first (in progress): audit every user-scoped table query to confirm an ownership filter is present — get to "confirmed complete," not "no confirmed missing" — even while full RLS stays deferred.
Source: ~/wayforth-security/SECURITY_AUDIT_2026-06.md §3.6 DATA-1.
Severity: High (architectural) · Target window: before external pentest
Finding: No RLS anywhere; the app connects via one asyncpg pool on an owner role, so tenant isolation rests entirely on ~184 hand-written
WHERE user_id =predicates. One omission = cross-tenant breach of keys/billing/credits/USDC/hosted-agent code+secrets/PII. No confirmed missing filter was found.Why deferred: Not a one-commit fix — needs either (a) a non-owner per-request DB role +
SET LOCAL app.user_id+USING (...)policies on every tenant table, or (b) a centralized tenant-scoping query helper + automated predicate tests. Multi-day, high regression risk.Cheap risk-closer first (in progress): audit every user-scoped table query to confirm an ownership filter is present — get to "confirmed complete," not "no confirmed missing" — even while full RLS stays deferred.
Source: ~/wayforth-security/SECURITY_AUDIT_2026-06.md §3.6 DATA-1.