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 características de Supabase. Las firmas de funciones, la configuración de config.toml y las convenciones de la API cambian entre versiones.
Primero, obten https://supabase.com/changelog.md (un índice de resumen ligero, no una descarga pesada), busca etiquetas breaking-change relevantes para tu tarea y sigue la página enlazada 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 los errores, no te estanques. 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 cuidado y revisa los registros relevantes cuando estén disponibles. Los problemas de Supabase no siempre se resuelven repitiendo 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 sentencias SQL GRANT explícitas. Al otorgar acceso público (anon/authenticated), habilita también RLS. Consulta Exponer una Tabla a la API de Datos para ver el flujo de trabajo 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 toque 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 silenciosamente vulnerabilidades:
-
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 renueva el token del usuario.
- Nunca uses las reclamaciones de
-
Exposición de claves API y cliente
- Nunca expongas
service_roleo la clave 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. - Usa tokens de acceso personal con ámbito para la API de Administración, CLI y servidor MCP. Un token de acceso personal clásico conlleva el acceso completo a la cuenta del usuario, en todas las organizaciones y proyectos. Para scripts, CI y agentes, haz que el usuario cree un token con ámbito limitado a las organizaciones, proyectos y permisos que la tarea necesite. La guía de tokens de acceso personal enumera el permiso que requiere cada endpoint de la API de Administración y cada herramienta MCP. Consulta los permisos allí en lugar de adivinarlos.
- Nunca expongas
-
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 de los rolesanonyauthenticated, o colocándolas en un esquema no expuesto. - UPDATE requiere una política SELECT. En Postgres RLS, un UPDATE necesita primero SELECT sobre 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 desaprobadoauth.role()en favor de especificar el rol de destino directamente en la política conTO authenticatedoTO anon. Más allá de la desaprobación,auth.role() = 'authenticated''falla silenciosamente cuando los inicios de sesión anónimos están habilitados, porque los usuarios anónimos llevan el rol de Postgresauthenticatedy pasan la verificación independientemente de si el usuario ha iniciado sesión realmente.-- Obsoleto (no usar) create policy "example" on table_name 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 "example" on table_name 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 "example" on table_name 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(por ejemplo,postgres). Nunca agreguesSECURITY DEFINERpara resolver un error de permiso; elimina silenciosamente el control de acceso sin corregir 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 una concesión adicional. CuandoSECURITY DEFINERsea realmente necesario (por ejemplo, para omitir RLS en una tabla de búsqueda interna), mantén la función en un esquema no expuesto, incluye siempre una verificaciónauth.uid()en el cuerpo de la función y ejecutasupabase db advisorsdespués de realizar cambios.
- Las vistas omiten RLS por defecto. En Postgres 15 y superior, usa
-
Control de acceso al almacenamiento
- Upsert en Storage requiere INSERT + SELECT + UPDATE. Otorgar solo INSERT permite nuevas subidas, pero el reemplazo de archivos (upsert) falla silenciosamente. Necesitas los tres.
-
Seguridad de dependencias y cadena de suministro
- Siempre fija las versiones de los paquetes y confirma los archivos de bloqueo al instalar paquetes de Supabase (
supabase-js,@supabase/ssr,supabase-py, etc.). Consulta la guía de seguridad de npm para obtener la lista de verificación completa.
- Siempre fija las versiones de los paquetes y confirma los archivos de bloqueo al instalar paquetes de Supabase (
Para cualquier problema de seguridad no cubierto anteriormente, obtén el índice de seguridad del producto Supabase: https://supabase.com/docs/guides/security/product-security.md
CLI de Supabase
Siempre descubre los comandos 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
Problemas conocidos 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- El flujo del navegador de
supabase logincrea un token clásico con acceso completo a la cuenta. En CI, estableceSUPABASE_ACCESS_TOKENen un token de acceso personal con ámbito en su lugar. Tiene prioridad sobre cualquier inicio de sesión guardado. Los comandos que se conectan con la contraseña de la base de datos (--passwordoSUPABASE_DB_PASSWORD, por ejemplosupabase db push) no están limitados por los permisos del token. - En proyectos de migración imperativa, crea nuevos archivos de migración escritos manualmente con
supabase migration new <nombre>primero. Nunca inventes un nombre de archivo de migración ni confíes en la memoria para el formato esperado. Los proyectos de esquema declarativo generan migraciones a partir desupabase/schemas/; consulta "Realizar y Confirmar Cambios de Esquema" a continuación.
Verificación de versión y actualización: Ejecuta supabase --version para verificar. Para los changelogs de la CLI y las características específicas de la versión, consulta la documentación de la CLI o los lanzamientos de GitHub.
Servidor MCP de Supabase
Para instrucciones de configuración, URL del servidor y configuración, consulta la guía de configuración de 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/mcpUn401es esperado (sin token) y significa que el servidor está activo. El tiempo de espera 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 archivo.mcp.jsonválido con la URL correcta del servidor. 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. En CI u otros entornos donde el flujo del navegador no puede ejecutarse, pasa un token de acceso personal con ámbito en el encabezadoAuthorization: Bearer. -
Verifica los permisos del token con ámbito: Si una herramienta falla con "No tienes permiso para realizar esta acción" mientras se usa un token de acceso personal con ámbito, el token carece del permiso de esa herramienta o el proyecto está fuera del ámbito del token. Verifica el permiso requerido de la herramienta en la guía de tokens de acceso personal.
Documentación de Supabase
Antes de implementar cualquier característica de Supabase, encuentra la documentación relevante. Usa 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 de la URL. - Búsqueda web para temas específicos de Supabase cuando no sabes qué página consultar.
Realizar y Confirmar Cambios de Esquema
Primero, decide qué flujo de trabajo de esquema utiliza el proyecto.
Opción A: Esquemas declarativos
Usa esta opción cuando exista supabase/schemas/ o config.toml establezca schema_paths. Edita el estado del esquema deseado en esos archivos, luego genera y revisa la migración. No empieces escribiendo una migración a mano. Consulta la guía de esquemas de base de datos declarativos.
Opción B: Migraciones imperativas
Usa esta opción cuando el proyecto no utilice esquemas declarativos.
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, te quedarás atascado con el SQL que hayas pasado en el primer intento.
Cuando estés listo para confirmar tus cambios en un archivo de migración:
- Ejecuta los advisors →
supabase db advisors(CLI v2.81.3+) o MCPget_advisors. Soluciona 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
Depuración
Cuando recibas un error en una solicitud relacionada con Supabase, por ejemplo, un código de error de la API REST de Supabase, la base de datos Postgres o PostgREST, un resultado vacío, un bloqueo inesperado por RLS, o un error de un servicio de Supabase como Auth, Realtime, Edge Functions o Storage, debes obtener la documentación de Monitoreo y Depuración de Supabase antes de diagnosticar o proponer una corrección, en lugar de trabajar de memoria. Los mismos documentos también cubren optimizaciones de rendimiento, como consultas lentas e índices faltantes.
Guías de Referencia
- Comentarios sobre el Skill → references/skill-feedback.md DEBE leerlo cuando el usuario informe que este skill proporcionó orientación incorrecta o falta información.