PostgreSQL Row-Level Security
Summary: in this tutorial, you will learn how to use PostgreSQL row-level security to control access to individual rows in a table.
Introduction to the PostgreSQL Row-Level Security
Row-level security (RLS) is a feature that allows you to restrict rows returned by a query based on the user executing the query.
The RLS allows you to control access to individual rows in tables based on the current user and specific conditions defined by policies.
The basic steps for implementing row-level security are as follows:
First, enable row-level security on a table using the ALTER TABLE
statement:
Second, create a new row-level security policy for a table using the CREATE POLICY
statement:
In the policy, you define a condition that determines which rows are visible.
Note that superusers and roles with the BYPASSRLS
attribute can bypass the row security system when accessing a table.
Additionally, table owners also bypass row-level security. To enforce the row-level security to the table owners, you can modify the table using the FORCE ROW LEVEL SECURITY
option:
PostgreSQL Row-Level Security example
We’ll take an example of creating a table and roles where the roles can retrieve data from the table whose manager
column matches the current role.
1) Create a new database called hr
:
2) Change the current database to the hr
database:
3) Create a new table called departments
to store department data:
4) Insert some rows into the departments
table:
5) Create a group role called managers
:
6) Grant the SELECT
privileges of all tables in the public
schema to the group role managers
:
7) Create three new roles alice
, bob
, peter
and assign them as members of the managers
group role:
The roles alice
, bob
, and jack
will implicitly inherit privileges from the group role managers. In other words, they can retrieve data from all tables in the public
schema.
8) Enable row-level security on the departments
table:
9) Create a policy that the current user can access the rows whose value in the manager
column of the departments
table matches the current role name:
10) Connect to the hr
database using the alice
role in a separate session:
11) Retrieve data from the departments
table:
Output:
The query returns the rows whose manager column is alice
.
12) Connect to the hr
database using the bob
role in a separate session:
13) Select data from the departments
table:
Output:
Like alice
, bob
can only retrieve data whose manager is bob
.
Summary
- Use the
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY
statement to enable row-level security of a table. - Use the
CREATE POLICY
statement to define a new row-level security policy for a table.