Row Level Security using Go and PostgreSQL
What is Row Level Security (RLS)?
Row level security (RLS for short) is a PostgreSQL security feature provided by the PostgreSQL database. It allows database administrators to define policies to control how specific rows of data display and operate for one or more user roles.
You can create row level security policies for specific commands like SELECT, INSERT, UPDATE, and DELETE or you can specify it for ALL commands.
What to consider when implementing RLS
- Enable RLS on a table using
ALTER TABLE ... ENABLE ROW LEVEL SECURITY. Without this, policies won’t be applied. - Define RLS policies with the
CREATE POLICYcommand for each table. - Policies control specific operations like
SELECT,UPDATE, andDELETE. - They apply only to rows that meet a specified SQL condition.
USINGclauses filter existing rows based on the policy condition.WITH CHECKclauses validate new rows before insertion or modification.- Policies can share the same name across multiple tables, allowing reuse.
- Superusers and roles with the
BYPASSRLSattribute always bypass the row security system when accessing a table.
Important to note
- Enabling and disabling row security, as well as adding policies to a table, is always the privilege of the table owner only.
- Each policy has a name and multiple policies can be defined for a table.
- When multiple policies apply to a given query, they are combined using either OR (for permissive policies, which are the default) or using AND (for restrictive policies).
- A given role has the privileges of all roles that they are a member of.
RLS Example (using Go and GORM)
| |
Limitations and Considerations
- RLS may not be suitable for cases requiring complex cross-tenant operations
- Additional care is needed when performing bulk operations
- Backup and restore operations need to account for RLS policies