RLS policies implementation#95
Conversation
EmeditWeb
left a comment
There was a problem hiding this comment.
Review verdict: ❌ Request changes (security)
RLS as defense-in-depth is the right idea, but as submitted these policies do not protect anything and one pattern is an active footgun.
1. Not enforced for any application traffic. The migration header says "The API layer sets a Postgres session variable app.current_wallet before making queries." It doesn't — there is no SET LOCAL app.current_wallet / set_config anywhere in src/. And the API uses the service-role client (src/database/supabase.client.ts:52), which bypasses RLS entirely. So the checked acceptance criterion "Users can only access their own data — MET" is not accurate; the policies are inert for the running app.
2. Blanket-permissive write policies (footgun). The file has 8 policies using WITH CHECK (true) / USING (true), e.g.:
CREATE POLICY "Service role can insert loans" ON public.loans FOR INSERT WITH CHECK (true);
CREATE POLICY "Service role can update loans" ON public.loans FOR UPDATE USING (true);Service role bypasses RLS, so these true policies don't apply to service role — they apply to non-service-role sessions, i.e. exactly the sessions RLS should restrict. The moment any non-service path exists (the whole premise of adding RLS), any user could insert/update any loan/position. To restrict writes to service role, write no policy for other roles and rely on the bypass — don't add USING(true).
3. RLS may not be enabled on all target tables. Prior migrations enable RLS on loans/nonces/liquidity_positions, but I don't see ENABLE ROW LEVEL SECURITY for learner_profiles/vouches/vendors/sponsor_pools — their policies would be dormant. Please verify/add.
4. Scope creep: edits .github/PULL_REQUEST_TEMPLATE.md (+59/-20), unrelated to RLS.
To move forward: add a request-scoped, non-service-role DB client that runs SET LOCAL app.current_wallet = $wallet per authenticated request; delete the 8 true write policies; add ENABLE ROW LEVEL SECURITY on the uncovered tables; drop the template edit.
|
Removed 8 blanket-permissive write policies - Deleted WITH CHECK (true) / USING (true) policies that were security footguns |
|
Summary Changes: |
|
Your PR Summary structure is poor and doesn't follow standards, please rework on it. |
|
I just updated the pr now and gave it a proper structure |
Closes #32
Summary
This PR introduces Row Level Security (RLS) for Supabase to strengthen database security by restricting user access to only their own records. It lays the foundation for enforcing wallet-scoped authorization while preserving service-role access for trusted backend operations.
Why
Previously, database access relied primarily on the service-role client, which bypasses RLS entirely. This created a security gap where user-facing operations were not protected by database-level authorization.
This PR introduces the necessary database policies and client infrastructure required to support secure, wallet-scoped access.
Changes
Database
Service Layer
Testing