Files
motor-de-encuestas/supabase/migrations/20260531000006_grants.sql
2026-05-31 04:33:07 -03:00

79 lines
3.7 KiB
SQL

-- ============================================================
-- Migration 006: GRANTs explícitos de tabla
--
-- CONTEXTO: A partir de 2026-05-30, Supabase cambia el default de
-- auto_expose_new_tables a false. Sin GRANTs explícitos, los roles
-- anon/authenticated no pueden acceder a las tablas aunque haya
-- políticas RLS. Las RLS policies son la capa de restricción por-fila;
-- los GRANTs son la capa de acceso al objeto. Ambas son necesarias.
--
-- Diseño de capas para responses/answers:
-- Capa 1 (objeto): authenticated tiene SELECT → el role puede hacer queries
-- Capa 2 (RLS): sin policy SELECT para org_admin → resultado = 0 filas
-- Capa 3 (datos): para obtener datos reales, org_admin llama agg_segment,
-- que aplica k_threshold internamente (SECURITY DEFINER)
--
-- Esta layering cumple la intención del DATA_MODEL: "0 filas crudas",
-- no "permission denied". El resultado es indistinguible para el caller
-- (tabla vacía), pero la arquitectura es auditable y testeable con RLS.
--
-- Principio mínimo de privilegios:
-- anon → solo lo necesario para responder una encuesta
-- authenticated → lo que necesita org_admin + respondentes autenticados
-- service_role → bypasa RLS, no necesita GRANTs adicionales aquí
-- ============================================================
-- Acceso al schema public
GRANT USAGE ON SCHEMA public TO anon, authenticated;
-- ============================================================
-- organizations
-- authenticated (org_admin) lee solo su org (filtrado por RLS)
-- ============================================================
GRANT SELECT ON public.organizations TO authenticated;
-- ============================================================
-- consent_versions
-- anon lee el texto de consentimiento para mostrarlo en el form
-- ============================================================
GRANT SELECT ON public.consent_versions TO anon, authenticated;
-- ============================================================
-- surveys
-- anon: encuestas live (para renderizar el form)
-- authenticated: sus encuestas en cualquier estado
-- ============================================================
GRANT SELECT ON public.surveys TO anon, authenticated;
-- ============================================================
-- questions
-- anon: preguntas de encuestas live
-- authenticated: preguntas de sus encuestas
-- ============================================================
GRANT SELECT ON public.questions TO anon, authenticated;
-- ============================================================
-- consent_records
-- INSERT: al enviar el form
-- SELECT: authenticated puede consultar (RLS filtra; analyst usa service_role)
-- ============================================================
GRANT INSERT ON public.consent_records TO anon, authenticated;
GRANT SELECT ON public.consent_records TO authenticated;
-- ============================================================
-- responses
-- INSERT: al enviar el form
-- SELECT: authenticated puede hacer el query (RLS devuelve 0 filas para org_admin)
-- El acceso con datos reales es solo via agg_segment (SECURITY DEFINER)
-- ============================================================
GRANT INSERT ON public.responses TO anon, authenticated;
GRANT SELECT ON public.responses TO authenticated;
-- ============================================================
-- answers
-- INSERT: al enviar el form
-- SELECT: authenticated puede hacer el query (RLS devuelve 0 filas para org_admin)
-- ============================================================
GRANT INSERT ON public.answers TO anon, authenticated;
GRANT SELECT ON public.answers TO authenticated;