Skip to content

Commit

Permalink
Apply RLS policy to all users (not just the current role)
Browse files Browse the repository at this point in the history
Rails schema/migrations should be isolated from the upper user/role layer. Leverage the BYPASS RLS flag so we can connect with a admin user (or database owner) which by default bypasses rls (for migrations etc.), but all other roles should be subject to the RLS policy. Tables should not be hardwired to a specific role within postgres, otherwise we get exceptions such as  `role "koleo_rls" cannot be dropped because some objects depend on it` when trying to drop the role (messy).
  • Loading branch information
stevschmid committed Apr 24, 2024
1 parent 0893779 commit 99bf325
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions lib/rls/migration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ module Migration
# RESET rls.tenant_id will not remove the setting, current_setting(missing_ok=FALSE) will still return ''
# There is no way to remove a setting right now in PostgreSQL, so missing_ok=FALSE is not useful
# https://stackoverflow.com/questions/50923911/how-to-remove-configuration-parameter/50929568#50929568
def rls_tenant_table(table_name, column: :tenant_id, role: RLS.role, &block)
def rls_tenant_table(table_name, column: :tenant_id, &block)
reversible do |dir|
dir.up do
execute <<~SQL
ALTER TABLE "#{table_name}" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "#{table_name}_#{role}" ON "#{table_name}" TO "#{role}"
CREATE POLICY "#{table_name}_rls" ON "#{table_name}" FOR ALL
USING ("#{column}" = NULLIF(current_setting('rls.tenant_id', TRUE), '')::bigint);
SQL
end
dir.down do
execute <<~SQL
DROP POLICY "#{table_name}_#{role}" ON "#{table_name}";
DROP POLICY "#{table_name}_rls" ON "#{table_name}";
ALTER TABLE "#{table_name}" DISABLE ROW LEVEL SECURITY;
SQL
end
Expand Down

0 comments on commit 99bf325

Please sign in to comment.