Reglas de Seguridad (RLS)
Resumen
Sección titulada «Resumen»Las reglas de seguridad le permiten definir políticas de Seguridad a Nivel de Fila (RLS) para sus tablas PostgreSQL directamente en las definiciones de sus colecciones. Cuando se genera el esquema Drizzle, Rebase crea las sentencias CREATE POLICY correspondientes.
const postsCollection: EntityCollection = { slug: "posts", table: "posts", properties: { /* ... */ }, securityRules: [ { operation: "select", access: "public" }, { operations: ["insert", "update", "delete"], ownerField: "author_id" } ]};Cómo Funciona
Sección titulada «Cómo Funciona»- Usted define
securityRulesen una colección rebase schema generatecrea el esquema Drizzle con RLS habilitadorebase db pushorebase db migrateaplica las políticas a PostgreSQL- Cada consulta es filtrada automáticamente por el contexto del usuario actual
La identidad del usuario autenticado está disponible en SQL a través de:
| Función | Devuelve |
|---|---|
auth.uid() | El ID del usuario actual |
auth.roles() | IDs de roles de aplicación separados por comas |
auth.jwt() | Reclamaciones JWT completas como JSONB |
Estos se establecen automáticamente por transacción por el backend de Rebase.
Atajos de Conveniencia
Sección titulada «Atajos de Conveniencia»Acceso Basado en el Propietario
Sección titulada «Acceso Basado en el Propietario»El patrón más simple: los usuarios solo pueden acceder a las filas que poseen:
securityRules: [ { operation: "all", ownerField: "user_id" }]Esto genera: USING (user_id = auth.uid())
Acceso Público
Sección titulada «Acceso Público»Permitir que cualquiera (incluidos los usuarios no autenticados) lea:
securityRules: [ { operation: "select", access: "public" }]Esto genera: USING (true)
Acceso Autenticado
Sección titulada «Acceso Autenticado»Permitir a cualquier usuario autenticado:
securityRules: [ { operation: "select", access: "authenticated" }]Acceso Basado en Roles
Sección titulada «Acceso Basado en Roles»Restringir operaciones a roles específicos:
securityRules: [ { operation: "all", roles: ["admin"] }, { operation: "select", roles: ["editor", "viewer"] }]Expresiones SQL Puras
Sección titulada «Expresiones SQL Puras»Para lógica compleja, utilice using y withCheck:
securityRules: [ { operation: "select", using: "EXISTS (SELECT 1 FROM org_members WHERE org_members.org_id = {org_id} AND org_members.user_id = auth.uid())" }]using— Filtra qué filas existentes son visibles (se aplica a SELECT, UPDATE, DELETE)withCheck— Valida nuevos valores de fila (se aplica a INSERT, UPDATE)
Las referencias a columnas utilizan la sintaxis {nombre_de_columna} que se resuelve a la columna completa cualificada por la tabla.
Combinando Atajos y SQL
Sección titulada «Combinando Atajos y SQL»Combine atajos de conveniencia con SQL puro:
securityRules: [ // Los administradores pueden hacer cualquier cosa { operation: "all", roles: ["admin"], using: "true" }, // Los usuarios regulares solo pueden ver sus propias filas { operation: "select", ownerField: "user_id" }, // Los usuarios pueden insertar, pero solo para sí mismos { operation: "insert", withCheck: "{user_id} = auth.uid()" }, // Las filas bloqueadas no se pueden actualizar { operation: "update", mode: "restrictive", using: "{is_locked} = false" }]Permisivo vs Restrictivo
Sección titulada «Permisivo vs Restrictivo»PostgreSQL tiene dos modos de política:
- Permisivo (predeterminado) — Múltiples políticas permisivas se combinan con OR. Si alguna de ellas se cumple, se concede el acceso.
- Restrictivo — Las políticas restrictivas se combinan con AND. Todas deben cumplirse.
securityRules: [ // Permisivo: los propietarios pueden acceder a sus filas { operation: "all", ownerField: "user_id" }, // Restrictivo: pero las filas bloqueadas no se pueden actualizar { operation: "update", mode: "restrictive", using: "{is_locked} = false", withCheck: "{is_locked} = false" }]Operaciones
Sección titulada «Operaciones»| Operación | Equivalente SQL | Descripción |
|---|---|---|
"select" | SELECT | Leer filas |
"insert" | INSERT | Crear nuevas filas |
"update" | UPDATE | Modificar filas existentes |
"delete" | DELETE | Eliminar filas |
"all" | Todas las anteriores | Abreviatura para todas las operaciones |
También puede usar operations (plural) para aplicar una regla a múltiples operaciones:
{ operations: ["insert", "update", "delete"], ownerField: "author_id" }Interfaz Completa de SecurityRule
Sección titulada «Interfaz Completa de SecurityRule»interface SecurityRule { name?: string; // Nombre de política legible por humanos operation?: SecurityOperation; // Operación única operations?: SecurityOperation[]; // Múltiples operaciones mode?: "permissive" | "restrictive"; // Predeterminado: "permissive" access?: "public" | "authenticated"; ownerField?: string; // Columna que contiene el ID de usuario del propietario roles?: string[]; // Roles de aplicación a los que se aplica esta política using?: string; // Expresión SQL USING pura withCheck?: string; // Expresión SQL WITH CHECK pura}Ejemplos
Sección titulada «Ejemplos»Plataforma de Blog
Sección titulada «Plataforma de Blog»securityRules: [ // Cualquiera puede leer publicaciones publicadas { operation: "select", access: "public", using: "{status} = 'published'" }, // Los autores pueden ver sus propios borradores { operation: "select", ownerField: "author_id" }, // Los autores pueden crear y editar sus propias publicaciones { operations: ["insert", "update"], ownerField: "author_id" }, // Solo los administradores pueden eliminar { operation: "delete", roles: ["admin"] }]SaaS Multi-inquilino
Sección titulada «SaaS Multi-inquilino»securityRules: [ { operation: "all", using: "EXISTS (SELECT 1 FROM org_members WHERE org_members.org_id = {org_id} AND org_members.user_id = auth.uid())" }]Acceso Anónimo (Inserciones Públicas)
Sección titulada «Acceso Anónimo (Inserciones Públicas)»Una necesidad común es permitir que usuarios no autenticados envíen datos — formularios de contacto, suscripciones a boletines, aplicaciones públicas. Rebase proporciona un patrón limpio para esto.
Recomendado: access: "public" con withCheck
Sección titulada «Recomendado: access: "public" con withCheck»const contactMessagesCollection: EntityCollection = { slug: "contact_messages", securityRules: [ // Cualquiera puede enviar un mensaje de contacto { operation: "insert", access: "public", withCheck: "true" }, // Solo los administradores pueden leer, actualizar o eliminar mensajes { operations: ["select", "update", "delete"], roles: ["admin"] } ], properties: { /* ... */ }};El atajo access: "public" genera una política que permite la operación sin requerir autenticación.
Para Captura de Leads / Registros
Sección titulada «Para Captura de Leads / Registros»const leadSignupsCollection: EntityCollection = { slug: "lead_magnet_signups", securityRules: [ // Permitir inserciones anónimas { operation: "insert", access: "public", withCheck: "true" }, // Los administradores pueden ver todos los registros { operation: "select", roles: ["admin"] } ], properties: { /* ... */ }};Cómo Funcionan las Solicitudes Anónimas
Sección titulada «Cómo Funcionan las Solicitudes Anónimas»Cuando una solicitud llega sin un token JWT, el backend de Rebase establece las variables de sesión de PostgreSQL a:
| Variable | Valor |
|---|---|
app.user_id | 'anonymous' |
app.user_roles | '' (vacío) |
Esto significa:
auth.uid()devuelve'anonymous'auth.roles()devuelve una cadena vacía- Las políticas
access: "public"pasan porque generanUSING (true)/WITH CHECK (true) - Las políticas
access: "authenticated"fallan porque verifican un ID de usuario real - Las políticas
ownerFieldfallan porque ninguna fila tendráuser_id = 'anonymous'(a menos que se establezca explícitamente)
Avanzado: SQL Puro para Anónimos
Sección titulada «Avanzado: SQL Puro para Anónimos»Si necesita un control más granular, utilice SQL puro:
securityRules: [ { operation: "insert", withCheck: "auth.uid() = 'anonymous' OR auth.uid() IS NOT NULL" }]Próximos Pasos
Sección titulada «Próximos Pasos»- Relaciones — Claves foráneas y uniones
- Callbacks de Entidad — Ganchos de ciclo de vida
- Funciones Personalizadas — Puntos finales de API personalizados