ADR-0005 · Auth: Cognito mixto (humanos) + M2M en capas (webhooks)¶
- Status: Accepted (revisado 2026-05-13)
- Date: 2026-04-30 · Revisado: 2026-05-13
- Deciders: Cristian Fernández (Zerviz Group)
- Related: ADR-0002 (tenancy),
docs/discovery/00-phase1-prerequisites.md1.1/1.2/1.3 + Anexo A-01,docs/discovery/08-legacy-delta.md §6.5.
Revisión 2026-05-13 — UP nuevo + dominios¶
- Cognito existente
us-east-2_jce30mkvT(legacy, vivo desde 2026-05-07) no se reutiliza. Fase 2 crea un UP nuevozen-{env}-app-usersen la misma cuenta450972188274. La migración de usuarios desde el UP legacy se planifica como tarea aparte, post-cutover. - Dominios públicos del proyecto nuevo (sobre
zervizdev.compropiedad del owner): zen.zervizdev.com(+dev.zen.*,qa.zen.*) → frontal cliente (widget, SPA cliente, APIs públicas, webhooks externos).zen-admin.zervizdev.com→ consola admin interna (builder, reporting).auth.{env}.zen.zervizdev.com→ Hosted UI Cognito por env (ACM en us-east-1).- Los dominios legacy
zerviz.zengine.onlineylogin.zengine.onlinesiguen sirviendo al legacy y no se tocan.
Context¶
Decisión asentada: Cognito mixto (Cognito propio + federación opcional) para humanos. M2M en capas (firma + Lambda Authorizer + mTLS donde el proveedor lo soporte). Tier lógico = UP único; tier físico = UP por tenant.
Decision¶
Identidad humana (builder admin, agentes, ops)¶
- Cognito User Pool por tier:
- Tier lógico: un solo UP por env (
zen-{env}-app-users) compartido entre tenants SMB. - Tier físico enterprise: UP propio por tenant, en su cuenta dedicada.
- MFA TOTP obligatorio para todos los usuarios admin/ops. Opcional para usuarios end-user del builder por tenant.
- Federación opt-in por tenant: un tenant puede federar contra Azure AD / Google Workspace / Okta vía OIDC IdP en su UP. La habilitación queda en
ze_control_plane.tenants.federationy no impide login local con username/password (regla del owner: "tiene que poder funcionar solo un sistema"). - Claims obligatorios en JWT:
sub(Cognito user id)custom:tenant_id(uuid del tenant)custom:tier(logical|physical)custom:roles(array:tenant-admin,agent,viewer,platform-ops)- Token TTL: access 60 min, refresh 30 días, ID 60 min.
- Hosted UI activado con custom domain
auth.{env}.zen.zervizdev.com(ACM en us-east-1). - Trigger Lambdas Cognito:
Pre Sign-up→ valida invitation token detenant-mgmt.Pre Token Generation→ inyectacustom:tenant_idycustom:rolesdesdetenant-mgmt.Post Confirmation→ publicaUserAuthenticated.
M2M (webhooks externos hacia ZEngine)¶
Capas obligatorias en orden de ejecución:
- Layer 1 · WAF rate-limit + IP allowlist sobre el endpoint público en CloudFront/APIGW. IP allowlist se aplica donde el proveedor publica rangos estables (Five9, partners B2B).
- Layer 2 · Validación de firma criptográfica del proveedor: obligatoria para todos los webhooks que el proveedor sí firma:
- Meta:
x-hub-signature-256conMETA_APP_SECRET. - 360dialog: header
D360-WEBHOOK-SIGNATURE(cuando esté disponible) + IP allowlist en su defecto. - Five9: header de firma propio.
- Layer 3 · Lambda Authorizer con secreto rotativo por proveedor (
/ze/{env}/webhook-secrets/<provider>), válido como anti-replay window (5 min) + nonce/timestamp checks. Aplica a rutas/webhook/*. - Layer 4 · mTLS en API Gateway sólo para integraciones B2B donde el proveedor lo soporte (Five9 outbound y partners enterprise futuros). API Gateway HTTP API con
mTLS truststoreen bucket S3 dedicadoze-{env}-mtls-truststore.
Nota crítica (Anexo A-01): Meta y 360dialog NO soportan mTLS desde su lado. Para esos proveedores se aplican Layers 1+2+3 únicamente.
M2M (ZEngine hacia externos)¶
- Cada strategy connector recupera credenciales de Secrets Manager
/ze/{env}/connectors/<provider>/<tenant_id>(KMS CMK por tenant). - Cache in-memory ≤ 5 min con invalidación por evento
SecretRotatedpublicado porconnector-orchestrator. - TLS 1.2 mínimo en outbound; TLS 1.3 cuando el peer lo permita.
M2M (servicio ↔ servicio interno)¶
- IAM SigV4 entre Lambdas (no JWT) cuando se invoca por API GW interno.
- EventBridge cross-service no requiere auth (la infra es trusted).
Consequences¶
Positive¶
- 4 capas en webhooks reducen drásticamente el R-02 / R-11.
- UP único en tier lógico simplifica login para SMB; UP por tenant en tier físico cumple aislamiento contractual.
- Federación opt-in evita locking-in con un IdP central.
Negative¶
- mTLS truststore agrega ops (rotación cada 12 meses).
- Cognito UP no permite cambiar nombre fácilmente — naming locked.
- Lambda Authorizer agrega 30–80 ms de latencia. Aceptable para webhooks.
Alternatives considered¶
- Sólo firma del proveedor: rechazado, no protege contra replay si el secret se filtra.
- Sólo Lambda Authorizer: rechazado, perdería el chain-of-trust del proveedor.
- OAuth2 mTLS para todos: rechazado, no soportado por proveedores principales.
- Auth0/Okta como IdP único: rechazado, costo + lock-in. Cognito es nativo AWS.
Tenant-isolation impact¶
- JWT
custom:tenant_idse valida enpackages/tenant-contextmiddleware antes de cualquier acceso a datos. - Cross-tenant token theft mitigado por: (a) aud claim del UP (b) refresh token rotation (c) revocación inmediata desde
tenant-mgmt. - Tier físico: tokens emitidos por UP del tenant no son válidos en otra cuenta (audience-bound).
Blast radius¶
- UP comprometido (lógico) ⇒ todos los SMB del env afectados → rotación masiva del firmador + force sign-out.
- UP comprometido (físico) ⇒ sólo el tenant.
- Webhook secret comprometido ⇒ rotación + replay window cierra ataque en ≤ 5 min.
Cost note¶
- Cognito: free tier 50k MAU; sobre eso USD 0.0055/MAU. Esperado dev gratis; prod: USD 50–500/mes según escala.
- Lambda Authorizer: ~ USD 0.20/millón requests.
- mTLS truststore: gratis (S3).
ISO 27001 controls touched¶
- A.9.2.1 / A.9.2.2 / A.9.2.4 (gestión de identidad y credenciales): Cognito + invitation flow.
- A.9.4.1 (control de acceso a información): RLS+IAM con
tenant_iddesde JWT. - A.9.4.2 (procedimientos seguros de inicio de sesión): MFA TOTP.
- A.10.1.1 (criptografía): mTLS, KMS, JWT firma.
- A.13.1.1 (controles de red): WAF + IP allowlist.
Sources¶
docs/discovery/00-phase1-prerequisites.md1.1, 1.2, 1.3 + Anexo A-01, A-02.- AWS docs: Cognito triggers, API GW HTTP API JWT authorizer, mTLS.