ADR-001 — Identidad verificada en la Lambda y catálogo de experiencias en el servidor¶
Autor: Iker Acevedo
Fecha: 2026-11-10
Estado: Propuesta (pasa a Aceptada cuando Iker apruebe la salida a producción)
Contexto¶
El Sistema de Experiencias necesita guardar la experiencia visual de cada usuario y decir qué experiencias puede usar. Hay tres decisiones que no son obvias:
- De dónde sale la identidad. El authorizer Cognito del REST valida el token, pero en PreProd ya hubo rutas del mismo REST creadas con autorización
NONE(métricas) y el authorizer de PreProd apunta al pool de la cuenta de producción. Confiar solo en que el gateway filtre es frágil. - Quién decide la disponibilidad de una experiencia (
borrador,beta,general,retirada): el front no puede, porque cualquiera puede alterar el código del navegador. - Dónde vive la configuración del catálogo y cómo se cambia con seguridad.
También hubo que decidir cómo publicar las rutas en el REST compartido sin romper a los demás dominios.
Opciones consideradas¶
Opción A — Identidad solo del authorizer (claims del gateway)¶
La Lambda lee requestContext.authorizer.claims.sub.
Pros: menos código, sin descargar JWKS.
Contras: si una ruta queda con autorización NONE (ya pasó en PreProd) cualquiera suplanta a cualquiera; sin claims la Lambda no sabría que no está autenticado.
Opción B — Authorizer del gateway + verificación de firma del JWT en la Lambda (elegida)¶
La Lambda verifica RS256, iss, exp, nbf, token_use y app client contra el JWKS del user pool, y toma el sub solo de ese token. El authorizer sigue puesto en las rutas.
Pros: defensa en profundidad; es el patrón ya usado en métricas e inventario; falla cerrada si falta configuración.
Contras: código duplicado del verificador (mejora pendiente: librería común); una descarga del JWKS por contenedor.
Opción C — Catálogo en una colección de MongoDB administrable desde una pantalla¶
Pros: cambiar el catálogo sin desplegar.
Contras: una escritura de administración más que proteger, una pantalla más, y cada GET dependería de otra consulta. Excesivo para empezar.
Decisión¶
- Identidad: opción B. El
subsale únicamente del JWT verificado dentro de la Lambda y se valida con un formato estricto. La ruta es/preferencias/miay no acepta identificadores. - Disponibilidad: la decide el servidor.
generalpara todos;betapara quienes tengan el rolExperiencia(variableROLES_BETA) oDesarrollador;borradorsoloDesarrollador(ROLES_BORRADOR);retiradapara nadie. Los roles se leen deUsersy nunca se devuelven ni se aceptan del cliente. Cuando una experiencia pasa ageneral, la ven todos los usuarios (el front sigue mostrando a cada uno solo sus módulos asignados). - Catálogo: (sustituida por ADR-002: el catálogo ahora vive en la colección
Experiencias) variables de entorno gestionadas por Terraform (EXPERIENCIAS,TEMAS,ROLES_*,ORIGEN_PERMITIDO). Cambiarlo es un cambio revisado conplany reversible volviendo aclasica:general. La Lambda falla cerrada si la configuración es inválida (clasica:generalsiempre presente). - Publicación: el stack
corecrea sus rutas en el REST existente y publicaids_para_despliegue; el dueño del REST de PreProd (environments/preprod/datos) los suma al trigger de su deployment (el mismo mecanismo de métricas y autenticación). En producción el deployment lo publica Iker con el CLI. Se descartócreate-deploymentdesde el pipeline conignore_changesporque rompía la regla de un solo dueño del stage. - CORS: el preflight
OPTIONSlo responde la Lambda (no un MOCK del gateway) para devolver el origen exacto entre una lista cerrada; nunca*. - Base de datos: se usa la cadena actual (decisión de Iker 2026-11-10). La Lambda solo toca
PreferenciasUsuario(lectura/escritura) yUsers(lectura con proyección deroles). El usuario de base de datos con permisos mínimos queda como mejora.
Consecuencias¶
Positivas
- Un token falso o una ruta mal configurada no permiten leer ni escribir preferencias ajenas.
- Un front manipulado no puede activar una experiencia que no le corresponde (422).
- Revertir todo es un cambio de una línea (clasica:general) y el front tolera la ausencia de la API.
Negativas / riesgos aceptados
- Código del verificador JWT duplicado en tres Lambdas (mejora: librería compartida).
- La Lambda tiene acceso a toda la base por la cadena de conexión compartida (mejora: usuario mínimo).
- Un 401 del authorizer no lleva cabeceras CORS (comportamiento del REST compartido).
Relacionado¶
Autor: Iker Acevedo¶
Fecha creacion: 2026-11-10
Estado: propuesta