Course contentsShow
← Databases & SQL
Lesson 1582 of 1,95315. Database Security and GovernanceFree lesson

Row-Level Security Implementation

You will be able to write dynamic filters that restrict row visibility based on the executing user's attributes.

In this lesson, you will learn how to implement dynamic filters that restrict row visibility based on the executing user's specific attributes, ensuring that users only see the data they are authorized to access.

Beyond Table-Level Access

While Role-Based Access Control (RBAC) is excellent for managing which users can SELECT from a table, it is often too broad. In many enterprise scenarios, you need to restrict data based on content. For example, a regional sales manager should only see records for their specific territory, even though they share the same sales_analyst role as their peers in other regions.

Row-Level Security (RLS) solves this by injecting a hidden WHERE clause into every query executed against a table. This filter is dynamic; it evaluates the properties of the current session or the database user at runtime.

The Dynamic Filter Mechanism

To implement RLS, you typically define a security policy that maps to a specific table. This policy uses a function that returns a boolean expression. If the expression evaluates to TRUE for a specific row, the user sees it; if FALSE, the row is invisible to them as if it didn't exist.

Consider an Employees table with a department_id column. We want to ensure users only see their own department’s data:

-- Define the policy function
CREATE FUNCTION fn_dept_security(dept_id INT) 
RETURNS BOOLEAN AS $$
BEGIN
  RETURN dept_id = (SELECT department_id FROM user_profiles WHERE username = CURRENT_USER);
END;
$$ LANGUAGE plpgsql;

-- Apply the policy to the table
ALTER TABLE employees ENABLE ROW LEVEL SECURITY;

CREATE POLICY dept_access_policy ON employees
USING (fn_dept_security(department_id));

When a user runs SELECT * FROM employees;, the database engine automatically appends the condition from fn_dept_security to their query. Because the function references CURRENT_USER, the database dynamically resolves the filter based on whoever is logged in. This logic is transparent to the application code, preventing data leaks without requiring you to manually rewrite queries for every different user role.

Key Takeaway: Row-Level Security acts as a transparent, session-aware filter that enforces data segregation at the engine level, ensuring that users interact only with the subset of data permitted by their specific attributes.