RLS (Row Level Security) helps protect your data by controlling who can see or change each row in a table.
Enabling RLS on tables in Supabase
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
This command turns on RLS for the specified table.
After enabling RLS, you must create policies to allow access; otherwise, no one can read or write data.
users table to start controlling row access.ALTER TABLE users ENABLE ROW LEVEL SECURITY;
orders table to protect order data per user.ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
This example creates a messages table, enables RLS, and adds policies so users can only see and add messages linked to their own user ID.
CREATE TABLE messages ( id SERIAL PRIMARY KEY, user_id UUID NOT NULL, content TEXT NOT NULL ); ALTER TABLE messages ENABLE ROW LEVEL SECURITY; CREATE POLICY "Users can view their messages" ON messages FOR SELECT USING (auth.uid() = user_id); CREATE POLICY "Users can insert their messages" ON messages FOR INSERT WITH CHECK (auth.uid() = user_id);
Enabling RLS alone does not grant access; you must define policies to allow actions.
Use auth.uid() in policies to get the current user's ID in Supabase.
Test your policies carefully to avoid locking out all users.
RLS controls access to rows in a table based on user identity.
Enable RLS with ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
Create policies to specify who can read or write rows.
Practice
Solution
Step 1: Understand RLS purpose
RLS restricts access to rows in a table depending on who the user is.Step 2: Compare options
Only It controls which rows a user can access based on their identity. describes controlling row access by user identity, others describe unrelated features.Final Answer:
It controls which rows a user can access based on their identity. -> Option CQuick Check:
RLS = Row access control [OK]
- Confusing RLS with encryption
- Thinking RLS backs up data
- Assuming RLS increases storage
profiles in Supabase?Solution
Step 1: Recall correct SQL syntax for enabling RLS
The correct command isALTER TABLE [table_name] ENABLE ROW LEVEL SECURITY;.Step 2: Match options to syntax
Only ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; matches the exact syntax; others are invalid SQL commands.Final Answer:
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; -> Option BQuick Check:
ALTER TABLE + ENABLE ROW LEVEL SECURITY = correct syntax [OK]
- Using SET instead of ENABLE
- Wrong command order
- Missing ALTER TABLE keyword
tasks with RLS enabled:CREATE POLICY "Users can view their tasks" ON tasks FOR SELECT USING (user_id = auth.uid());
What will happen if a user tries to select tasks where
user_id is different from their own?Solution
Step 1: Understand the policy condition
The policy allows SELECT only ifuser_id = auth.uid(), meaning users see only their own tasks.Step 2: Predict query result for mismatched user_id
If user_id differs, the condition fails, so those rows are not visible.Final Answer:
They will see only tasks where user_id matches their auth.uid(). -> Option AQuick Check:
Policy filters rows by user_id = auth.uid() [OK]
- Assuming all rows are visible
- Expecting syntax errors from policy
- Thinking no rows are visible at all
orders table but users report they cannot see any rows even though policies exist. What is the most likely cause?Solution
Step 1: Understand RLS behavior
When RLS is enabled, access depends on policies. Without policies allowing access, no rows are visible.Step 2: Evaluate other options
Missing primary key, connection loss, or row count do not directly cause no rows to show due to RLS.Final Answer:
RLS is enabled but no policies allow access to rows. -> Option DQuick Check:
RLS needs policies to permit row access [OK]
- Ignoring missing policies
- Blaming unrelated database issues
- Assuming RLS shows all rows by default
messages table only if the sender_id matches their authenticated user ID. Which policy correctly enforces this with RLS enabled?Solution
Step 1: Identify correct policy type for INSERT
For INSERT,WITH CHECKcontrols if new rows meet the condition.Step 2: Match condition to sender_id and auth.uid()
The conditionsender_id = auth.uid()ensures users insert only their own messages.Step 3: Verify options
CREATE POLICY "Allow insert if sender matches" ON messages FOR INSERT WITH CHECK (sender_id = auth.uid()); uses FOR INSERT with WITH CHECK and correct condition; others use wrong commands or clauses.Final Answer:
CREATE POLICY "Allow insert if sender matches" ON messages FOR INSERT WITH CHECK (sender_id = auth.uid()); -> Option AQuick Check:
INSERT policies use WITH CHECK to validate new rows [OK]
- Using USING instead of WITH CHECK for INSERT
- Applying SELECT or UPDATE instead of INSERT
- Missing condition on sender_id
Ready to prove it?
Pass the test and this pattern moves unknown
