How to securely manage user plans and Row-Level Permissions (RLS) in Supabase tables?

Hi all Question 1: I have a 'public.users' table where I store each user's default plan. When a user is inserted into the 'auth.users' table, a trigger fires and creates their entry in that table with their user_id (NEW.uid) and the default plan ('free'). The issue arises with the table insertion as I had to use a policy based on the user_id; otherwise, it fails. The policy is: (auth.uid() = id). I want users to only read their own rows but allow writing and updating only through a trigger. Is this behavior possible? Is it the most secure method? How could I improve it to prevent crafty users from updating their plan to premium? Question 2: Additionally, I'm using Next.js 14, and due to code requirements, sometimes I have to perform database reads/writes in client components. I know I should avoid this, ensuring requests aren't launched from the client, but sometimes it's challenging. Could this pose a security problem? Or with proper RLS (Row-Level Security) configuration on tables, should it not be an issue? Question 3: Lastly, as mentioned, users will have both free and premium plans, each with its limitations when saving or creating certain things in the database. Would this restriction also be managed using RLS? The documentation seems concise for me to achieve something this complex independently. Could you recommend any resources or information that elaborates on this aspect of RLS? Thank you in advance for your potential help, any suggestion to improve is welcome!! :supafire: :supafire:
2 Replies
garyaustin
garyaustin2y ago
1) Block insert with RLS. Then make your trigger function security definer so it can bypass RLS. 2) Supabase was initially designed mainly for a client browser environment. RLS is the means of limiting access and you need that if you every make your URL/anon_key public which is normal to do as it will be in a browser. 3) RLS would be a way to restrict based on a user table having their level and using that in RLS. You can also make that part of the JWT with app_metadata instead of table if desired. https://github.com/supabase-community/supabase-custom-claims https://github.com/point-source/supabase-tenant-rbac And this is my repository for simple table user properties and how to do RLS for all methods. https://github.com/GaryAustin1/custom-properties
FlaskDev
FlaskDevOP2y ago
Thanks for the help! 🙌🏼

Did you find this page helpful?