CommunityProgramación y desarrollogithub.com

supabase/supabase

Úsalo para cualquier tarea que involucre Supabase: productos, bibliotecas cliente, autenticación, CLI, esquemas, depuración y más.

¿Qué es supabase?

Este skill está diseñado para asistentes de IA (como Claude Code, Cursor o Codex) que trabajan con proyectos de Supabase. Proporciona directrices fundamentales para evitar errores comunes de seguridad, configuración y dependencia, asegurando que las implementaciones sean correctas y robustas. Cubre todos los productos de Supabase: Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues, así como las integraciones con frameworks modernos (Next.js, React, SvelteKit, Astro, Remix) y bibliotecas cliente (supabase-js, @supabase/ssr). También incluye pautas para usar la CLI de Supabase o el servidor MCP, manejar migraciones, esquemas declarativos, auditorías de seguridad y extensiones de Postgres como pg_graphql, pg_cron y pg_vector. El skill destaca la importancia de verificar los cambios contra la documentación actual, probar las soluciones y no repetir enfoques fallidos. Además, incorpora una lista de verificación de seguridad específica de Supabase que aborda desde el manejo de JWTs y RLS hasta la exposición segura de tablas y funciones SECURITY DEFINER. Es una guía indispensable para cualquier tarea que involucre Supabase, ayudando a prevenir vulnerabilidades silenciosas y problemas de despliegue.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/supabase/agent-skills/tree/main/skills/supabase

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace 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 funciones 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 resumido ligero, no una descarga pesada), busca etiquetas breaking-change relevantes para tu tarea y sigue la página enlazada si corresponde. Luego consulta el tema relevante usando 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 entres en un bucle. Si un enfoque falla después de 2 o 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 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, es posible que las tablas recién creadas no se expongan 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 informa 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 una instrucción GRANT SQL explícita. Al otorgar acceso público (anon/authenticated), habilita también RLS. Consulta Exponer una tabla a la API de datos para obtener el flujo de trabajo completo de configuración.

5. RLS en esquemas expuestos. Habilita RLS en cada tabla de cualquier esquema expuesto, lo que incluye public de forma predeterminada. Esto es fundamental 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 aplicar por defecto el mismo patrón auth.uid() a todas las tablas.

6. Lista de verificación de seguridad. Al trabajar en cualquier tarea de Supabase que involucre autenticación, RLS, vistas, almacenamiento o datos de usuario, revisa esta lista. 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_metadata en decisiones de autorización basadas en JWT. En Supabase, raw_user_meta_data es editable por el usuario y puede aparecer en auth.jwt(), por lo que no es seguro para las políticas de RLS ni para ninguna otra lógica de autorización. Almacena los datos de autorización en raw_app_meta_data / app_metadata en su lugar.
    • Eliminar un usuario no invalida los tokens de acceso existentes. Primero cierra sesión o revoca las sesiones, mantén la caducidad del JWT corta para aplicaciones sensibles y, para garantías estrictas, valida session_id contra auth.sessions en operaciones sensibles.
    • Si usas app_metadata o auth.jwt() para la autorización, recuerda que las reclamaciones JWT no siempre están actualizadas hasta que se renueva el token del usuario.
  • Exposición de claves de API y cliente

    • Nunca expongas la clave service_role o secreta en clientes públicos. Prefiere las claves publicables para el código del frontend. Las claves anon heredadas son solo para compatibilidad. En Next.js, cualquier variable de entorno NEXT_PUBLIC_ se envía al navegador.
  • RLS, vistas y código de base de datos privilegiado

    • Las vistas omiten RLS de forma predeterminada. En Postgres 15 y versiones posteriores, usa CREATE VIEW ... WITH (security_invoker = true). En versiones anteriores de Postgres, protege tus vistas revocando el acceso a los roles anon y authenticated, o colocándolas en un esquema no expuesto.
    • UPDATE requiere una política SELECT. En Postgres RLS, un UPDATE necesita primero hacer un SELECT de la fila. Sin una política SELECT, las actualizaciones devuelven silenciosamente 0 filas — sin error, simplemente ningún cambio.
    • auth.role() está obsoleto — usa la cláusula TO en su lugar. Supabase ha dejado obsoleto auth.role() a favor de especificar el rol objetivo directamente en la política con TO authenticated o TO 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 tienen el rol authenticated de Postgres y pasan la verificación independientemente de si el usuario ha iniciado sesión realmente.
      -- Obsoleto (no usar)
      create policy "ejemplo" on nombre_tabla for select
      using ( auth.role() = 'authenticated' );
      
    • TO authenticated por sí solo es autenticación sin autorización (BOLA / IDOR). Usar TO authenticated solo verifica el rol — no restringe qué filas puede acceder un usuario. El patrón correcto combina TO authenticated con un predicado de propiedad en USING:
      create policy "ejemplo" on nombre_tabla for select
      to authenticated
      using ( (select auth.uid()) = user_id );
      
    • Las políticas UPDATE requieren tanto USING como WITH CHECK. Sin WITH CHECK, un usuario puede reasignar el user_id de 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 DEFINER omiten RLS. Una función SECURITY DEFINER se ejecuta con los privilegios de su creador — normalmente un rol con bypassrls (por ejemplo, postgres). Nunca agregues SECURITY DEFINER para resolver un error de permiso; elimina silenciosamente el control de acceso sin solucionar la causa subyacente. Prefiere SECURITY INVOKER.
    • Las funciones SECURITY DEFINER en public son invocables por todos los roles. Postgres otorga EXECUTE a PUBLIC de forma predeterminada para cada función nueva, por lo que cualquier función SECURITY DEFINER en public es un punto final de API pública invocable por anon y authenticated (que heredan de PUBLIC) sin necesidad de concesiones adicionales. Cuando SECURITY DEFINER es 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ón de auth.uid() en el cuerpo de la función y ejecuta supabase db advisors después de realizar cambios.
  • 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

    • Fija siempre 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 npm para obtener la lista de verificación completa.

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

Supabase CL

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills relacionados