Reputation: 1202
I recently learned about row-level security policies in SQL, and love the idea of being able to run important security logic inside the database. However, I'm not sure how to make the workflow for updating RLS policies as good as updating API code is.
Since RLS policies are essentially just stateless logic, it feels like I should be able to define them all in an sql schema file that is checked into git and run on each deploy to idempotently set the policies.
We can get some of the way there by using drop if exists
, e.g.:
drop policy if exists "everyone can read" on patterns;
create policy "everyone can read" on patterns for select using (auth.role() = 'anon');
This seems pretty good, but it's not quite truly declarative, because it won't drop any policies that still exist in the database from a previous version of the schema. Can I drop all existing policies for a table and then recreate them? Or is there another way to go about this?
Upvotes: 2
Views: 612
Reputation: 1202
I figured out how to drop all policies. There are two catalog tables that list policies; pg_policy
has low-level info, whereas pg_policies
is more useful for this because it includes the table names directly.
-- Drop all existing policies
do
$$
declare
rec record;
begin
for rec in (SELECT tablename, policyname FROM pg_policies)
loop
execute 'drop policy "'||rec.policyname||'" on '||rec.tablename;
end loop;
end;
$$;
Upvotes: 1
Reputation: 246308
You have two options:
query pg_policy
for all policies on a table and drop them
drop all policies that ever existed in any version of your schema
Upvotes: 0