Hi, and thanks for OpenStudy. I ran a static RLS analyzer (pgrls) over migrations/ and spotted two small hardening items:
- Perf: the
*_user_isolation policies (~16, on courses / deliverables / app_settings / …) call current_setting('app.user_id', …) per row in USING. Wrapping it in (select current_setting(…)) makes it a per-statement InitPlan (the Supabase-documented RLS perf pattern) — predicate-equivalent, so visibility is unchanged.
- Defense-in-depth: the RLS tables
ENABLE but don't FORCE ROW LEVEL SECURITY, so the table-owner role still bypasses the policies. ALTER TABLE … FORCE ROW LEVEL SECURITY closes that — unless a SECURITY DEFINER path relies on owner-bypass, in which case it's worth a deliberate skip.
Happy to send a PR for the (select …) wrap (the safe, mechanical one) if useful.
Hi, and thanks for OpenStudy. I ran a static RLS analyzer (pgrls) over
migrations/and spotted two small hardening items:*_user_isolationpolicies (~16, oncourses/deliverables/app_settings/ …) callcurrent_setting('app.user_id', …)per row inUSING. Wrapping it in(select current_setting(…))makes it a per-statement InitPlan (the Supabase-documented RLS perf pattern) — predicate-equivalent, so visibility is unchanged.ENABLEbut don'tFORCE ROW LEVEL SECURITY, so the table-owner role still bypasses the policies.ALTER TABLE … FORCE ROW LEVEL SECURITYcloses that — unless a SECURITY DEFINER path relies on owner-bypass, in which case it's worth a deliberate skip.Happy to send a PR for the (select …) wrap (the safe, mechanical one) if useful.