TechLead
Lección 4 de 8
5 min de lectura
Supabase

Row Level Security (RLS)

Protege tus datos con políticas de Row Level Security en PostgreSQL

¿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

Continuar Aprendiendo