Row Access Policies β Row Level Security (RLS)
π¬ Story Time β βOnly Show Me My Regionβs Dataββ
Ravi, a regional data manager at a global retail company, logs into Snowflake.
He runs a revenue dashboard queryβ¦
But suddenly realizes:
βWaitβ¦ am I seeing everyoneβs revenue?β
Not good.
Each region should only see its own data:
- North America β sees NA rows
- Europe β sees EU rows
- Asia β sees APAC rows
Analysts should see all regions,
but partners should only see theirs.
Snowflakeβs Row Access Policies (RLS) save the day.
π‘οΈ 1. What Are Row Access Policies?β
Row Access Policies restrict which rows a user or role may query.
They enforce security at row level by checking:
- user
- role
- attributes (e.g., employee region)
- tags
- lookup tables
RLS is fully dynamic β enforced during query execution, not during data storage.
π§ 2. Create Your First RLS Policyβ
Ravi starts with a simple rule:
βUsers in the NA role can only see region = 'NorthAmerica' rows.β
CREATE ROW ACCESS POLICY region_rls
AS (region STRING) RETURNS BOOLEAN ->
CASE
WHEN CURRENT_ROLE() = 'NA_MANAGER' AND region = 'NorthAmerica' THEN TRUE
WHEN CURRENT_ROLE() = 'EU_MANAGER' AND region = 'Europe' THEN TRUE
ELSE FALSE
END;
Apply to the sales table:
ALTER TABLE sales
ADD ROW ACCESS POLICY region_rls ON (region);
Now, each region manager sees only their rows.
π§© 3. Real Enterprise Use Cases for RLSβ
β Use Case 1: Department-Based Securityβ
Finance sees all rows. HR sees only HR rows:
CREATE ROW ACCESS POLICY dept_rls
AS (department STRING) RETURNS BOOLEAN ->
CASE
WHEN CURRENT_ROLE() = 'FINANCE_ANALYST' THEN TRUE
WHEN CURRENT_ROLE() = 'HR_USER' AND department = 'HR' THEN TRUE
ELSE FALSE
END;
β Use Case 2: Multi-Tenant SaaS Architectureβ
Each tenant should only see their own data.
CREATE ROW ACCESS POLICY tenant_rls
AS (tenant_id STRING) RETURNS BOOLEAN ->
tenant_id = CURRENT_USER();
Perfect for:
- SaaS products
- Embedded analytics
- Shared databases for multiple customers
β Use Case 3: Employee Hierarchy Accessβ
Managers see rows for their employees; employees see only themselves.
CREATE ROW ACCESS POLICY employee_rls
AS (emp_id STRING) RETURNS BOOLEAN ->
emp_id = CURRENT_USER()
OR emp_id IN (
SELECT subordinate_id
FROM employee_hierarchy
WHERE manager_id = CURRENT_USER()
);
This supports:
- Org charts
- Supervisory workflows
- Call center analytics
β Use Case 4: Geo-Based Regulatory Complianceβ
EU employees cannot see US customer data due to GDPR rules.
CREATE ROW ACCESS POLICY geo_compliance_rls
AS (country STRING) RETURNS BOOLEAN ->
CASE
WHEN CURRENT_REGION() = 'EU' AND country != 'USA' THEN TRUE
WHEN CURRENT_REGION() != 'EU' THEN TRUE
ELSE FALSE
END;
Built for international data locality requirements.
β Use Case 5: RLS With Lookup Table (Best Practice)β
Instead of hardcoding rules, Ravi uses a mapping table.
1. Create mapping tableβ
CREATE TABLE rls_map (
role STRING,
allowed_region STRING
);
2. Create dynamic RLS policyβ
CREATE ROW ACCESS POLICY dynamic_rls
AS (region STRING) RETURNS BOOLEAN ->
region IN (
SELECT allowed_region
FROM rls_map
WHERE role = CURRENT_ROLE()
);
This approach scales to:
- thousands of stores
- hundreds of regions
- dozens of roles
Minimal SQL changes.
π 4. Applying RLS to Views, Tables & Columnsβ
Apply to a table:β
ALTER TABLE orders ADD ROW ACCESS POLICY dynamic_rls ON (region);
Apply to a secure view:β
CREATE SECURE VIEW regional_view AS
SELECT * FROM orders;
RLS works automatically.
π§ 5. How RLS Works Behind the Scenesβ
When a query runs:
- Snowflake evaluates the policy
- Filters rows before query results
- Applies masking policies afterwards
- Returns only authorized data
RLS interacts seamlessly with:
- Tags
- Masking Policies
- Secure Views
- Access Control
- Snowflake Sharing (Secure Shares)
π§ͺ 6. Testing RLSβ
Switch roles to validate:
USE ROLE NA_MANAGER;
SELECT region, revenue FROM sales;
USE ROLE EU_MANAGER;
SELECT region, revenue FROM sales;
USE ROLE ANALYTICS_TEAM;
SELECT region, revenue FROM sales;
Results differ by role β without modifying the actual table.
π§± 7. Performance Considerationsβ
- RLS is metadata-based β no physical data copy
- Polices are evaluated at query time
- Works efficiently with micro-partition pruning
- Use lookup tables for scalable logic
- Complex expressions can slow queries β keep policies efficient
π Best Practicesβ
- Use lookup tables, not hardcoded roles
- Combine RLS with masking for column-level protection
- Avoid nested CASE statements
- Apply policies to root tables, not derived views
- Document every RLS policy in a governance catalog
- Audit row-level access using Access History
- Use Secure Views for added protection when sharing data
π Real-World Ending β βSecure Data, Happier Teamsββ
After deploying RLS:
- Regional managers see only their regions
- Analysts get full visibility
- Legal & compliance teams sleep peacefully
- No duplicate tables
- No custom ETL pipelines
- No manual partitions
Ravi's dashboard now shows only the right data to the right people.
His boss says:
βThis is security done right β invisible, accurate, and scalable.β
π Summaryβ
Snowflake Row Access Policies provide:
β Row-level filteringβ
β Conditional visibilityβ
β Multi-tenant isolationβ
β Regulatory complianceβ
β Real-time enforcementβ
β Seamless integration with governance toolsβ
A critical component of any secure Snowflake data platform.
π Next Topic
Snowflake Costs & Billing Dashboard β Monitoring Tips
`