Files
motor-de-encuestas/docs/adr/ADR-004-capa-de-identidad.md

3.2 KiB
Raw Permalink Blame History

ADR-004 — Capa de identidad: respondente anónimo vs staff con SSO

  • Estado: Aceptado (frontera) · Diferido (integración Keycloak)
  • Fecha: (completar con fecha de commit)

Contexto

El equipo construye una familia de productos Inquality que se autentican contra un Keycloak propio (proyecto en curso de otro equipo). Surge la pregunta de si esa capa de identidad aplica a este producto. El producto tiene dos audiencias con necesidades opuestas (respondente anónimo vs staff interno), por lo que la respuesta no es única.

Decisión

Frontera dura (no negociable)

  • El flujo del respondente NUNCA se ata a un IdP. Las encuestas de v1 son anónimas: el respondente no se loguea, ni con Keycloak ni con nada. Atarlo a SSO destruiría el anonimato (la premisa de v1) y agregaría fricción que baja la tasa de respuesta. Lado respondente = anon key + RLS + sin identidad. Para siempre, mientras la encuesta sea anónima.
  • El staff interno SÍ puede usar SSO. El acceso del equipo a dashboards/administración —a través de la familia de productos— es donde Keycloak aporta: SSO único, gestión de usuarios centralizada, offboarding en un solo lugar (control de seguridad real para dato sensible), una sola fuente de verdad de identidad. Y Keycloak es self-hosteable → alinea con la dirección Dokploy/soberanía.

Integración técnica (cuando Keycloak madure)

Supabase soporta third-party auth: confía en JWT de un emisor externo si son firmados asimétricamente (RS256/ES256), expuestos vía OIDC Discovery URL, con kid en el header. Keycloak cumple. Dos caminos válidos:

  1. Registrar Keycloak como emisor OIDC confiable (más libre en self-host).
  2. Patrón universal: verificar el JWT de Keycloak en el edge e intercambiarlo por un JWT firmado por Supabase. Funciona con cualquier emisor. RLS lee los claims del token externo con auth.jwt() igual que con tokens de Supabase Auth.

No bloquear v1

Keycloak es un proyecto en curso de otro equipo. v1 no depende de él. v1 casi no necesita auth (encuestas anónimas + dashboard que presenta el staff). Estrategia:

  1. Diseñar las policies de RLS para que lean claims por nombre (org_id, role), no helpers exclusivos de Supabase Auth, para que el emisor sea intercambiable.
  2. v1 corre con auth nativa de Supabase para los pocos usuarios internos (o sin login interno si alcanza).
  3. Cuando Keycloak esté listo: emite esos claims, se registra como emisor confiable, y RLS sigue andando sin reescribir.

Consecuencias

  • (+) Identidad portable: el emisor del token se cambia por config, no por reescritura.
  • (+) Encaja con la familia de productos y con la soberanía (Keycloak self-host).
  • () Disciplina: nunca basar RLS en user_metadata (modificable por el usuario); usar claims verificados del servidor (Keycloak los da).
  • () Cuando se integre, alinear los claims de Keycloak (org_id, role) con lo que esperan las policies — tarea de config, no de esquema.

Relación con otros ADR

Vive sobre el patrón de backend de ADR-002 (Supabase como backend). La regla de keys de CLAUDE.md (rule 9) sigue aplicando: service_role nunca al cliente, pase lo que pase con el IdP.