Supabase
Principios Fundamentales
1. Supabase cambia con frecuencia — verifica contra el changelog y la documentación actual antes de implementar.
No confíes en los datos de entrenamiento para las funcionalidades de Supabase. Las firmas de funciones, la configuración de config.toml y las convenciones de la API cambian entre versiones.
Primero, obtén https://supabase.com/changelog.md (un índice de resumen ligero — no una descarga pesada), busca etiquetas breaking-change relevantes para tu tarea y sigue el enlace de la página para las que apliquen. Luego, busca el tema relevante utilizando los métodos de acceso a la documentación que se indican a continuación.
2. Verifica tu trabajo. Después de implementar cualquier corrección, ejecuta una consulta de prueba para confirmar que el cambio funciona. Una corrección sin verificación está incompleta.
3. Recupérate de errores, no entres en bucle. Si un enfoque falla después de 2-3 intentos, detente y reconsidera. Prueba un método diferente, consulta la documentación, inspecciona el error con más atención y revisa los registros relevantes cuando estén disponibles. Los problemas de Supabase no siempre se resuelven reintentando el mismo comando, y la respuesta no siempre está en los registros, pero a menudo vale la pena revisarlos antes de continuar.
4. Exponer tablas a la API de Datos: Dependiendo de la configuración de la API de Datos del usuario, las tablas recién creadas pueden no exponerse automáticamente a través de la API de Datos (REST). Si este es el caso, será necesario otorgar acceso explícitamente a los roles anon y authenticated.
Ten en cuenta que esto es independiente de RLS, que controla qué filas son visibles una vez que una tabla es accesible, no si la tabla es accesible en absoluto.
Cuando un usuario informe que una tabla creada con SQL es inesperadamente inaccesible, verifica su configuración de la API de Datos y si se ha otorgado acceso a los roles mediante GRANT SQL explícito. Al otorgar acceso público (anon/authenticated), habilita también RLS. Consulta Exponer una Tabla a la API de Datos para el flujo de trabajo de configuración completo.
5. RLS en esquemas expuestos.
Habilita RLS en cada tabla de cualquier esquema expuesto, lo que incluye public por defecto. Esto es crítico en Supabase porque las tablas en esquemas expuestos pueden ser accesibles a través de la API de Datos cuando los roles anon/authenticated tienen acceso (consulta Exponer una Tabla a la API de Datos). Para esquemas privados, prefiere RLS como defensa en profundidad. Después de habilitar RLS, crea políticas que coincidan con el modelo de acceso real, en lugar de asignar por defecto el mismo patrón auth.uid() a cada tabla.
6. Lista de verificación de seguridad. Al trabajar en cualquier tarea de Supabase que afecte a autenticación, RLS, vistas, almacenamiento o datos de usuario, revisa esta lista de verificación. Estas son trampas de seguridad específicas de Supabase que crean vulnerabilidades silenciosamente:
-
Seguridad de autenticación y sesiones
- Nunca uses las reclamaciones de
user_metadataen decisiones de autorización basadas en JWT. En Supabase,raw_user_meta_dataes editable por el usuario y puede aparecer enauth.jwt(), por lo que no es seguro para políticas RLS ni para ninguna otra lógica de autorización. Almacena los datos de autorización enraw_app_meta_data/app_metadataen su lugar. - Eliminar un usuario no invalida los tokens de acceso existentes. Primero cierra la sesión o revoca las sesiones, mantén la caducidad del JWT corta para aplicaciones sensibles y, para garantías estrictas, valida
session_idcontraauth.sessionsen operaciones sensibles. - Si usas
app_metadataoauth.jwt()para la autorización, recuerda que las reclamaciones JWT no siempre están actualizadas hasta que se refresca el token del usuario.
- Nunca uses las reclamaciones de
-
Claves de API y exposición del cliente
- Nunca expongas la clave
service_roleo secreta en clientes públicos. Prefiere claves publicables para el código frontend. Las clavesanonheredadas son solo para compatibilidad. En Next.js, cualquier variable de entornoNEXT_PUBLIC_se envía al navegador.
- Nunca expongas la clave
-
RLS, vistas y código de base de datos privilegiado
- Las vistas omiten RLS por defecto. En Postgres 15 y superior, usa
CREATE VIEW ... WITH (security_invoker = true). En versiones anteriores de Postgres, protege tus vistas revocando el acceso a los rolesanonyauthenticated, o colocándolas en un esquema no expuesto. - UPDATE requiere una política SELECT. En RLS de Postgres, un UPDATE necesita primero hacer SELECT de la fila. Sin una política SELECT, las actualizaciones devuelven silenciosamente 0 filas — sin error, solo sin cambios.
auth.role()está obsoleto — usa la cláusulaTOen su lugar. Supabase ha marcadoauth.role()como obsoleto en favor de especificar el rol objetivo directamente en la política conTO authenticatedoTO anon. Más allá de la obsolescencia,auth.role() = 'authenticated''falla silenciosamente cuando los inicios de sesión anónimos están habilitados, porque los usuarios anónimos llevan el rolauthenticatedde Postgres y pasan la verificación independientemente de si el usuario está realmente autenticado.-- Obsoleto (no usar) create policy "ejemplo" on nombre_tabla for select using ( auth.role() = 'authenticated' );TO authenticatedpor sí solo es autenticación sin autorización (BOLA / IDOR). UsarTO authenticatedsolo verifica el rol — no restringe qué filas puede acceder un usuario. El patrón correcto combinaTO authenticatedcon un predicado de propiedad enUSING:create policy "ejemplo" on nombre_tabla for select to authenticated using ( (select auth.uid()) = user_id );- Las políticas UPDATE requieren tanto
USINGcomoWITH CHECK. SinWITH CHECK, un usuario puede reasignar eluser_idde una fila a otro usuario:create policy "ejemplo" on nombre_tabla for update to authenticated using ( (select auth.uid()) = user_id ) with check ( (select auth.uid()) = user_id ); - Las funciones
SECURITY DEFINERomiten RLS. Una funciónSECURITY DEFINERse ejecuta con los privilegios de su creador — típicamente un rol conbypassrls(ej.,postgres). Nunca añadasSECURITY DEFINERpara resolver un error de permisos; elimina silenciosamente el control de acceso sin solucionar la causa subyacente. PrefiereSECURITY INVOKER. - Las funciones
SECURITY DEFINERenpublicson invocables por todos los roles. Postgres otorgaEXECUTEaPUBLICpor defecto para cada nueva función, por lo que cualquier funciónSECURITY DEFINERenpublices un endpoint de API pública invocable poranonyauthenticated(que heredan dePUBLIC) sin necesidad de concesión adicional. CuandoSECURITY DEFINERsea realmente necesario (ej., para omitir RLS en una tabla de búsqueda interna), mantén la función en un esquema no expuesto, incluye siempre una verificación deauth.uid()en el cuerpo de la función y ejecutasupabase db advisorsdespués de hacer cambios.
- Las vistas omiten RLS por defecto. En Postgres 15 y superior, usa
-
Control de acceso a Storage
- Storage upsert requiere INSERT + SELECT + UPDATE. Otorgar solo INSERT permite nuevas subidas, pero el reemplazo de archivos (upsert) falla silenciosamente. Necesitas los tres.
Para cualquier problema de seguridad no cubierto anteriormente, obtén el índice de seguridad de productos de Supabase: https://supabase.com/docs/guides/security/product-security.md
CLI de Supabase
Descubre los comandos siempre mediante --help — nunca adivines. La estructura de la CLI cambia entre versiones.
supabase --help # Todos los comandos de nivel superior
supabase <grupo> --help # Subcomandos (ej., supabase db --help)
supabase <grupo> <comando> --help # Banderas para un comando específico
Trampas conocidas de la CLI de Supabase:
supabase db queryrequiere CLI v2.79.0+ → usa MCPexecute_sqlopsqlcomo alternativasupabase db advisorsrequiere CLI v2.81.3+ → usa MCPget_advisorscomo alternativa- Cuando necesites un nuevo archivo SQL de migración, siempre créalo primero con
supabase migration new <nombre>. Nunca inventes un nombre de archivo de migración ni confíes en la memoria para el formato esperado.
Verificación de versión y actualización: Ejecuta supabase --version para comprobarlo. Para los changelogs de la CLI y las funcionalidades específicas de la versión, consulta la documentación de la CLI o las versiones de GitHub.
Servidor MCP de Supabase
Para instrucciones de configuración, URL del servidor y configuración, consulta la guía de configuración MCP.
Solución de problemas de conexión — sigue estos pasos en orden:
-
Verifica si el servidor es accesible:
curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcpUn código401es esperado (sin token) y significa que el servidor está activo. Timeout o "conexión rechazada" significa que puede estar caído. -
Verifica la configuración de
.mcp.json: Asegúrate de que la raíz del proyecto tenga un.mcp.jsonválido con la URL del servidor correcta. Si falta, crea uno que apunte ahttps://mcp.supabase.com/mcp. -
Autentica el servidor MCP: Si el servidor es accesible y
.mcp.jsones correcto pero las herramientas no son visibles, el usuario necesita autenticarse. El servidor MCP de Supabase usa OAuth 2.1 — dile al usuario que active el flujo de autenticación en su agente, lo complete en el navegador y recargue la sesión.
Documentación de Supabase
Antes de implementar cualquier funcionalidad de Supabase, encuentra la documentación relevante. Utiliza estos métodos en orden de prioridad:
- Herramienta MCP
search_docs(preferida — devuelve fragmentos relevantes directamente) - Obtener páginas de documentación como markdown — cualquier página de documentación se puede obtener añadiendo
.mda la ruta URL. - Búsqueda web para temas específicos de Supabase cuando no sepas qué página consultar.
Realizar y Confirmar Cambios de Esquema
Para realizar cambios de esquema, usa execute_sql (MCP) o supabase db query (CLI). Estos ejecutan SQL directamente en la base de datos sin crear entradas en el historial de migraciones, por lo que puedes iterar libremente y generar una migración limpia cuando estés listo.
NO uses apply_migration para cambiar un esquema de base de datos local — escribe una entrada en el historial de migraciones en cada llamada, lo que significa que no puedes iterar, y supabase db diff / supabase db pull producirán diferencias vacías o conflictivas. Si lo usas, quedarás atascado con el SQL que pasaste en el primer intento.
Cuando estés listo para confirmar tus cambios en un archivo de migración:
- Ejecuta asesores →
supabase db advisors(CLI v2.81.3+) o MCPget_advisors. Corrige cualquier problema. - Revisa la Lista de Verificación de Seguridad anterior si tus cambios involucran vistas, funciones, disparadores o almacenamiento.
- Genera la migración →
supabase db pull <nombre-descriptivo> --local --yes - Verifica →
supabase migration list --local
Guías de Referencia
- Comentarios sobre el Skill → references/skill-feedback.md DEBE leerse cuando el usuario informe que este skill ha proporcionado orientación incorrecta o le falta información.