Saltar a contenido

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.md 1.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 nuevo zen-{env}-app-users en la misma cuenta 450972188274. La migración de usuarios desde el UP legacy se planifica como tarea aparte, post-cutover.
  • Dominios públicos del proyecto nuevo (sobre zervizdev.com propiedad 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.online y login.zengine.online siguen 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.federation y 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 de tenant-mgmt.
  • Pre Token Generation → inyecta custom:tenant_id y custom:roles desde tenant-mgmt.
  • Post Confirmation → publica UserAuthenticated.

M2M (webhooks externos hacia ZEngine)

Capas obligatorias en orden de ejecución:

  1. 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).
  2. Layer 2 · Validación de firma criptográfica del proveedor: obligatoria para todos los webhooks que el proveedor sí firma:
  3. Meta: x-hub-signature-256 con META_APP_SECRET.
  4. 360dialog: header D360-WEBHOOK-SIGNATURE (cuando esté disponible) + IP allowlist en su defecto.
  5. Five9: header de firma propio.
  6. 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/*.
  7. 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 truststore en bucket S3 dedicado ze-{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 SecretRotated publicado por connector-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_id se valida en packages/tenant-context middleware 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_id desde 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.md 1.1, 1.2, 1.3 + Anexo A-01, A-02.
  • AWS docs: Cognito triggers, API GW HTTP API JWT authorizer, mTLS.