ETAPA_CALIDAD: Nota de discrepancia: las 5 clases de P1 usan var(--color-primary), no var(--color-re-teal) como decía el prompt — ambas resuelven al mismo hex #43BBC8. Hice el reemplazo por nombre de clase (igual intención: texto teal → carbón), no por el literal del grep.
This commit is contained in:
106
sprints/sprint-5/INSUMOS_AUDIT_LOG.md
Normal file
106
sprints/sprint-5/INSUMOS_AUDIT_LOG.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# INSUMOS — Etapa Audit Log append-only (Sprint compliance, SEC-002)
|
||||
|
||||
> Material de contexto para que Claude (Projects, arquitecto) redacte el ETAPA_PROMPT.md
|
||||
> de esta etapa. No es el prompt en sí — es lo que el arquitecto necesita para escribirlo
|
||||
> bien, sin tener que releer todo el repo.
|
||||
|
||||
---
|
||||
|
||||
## 1. Por qué esta etapa, y por qué este alcance
|
||||
|
||||
`BACKLOG.md` (SEC-002) y `COMPLIANCE.md` §5.1 piden, dentro del sprint de compliance,
|
||||
un "registro de auditoría append-only (log inmutable de operaciones sensibles)". El
|
||||
director priorizó esta pieza primero, antes de hashing de integridad, trazabilidad de
|
||||
cambios o cifrado en reposo (esas quedan para etapas futuras del mismo sprint).
|
||||
|
||||
COMPLIANCE.md §5.1 pide loggear 3 cosas: accesos a datos sensibles, cambios de
|
||||
configuración, y ejecución de migraciones. Evalué las 3 y propongo **acotar el alcance
|
||||
de esta etapa a 2 de las 3**:
|
||||
|
||||
1. **Migraciones (DDL)** — factible con un event trigger nativo de Postgres
|
||||
(`ddl_command_end`), sin tocar el flujo de deploy.
|
||||
2. **Cambios de configuración** — triggers `AFTER INSERT/UPDATE/DELETE` en
|
||||
`user_roles` (altas/bajas/cambios de `app_role`/`org_id`) y en `surveys` cuando
|
||||
cambia `status` (activación/desactivación de encuestas).
|
||||
3. **Acceso a datos sensibles — propongo DEFERIR explícitamente.** Verificado en
|
||||
COMPLIANCE.md §3.2: hoy ningún camino de código (ni `/admin/responses` ni las RPCs
|
||||
`rpc_me_*`) lee columnas `is_sensitive=true`. Instrumentar "acceso" sin que exista
|
||||
un acceso real sería simular cobertura. Cuando se construya el primer camino que sí
|
||||
lea sensibles, ESE PR debe agregar su propio log de acceso junto con el código que
|
||||
lo necesita — no antes.
|
||||
|
||||
El arquitecto puede confirmar o ajustar este recorte; lo presento como punto de partida,
|
||||
no como cerrado (esto todavía no se aprobó con el director, se está armando el prompt).
|
||||
|
||||
---
|
||||
|
||||
## 2. Decisiones de diseño que ya tienen forma (para que el prompt las fije)
|
||||
|
||||
- **Tabla nueva:** `public.audit_log` — append-only real:
|
||||
- Ningún rol (`anon`, `authenticated`, ni `service_role` vía API) tiene
|
||||
`INSERT`/`UPDATE`/`DELETE` directo. Solo escriben funciones `SECURITY DEFINER`
|
||||
de los triggers, propiedad de `postgres` (mismo patrón que
|
||||
`custom_access_token_hook`, ver `supabase/migrations/20260627000001_auth_user_roles.sql`).
|
||||
- Trigger `BEFORE UPDATE OR DELETE ON audit_log` que aborta con excepción — segunda
|
||||
barrera, defensa en profundidad (no a prueba de un operador con `psql -U postgres`
|
||||
en el VPS — ver gap conocido abajo).
|
||||
- Lectura: RLS, solo `platform_admin` (reusar `current_app_role()`, ver
|
||||
`supabase/migrations/20260531000003_rls_policies.sql:17`).
|
||||
- **Columnas sugeridas (a validar por el arquitecto):** `id bigserial pk`,
|
||||
`occurred_at timestamptz default now()`, `actor_role text`, `actor_user_id uuid`,
|
||||
`action text`, `target_table text`, `target_id text`, `detail jsonb`.
|
||||
- **Gap conocido a documentar, no a resolver en esta etapa:** esto no protege contra
|
||||
`TRUNCATE`/`DROP` ejecutado por un superusuario directo en el VPS — mismo gap ya
|
||||
registrado en `SEC-003` (BACKLOG.md). Append-only a nivel de aplicación/RLS, no a
|
||||
prueba de acceso root a la base.
|
||||
|
||||
---
|
||||
|
||||
## 3. Convenciones del repo que el prompt debe respetar
|
||||
|
||||
- **Migraciones:** `supabase/migrations/`, naming `YYYYMMDDHHMMSS_descripcion.sql`.
|
||||
Última migración aplicada: `20260627000001_auth_user_roles.sql`. La próxima debe
|
||||
fecharse después de esa.
|
||||
- **Patrón SECURITY DEFINER + GRANT EXECUTE puntual:** ver
|
||||
`custom_access_token_hook` en `20260627000001_auth_user_roles.sql` — función
|
||||
`SECURITY DEFINER STABLE`, `GRANT EXECUTE ... TO supabase_auth_admin` (rol
|
||||
específico, no `PUBLIC`). Mismo patrón a replicar para las funciones de trigger
|
||||
de `audit_log`.
|
||||
- **Helpers RLS existentes a reusar, no reinventar:** `public.current_app_role()`
|
||||
y `public.current_org_id()` (`20260531000003_rls_policies.sql:17-30`).
|
||||
- **Verificación obligatoria antes de aplicar en VPS:** mostrar el SQL final completo
|
||||
y esperar OK explícito del director antes de correrlo en producción (ya es práctica
|
||||
establecida en este proyecto — ver incidente VPS del 27 jun, recuperación documentada
|
||||
en `docs/estado/ESTADO_PROYECTO_JUNIO_2026.md` §2.1).
|
||||
- **Formato esperado del archivo de etapa:** seguir la estructura de
|
||||
`sprints/sprint-4/ETAPA_AUTH_PROMPT.md` o `ETAPA_4G_PROMPT.md` — Objetivo,
|
||||
Decisiones ya tomadas (no consultar), Tareas, DoD, Qué reportar (datos concretos,
|
||||
no "funcionó"), Qué NO hacer, Versionado (mensaje de commit sugerido con tag
|
||||
`[compliance]` o similar).
|
||||
|
||||
---
|
||||
|
||||
## 4. Qué NO debería pedir el prompt (fuera de alcance de esta etapa)
|
||||
|
||||
- Hashing de integridad SHA-256 (siguiente pieza del mismo sprint, etapa separada).
|
||||
- Cifrado en reposo (es trabajo de VPS/infraestructura, no de migración SQL).
|
||||
- Trazabilidad histórica completa de cambios de datos (triggers de historial / WAL) —
|
||||
etapa separada también.
|
||||
- Logging de acceso a datos sensibles (ver §1, punto 3 — deferido a cuando exista
|
||||
código que lea sensibles).
|
||||
- pgaudit o cualquier extensión nueva — no está en el Supabase self-hosted actual,
|
||||
agregar una extensión es Nivel 3 aparte (afecta infraestructura/dependencias).
|
||||
|
||||
---
|
||||
|
||||
## 5. Referencias
|
||||
|
||||
- `COMPLIANCE.md` §5 (roadmap auditabilidad), §5.2 (por qué no blockchain), §3.2
|
||||
(qué es sensible y cómo se protege hoy).
|
||||
- `BACKLOG.md` → SEC-002, SEC-003 (gap de TRUNCATE), SEC-004 (bypass REST, contexto
|
||||
de otro riesgo residual ya aceptado, mismo espíritu de "documentar en vez de
|
||||
sobre-construir").
|
||||
- `TECH_DEBT.md` → TECH-DEBT-008 (resuelto 27 jun, ejemplo de cómo se cierra un ítem).
|
||||
- `docs/estado/ESTADO_PROYECTO_JUNIO_2026.md` — estado general post-release v3.0.0
|
||||
+ incidente VPS, para que el arquitecto tenga el panorama completo antes de escribir
|
||||
el prompt.
|
||||
Reference in New Issue
Block a user