79 lines
3.7 KiB
SQL
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;
|