¿Qué es Row Level Security?
Row Level Security (RLS) es una funcionalidad de PostgreSQL que restringe qué filas pueden acceder o modificar los usuarios. Es el mecanismo principal de seguridad en Supabase y te permite escribir políticas que controlan el acceso a nivel de base de datos.
🛡️ Por qué RLS es importante
- Seguridad a nivel de base de datos: Reglas aplicadas sin importar el acceso
- Control granular: Reglas distintas por operación
- Clave anon segura: Acceso seguro desde el cliente
- Sin backend: Seguridad sin código del servidor
Habilitar RLS
-- Enable RLS on a table
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- Tables with RLS enabled deny all access by default
-- You must create policies to allow access
⚠️ Importante
Cuando RLS está habilitado, TODO acceso se deniega por defecto. Debes crear políticas para permitir explícitamente el acceso que deseas.
Crear políticas
Estructura básica
CREATE POLICY "policy_name"
ON table_name
FOR operation -- SELECT, INSERT, UPDATE, DELETE, or ALL
TO role -- authenticated, anon, or specific role
USING (condition) -- For SELECT/UPDATE/DELETE
WITH CHECK (condition); -- For INSERT/UPDATE
Políticas comunes
Permitir que los usuarios lean sus propios datos:
CREATE POLICY "Users can read own posts"
ON posts FOR SELECT
TO authenticated
USING (auth.uid() = user_id);
Permitir que los usuarios inserten sus datos:
CREATE POLICY "Users can create posts"
ON posts FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
Permitir que los usuarios actualicen sus datos:
CREATE POLICY "Users can update own posts"
ON posts FOR UPDATE
TO authenticated
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
Permitir que los usuarios eliminen sus datos:
CREATE POLICY "Users can delete own posts"
ON posts FOR DELETE
TO authenticated
USING (auth.uid() = user_id);
Acceso público vs autenticado
-- Allow anyone to read published posts
CREATE POLICY "Public can read published posts"
ON posts FOR SELECT
TO anon, authenticated
USING (published = true);
-- Only authenticated users can read drafts
CREATE POLICY "Auth users can read own drafts"
ON posts FOR SELECT
TO authenticated
USING (auth.uid() = user_id AND published = false);
Funciones auxiliares
-- auth.uid() - Returns the current user's ID
-- auth.jwt() - Returns the current user's JWT claims
-- auth.role() - Returns the current user's role
-- Example: Check if user is admin
CREATE POLICY "Admins can do anything"
ON posts FOR ALL
TO authenticated
USING ((auth.jwt() ->> 'role') = 'admin');
Ejemplo completo
-- Create table
CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES auth.users(id) NOT NULL,
title TEXT NOT NULL,
content TEXT,
published BOOLEAN DEFAULT false
);
-- Enable RLS
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- Policies
CREATE POLICY "Anyone can read published posts"
ON posts FOR SELECT USING (published = true);
CREATE POLICY "Users can read own posts"
ON posts FOR SELECT
TO authenticated
USING (auth.uid() = user_id);
CREATE POLICY "Users can create own posts"
ON posts FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can update own posts"
ON posts FOR UPDATE
TO authenticated
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
CREATE POLICY "Users can delete own posts"
ON posts FOR DELETE
TO authenticated
USING (auth.uid() = user_id);
💡 Puntos clave
- • RLS ofrece seguridad a nivel de base de datos
- • Habilita RLS en cada tabla con datos de usuario
- • Usa auth.uid() para asociar filas al usuario actual
- • USING filtra filas para SELECT/UPDATE/DELETE
- • WITH CHECK valida datos en INSERT/UPDATE
📚 Más recursos
-
Documentación de RLS →
Guía completa de Row Level Security en Supabase.
-
Gestión de datos de usuario →
Buenas prácticas para asegurar datos de usuarios.