← Arquitectura por épica

FT-USR-01 · Identidad y autenticación de usuarios internos…

Arquitectura del Nuevo PIM por épica · corte del 18-oct-2026

Propuesta del TL: no sustituye la spec de cada épica

Actualizado el 18-oct-2026. Primera versión de la arquitectura de esta épica.

Qué responde. Cómo funciona por dentro FT-USR-01: qué piezas participan, en qué orden hablan, qué APIs hay que construir con su request y su response, y qué le entrega a la épica siguiente.

Para quién. Los equipos que van a construir la épica, QA y arquitectura.

Estado. [Propuesta] del TL del Nuevo PIM, 18-oct-2026, construida sobre ADR-12. La spec de cada épica dice el qué; estas páginas, el cómo.

Fuente. docs/arquitectura/por-epica/epicas/FT-USR-01.json, generada con generar.py; la ficha de la épica es trazabilidad/features/FT-USR-01-identidad-y-autenticacion.md.

En 30 segundos

Hoy hay tres directorios que no se hablan (P360, Entrada Única y el inicio de sesión propio de Omega) y casi ningún servicio revisa quién llama. Esta épica deja una sola identidad: el proveedor de identidad de Entrada Única inicia la sesión, el BFF del portal la guarda y revisa el token en cada petición, cada módulo lo vuelve a revisar y MS-13, el directorio único, dice quién es cada persona o equipo, de qué negocio es y si está activo.

  • Módulo dueño: MS-13 Identidad y acceso. También participan: MS-02 Producto, MS-11 Activos digitales, MS-05 Auditoría, MS-03 Migración y convivencia.
  • Etapa T · Transversal. Recibe de otras épicas y entrega «PE-T · Usuario con permisos y bitácora».
  • APIs: construye 15 y usa 3 que construyen otras épicas.
  • Eventos: publica 1 y consume 1.

1. Dónde encaja

Recibe

DeQué
FT-USR-02 · Matriz de roles y permisos por módulo, acción, negocio y…El catálogo de roles y áreas, con las pantallas de cada uno, que la sesión y los roles efectivos devuelven.
FT-MIG-04 · Convivencia P360 ↔ nuevo PIMLa corrida de usuarios de MS-03 que concilia P360, Entrada Única y Foro por la cuenta del proveedor de identidad.

Entrega

AQué
PE-T · Usuario con permisos y bitácoraQuien llama ya se identificó con un token válido, el BFF y cada módulo lo revisaron, MS-13 dijo quién es, y su acceso quedó en la bitácora de MS-05.
FT-USR-02 · Matriz de roles y permisos por módulo, acción, negocio y…Los usuarios del directorio, con tipo, negocios, proveedor o seller, áreas y secciones, a los que se les dan roles.
FT-USR-03 · Control de acceso por API para tercerosEl mismo proveedor de identidad y la misma librería del token para los clientes de máquina de los terceros.
FT-ARQ-02 · Bitácora inmutable y versionado de producto, plantilla y…El «quién» de cada evento: ID, rol y área del actor, tomados del token y del directorio.
FT-ARQ-01 · Núcleo headlessCada llamada a la API de producto llega autenticada y con los roles efectivos de quien llama.
FT-PRD-09 · Contrato de propuestas con Entrada ÚnicaLa sesión del portal en el BFF, con la que las pantallas de propuestas dejan de depender de la identidad de Entrada Única.

2. Diagrama de contexto

Quién participa y cómo se conecta. Las pantallas llegan por el BFF del portal, que valida el token y compone; cada módulo vuelve a validar el token y decide sus permisos con los roles de MS-13.

🟩 Verde: nuevo, se construye · 🟦 Azul: ya existe y se queda, se reutiliza su código · 🟧 Naranja: temporal o se retira (se apaga en R3) · ⬜ Gris: sistema externo · ★ módulo dueño

Sistemas externos

Nuevo PIM · un solo sistema

Pantallas y sistemas

Personas

Entra por la puerta del portal, con l…

Iniciar sesión

Lo manda a identificarse con su cuenta
Cambia el código por el token y revis…

Regreso del proveedor de identidad

Quién soy
Preparar un cambio de usuario
y 1 más

Sesión y menú
Ficha de un usuario con sus accesos

Buscar productos

Roles efectivos de quien llama

Lee cada minuto los inicios de sesión
Crea el cliente de máquina del equipo
y 2 más

Bitácora del proveedor de identidad

Pide su token con la credencial del e…

Entra por la puerta del agente, con l…

Pedir permiso para subir un archivo

Roles efectivos de quien llama

Lanzar una corrida de migración

Lee los 199 usuarios y sus 32 grupos

Lee los usuarios de Entrada Única y d…

Carga conciliada del directorio

Hasta R2, toma el contexto de Entrada…

USER_CHANGED

USER_CHANGED

Historial de accesos

bitácora

Compras

Administración del catálogo

Entrada Única · Vendor Center

Agente del estudio

Entrada del clúster

BFF del portal

★ MS-13 Identidad y acceso

MS-02 Producto

MS-11 Activos digitales

MS-05 Auditoría

MS-03 Migración y convivencia

Base pim

Eventos

Proveedor de identidad

P360

Backends de hoy de Entrada Única y Foro

Contexto de FT-USR-01

3. Diagrama de flujo

El camino principal, paso por paso. Cuando una pantalla llama a un módulo se ven dos flechas: la pantalla al BFF y el BFF al módulo. Los eventos salen del outbox del módulo después de guardar; quien los consume ignora los repetidos.

MS-05 AuditoríaMS-02 ProductoBase·pimMS-13 Identidad y accesoProveedor de identidadEntrada del clústerEntrada Única · Vendor CenterMS-05 AuditoríaMS-02 ProductoBase·pimMS-13 Identidad y accesoProveedor de identidadEntrada del clústerEntrada Única · Vendor CenterComprasBFF1. Abre el portal de catalogación2. Entra por la puerta del portal, con límite por usuario3. Pide iniciar sesiónGET /bff/v1/session/login4. Lo manda a identificarse con su cuenta5. Regresa con un código de un solo usoGET /bff/v1/session/callback6. Cambia el código por el token y revisa su firma7. Pregunta quién es y qué pantallas le tocanGET /api/v2/me8. Revisa el token otra vez y que esté activo9. Pide la sesión y el menú de su perfilGET /bff/v1/session10. Busca productos, el BFF reenvía el tokenPOST /api/v2/products/search11. Revisa el token y pide sus roles, con cachéGET /internal/identity/permissions?userId=12. Lee cada minuto los inicios de sesión13. Entrega los accesos a la bitácoraPOST /internal/audit/idp-logsComprasBFF
Flujo principal de FT-USR-01
Los pasos en texto
PasoDeAQué haceAPI o evento
1ComprasEntrada Única · Vendor CenterAbre el portal de catalogación—
2Entrada Única · Vendor CenterEntrada del clústerEntra por la puerta del portal, con límite por usuario—
3Entrada del clústerBFF del portalPide iniciar sesiónAPI-BFF-501
4BFF del portalProveedor de identidadLo manda a identificarse con su cuenta—
5Proveedor de identidadBFF del portalRegresa con un código de un solo usoAPI-BFF-502
6BFF del portalProveedor de identidadCambia el código por el token y revisa su firma—
7BFF del portalMS-13 Identidad y accesoPregunta quién es y qué pantallas le tocanAPI-13-002
8MS-13 Identidad y accesoBase pimRevisa el token otra vez y que esté activo—
9Entrada Única · Vendor CenterBFF del portalPide la sesión y el menú de su perfilAPI-BFF-503
10Entrada Única · Vendor CenterMS-02 Producto (por el BFF)Busca productos; el BFF reenvía el tokenAPI-02-001
11MS-02 ProductoMS-13 Identidad y accesoRevisa el token y pide sus roles, con cachéAPI-13-001
12MS-13 Identidad y accesoProveedor de identidadLee cada minuto los inicios de sesión—
13MS-13 Identidad y accesoMS-05 AuditoríaEntrega los accesos a la bitácoraAPI-05-005

3.1 Un equipo entra con su propia credencial

MS-11 Activos digitalesEntrada del clústerAgente del estudioProveedor de identidadMS-13 Identidad y accesoEntrada Única · Vendor CenterMS-11 Activos digitalesEntrada del clústerAgente del estudioProveedor de identidadMS-13 Identidad y accesoEntrada Única · Vendor CenterAdministración del catálogoBFF1. Registra el equipo del estudio con un solo rol2. Pide el plan del registro del equipoPOST /api/v2/users/plans3. Confirma el registroPOST /api/v2/identity-plans/{planId}/apply4. Crea el cliente de máquina del equipo5. Pide su token con la credencial del equipo6. Entra por la puerta del agente, con límite por equipo7. Sube la foto a Activos con su tokenPOST /api/v2/assets/uploads8. Pide los roles del equipo: sólo subir fotosGET /internal/identity/permissions?userId=Administración del catálogoBFF
Un equipo entra con su propia credencial

3.2 Del directorio de Entrada Única al directorio único (R1 a R2)

Proveedor de identidadMS-13 Identidad y accesoBackends de hoy de Entrada Única…P360MS-03 Migración y convivenciaEntrada Única · Vendor CenterProveedor de identidadMS-13 Identidad y accesoBackends de hoy de Entrada Única…P360MS-03 Migración y convivenciaEntrada Única · Vendor CenterAdministración del catálogoBFF1. Pide la corrida de usuarios en modo prueba2. Lanza la corrida USERSPOST /api/v2/migration/runs3. Lee los 199 usuarios y sus 32 grupos4. Lee los usuarios de Entrada Única y de Foro5. Carga el directorio conciliado por cuentaPOST /internal/identity/bulk-load/users6. Invita a quien todavía no tiene cuenta7. Hasta R2, toma el contexto de Entrada Única8. Desde R2, toma el contexto del directorioGET /api/v2/meAdministración del catálogoBFF
Del directorio de Entrada Única al directorio único (R1 a R2)

3.3 Bloquear a un usuario y ver sus accesos

MS-05 AuditoríaMS-02 ProductoEventosProveedor de identidadMS-13 Identidad y accesoEntrada Única · Vendor CenterMS-05 AuditoríaMS-02 ProductoEventosProveedor de identidadMS-13 Identidad y accesoEntrada Única · Vendor CenterAdministración del catálogoBFF1. Bloquea a un usuario que dejó el área2. Pide el plan del bloqueoPOST /api/v2/users/plans3. Confirma el bloqueoPOST /api/v2/identity-plans/{planId}/apply4. Bloquea la cuenta y corta sus sesiones5. Avisa el cambio del usuarioUSER_CHANGED6. Entrega el aviso para vaciar su cachéUSER_CHANGED7. Abre la ficha del usuario con sus accesosGET /bff/v1/access-admin/users/{userId}8. Trae inicios de sesión, bloqueos e intentos negadosGET /api/v2/audit/accessAdministración del catálogoBFF
Bloquear a un usuario y ver sus accesos

4. Si algo sale mal

  • El usuario está bloqueado, dado de baja o su membresía venció. El BFF no abre la sesión y cualquier módulo responde 401 aunque el token siga vigente; el intento queda en el historial de accesos que ve Administración de accesos.
  • Llega una cabecera de roles o de usuario desde el navegador o desde otro sistema. El BFF la borra y los módulos la ignoran: los roles salen siempre del directorio. Si llega a un módulo, queda como evento de seguridad en MS-05.
  • MS-13 no responde. El BFF y los módulos siguen leyendo con lo que tengan en caché hasta 15 minutos y rechazan escrituras con 503 DEPENDENCY_UNAVAILABLE; nadie entra por primera vez sin directorio. Operación recibe la alerta.
  • El token vence a media captura. El BFF lo renueva con el token de renovación sin perder la pantalla; si la sesión pasó de 8 horas, pide entrar de nuevo y el borrador sigue guardado en MS-02.

5. APIs

Las que construye esta épica (15)

GET /bff/v1/session/login · Iniciar sesión
CampoValor
APIAPI-BFF-501 · BFF del portal
Para quéEmpieza el inicio de sesión: manda al usuario a la página del proveedor de identidad con un código de un solo uso (PKCE) y recuerda a qué pantalla volver.
En esta épicaEmpezar el inicio de sesión con el proveedor de identidad
Quién la llamaEntrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF)
PermisoCualquiera, todavía sin sesión
CabecerasX-Request-Id
ParámetrosreturnTo = /catalogacion/propuestas

Request

null

Response · 302

null

Errores

HTTPCódigoCuándo
400VALIDATION_ERRORreturnTo no es una ruta del portal
429RATE_LIMITEDLa entrada frenó demasiados intentos desde el mismo origen
GET /bff/v1/session/callback · Regreso del proveedor de identidad
CampoValor
APIAPI-BFF-502 · BFF del portal
Para quéRecibe el código del proveedor de identidad, lo cambia por los tokens, revisa su firma con las llaves públicas del proveedor, confirma que el usuario está activo y deja la sesión en una cookie cifrada, sin base de datos.
En esta épicaRecibir el código, revisar el token y dejar la sesión cifrada
Quién la llamaEntrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF)
PermisoQuien regresa del proveedor de identidad con un código válido
CabecerasX-Request-Id
Parámetroscode = (código de un solo uso), state = st-91c2

Request

null

Response · 302

null

Errores

HTTPCódigoCuándo
401AUTHORIZATION_ERROREl código venció, ya se usó o el state no coincide
403AUTHORIZATION_ERROREl usuario no está activo en el directorio
503DEPENDENCY_UNAVAILABLEEl proveedor de identidad o el directorio no responden
GET /bff/v1/session · Sesión y menú
CampoValor
APIAPI-BFF-503 · BFF del portal
Para quéDa al portal la sesión vigente: quién es, su perfil, el menú que le toca según sus capacidades (permisos de pantalla), sus secciones y cuántos avisos tiene sin leer. Junta MS-13 (API-13-002) y MS-14 (API-14-001). Hasta R2 el contexto sale de Entrada Única; desde R2, del directorio.
En esta épicaLa sesión y el menú según las pantallas de sus roles
Quién la llamaEntrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF)
PermisoCualquier usuario con sesión
CabecerasX-Request-Id
También la usanFT-USR-02

Request

null

Response · 200

{
  "success": true,
  "data": {
    "user": {
      "userId": "USR-000231",
      "displayName": "Comprador Hogar 03",
      "type": "INTERNAL",
      "businesses": [
        "MER",
        "SUB"
      ],
      "areas": [
        "COMPRAS-HOGAR"
      ],
      "sections": [
        "2001",
        "2004"
      ]
    },
    "roles": [
      "COMPRAS"
    ],
    "menu": [
      {
        "section": "Propuestas",
        "items": [
          {
            "screen": "BANDEJA_VISTO_BUENO",
            "path": "/catalogacion/visto-bueno"
          }
        ]
      },
      {
        "section": "Reportes",
        "items": [
          {
            "screen": "TABLEROS",
            "path": "/reportes/tableros"
          },
          {
            "screen": "MIS_EXPORTES",
            "path": "/reportes/exportes"
          }
        ]
      }
    ],
    "unreadNotifications": 4,
    "idleExpiresAt": "2026-10-18T15:34:05Z",
    "expiresAt": "2026-10-18T23:04:05Z",
    "csrfToken": "(valor por sesión)",
    "contextSource": "DIRECTORIO"
  }
}

Errores

HTTPCódigoCuándo
401AUTHORIZATION_ERRORNo hay sesión o ya venció
POST /bff/v1/session/logout · Cerrar sesión
CampoValor
APIAPI-BFF-504 · BFF del portal
Para quéCierra la sesión: borra la cookie, revoca el token de renovación en el proveedor de identidad y deja el registro en la bitácora de accesos.
En esta épicaCerrar la sesión y revocar la renovación
Quién la llamaEntrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF)
PermisoCualquier usuario con sesión
CabecerasX-Request-Id, X-CSRF-Token

Request

{}

Response · 200

{
  "success": true,
  "data": {
    "loggedOut": true
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERRORFalta la cabecera contra falsificación de peticiones
GET /bff/v1/access-admin/users/{userId} · Ficha de un usuario con sus accesos
CampoValor
APIAPI-BFF-505 · BFF del portal
Para quéLa pantalla de administración de un usuario: sus datos y membresías del directorio (MS-13) junto con sus inicios de sesión, bloqueos e intentos negados de la bitácora (MS-05).
En esta épicaLa ficha de un usuario con su historial de accesos
Quién la llamaEntrada Única · Vendor Center (por el BFF)
PermisoACCESS-ADMIN (permiso de pantalla; cada módulo vuelve a revisar el suyo)
CabecerasX-Request-Id
ParámetrosuserId = USR-000318, from = 2026-09-18, to = 2026-10-18

Request

null

Response · 200

{
  "success": true,
  "data": {
    "user": {
      "userId": "USR-000318",
      "displayName": "Analista QA 07",
      "type": "INTERNAL",
      "status": "ACTIVE",
      "origin": "FORO"
    },
    "memberships": [
      {
        "roleId": "QA",
        "scope": {
          "businesses": [
            "MER"
          ],
          "sections": [
            "2001"
          ]
        },
        "validFrom": "2026-11-01T06:00:00Z",
        "validTo": "2027-10-31T23:59:59Z"
      }
    ],
    "access": [
      {
        "at": "2026-10-17T22:10:05Z",
        "kind": "LOGIN_OK",
        "app": "PORTAL"
      },
      {
        "at": "2026-10-17T22:31:40Z",
        "kind": "ACCESS_DENIED",
        "action": "FLU-ACCEPT",
        "resource": "PRD-0004812"
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERROREl perfil no tiene la pantalla de administración de accesos
404NOT_FOUNDEl usuario no existe
GET /internal/identity/permissions?userId= · Roles efectivos de quien llama
CampoValor
APIAPI-13-001 · MS-13 Identidad y acceso
Para quéLe dice a cualquier módulo quién es quien llama (persona o equipo): tipo, estado, negocios, proveedor o seller, áreas, secciones y roles con su alcance y vigencia. Cada módulo decide con su propia tabla de permisos (el motor de MS-02, MS-01 para el catálogo) y guarda la respuesta 5 minutos (ADR-05).
En esta épicaLos roles efectivos de quien llama, que cada módulo guarda 5 minutos
Quién la llamaMS-01 Catálogo, MS-02 Producto, MS-04 Reportes, MS-05 Auditoría, MS-06 Evaluación, MS-11 Activos digitales, MS-12 Estudio fotográfico, MS-14 Avisos y ayuda, MS-15 IA y enriquecimiento
PermisoSólo las cuentas de servicio de los módulos del PIM
CabecerasAuthorization, X-Request-Id
ParámetrosuserId = idp/5f2c9a71e0
También la usanFT-ACT-05, FT-ACT-06, FT-ARQ-01, FT-CAT-01, FT-FLU-01, FT-PLT-01, FT-PLT-02, FT-PRD-09, FT-REF-01, FT-USR-02

Request

null

Response · 200

{
  "success": true,
  "data": {
    "subject": "idp|5f2c9a71e0",
    "userId": "USR-000231",
    "type": "INTERNAL",
    "status": "ACTIVE",
    "businesses": [
      "MER",
      "SUB"
    ],
    "supplierIds": [],
    "sellerIds": [],
    "areas": [
      "COMPRAS-HOGAR"
    ],
    "sections": [
      "2001",
      "2004"
    ],
    "roles": [
      {
        "roleId": "COMPRAS",
        "scope": {
          "businesses": [
            "MER",
            "SUB"
          ],
          "sections": [
            "2001",
            "2004"
          ],
          "areas": [
            "COMPRAS-HOGAR"
          ]
        },
        "validTo": "2027-03-31T23:59:59Z"
      }
    ],
    "permissionsVersion": 41,
    "cacheSeconds": 300
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDEl sujeto no está en el directorio; el módulo responde 401 a quien llamó
403AUTHORIZATION_ERROREl usuario está bloqueado, dado de baja o fuera de vigencia; el módulo responde 401
503DEPENDENCY_UNAVAILABLEEl directorio no responde; el módulo lee con su caché hasta 15 minutos y rechaza escrituras
GET /api/v2/me · Quién soy
CampoValor
APIAPI-13-002 · MS-13 Identidad y acceso
Para quéLe dice al BFF quién es el usuario que inició sesión: tipo, negocios, proveedor o seller, áreas, secciones, roles y las pantallas que le tocan por sus roles. El BFF arma el menú y cuida cada pantalla con esto. Desde R2 es la fuente del contexto de la sesión.
En esta épicaQuién es el usuario de la sesión y qué pantallas le tocan
Quién la llamaBFF del portal
PermisoCualquier usuario con sesión válida, sobre su propio registro
CabecerasAuthorization, X-Request-Id

Request

null

Response · 200

{
  "success": true,
  "data": {
    "user": {
      "userId": "USR-004410",
      "displayName": "Proveedor Demo 01",
      "type": "SUPPLIER",
      "status": "ACTIVE",
      "businesses": [
        "MER"
      ],
      "supplierIds": [
        "PROV-0001"
      ],
      "sellerIds": [],
      "areas": [],
      "sections": [
        "2001"
      ]
    },
    "roles": [
      "PROVEEDOR"
    ],
    "screens": [
      "PROPUESTAS",
      "CARGA_MASIVA",
      "MIS_EXPORTES",
      "AYUDA"
    ],
    "lastLoginAt": "2026-10-18T14:58:12Z",
    "permissionsVersion": 41
  }
}

Errores

HTTPCódigoCuándo
401AUTHORIZATION_ERROREl token venció, no es válido o el usuario no está activo
GET /api/v2/users · Buscar usuarios
CampoValor
APIAPI-13-003 · MS-13 Identidad y acceso
Para quéBusca usuarios del directorio por tipo, estado, rol, área, sección, proveedor o seller, para la pantalla de administración de accesos.
En esta épicaBuscar usuarios en la administración de accesos
Quién la llamaBFF del portal
PermisoACCESS-ADMIN
CabecerasAuthorization, X-Request-Id
Parámetrostype = INTERNAL, status = ACTIVE, role = QA, area = `, section = 2001, q = , page = 1, size = 50`

Request

null

Response · 200

{
  "success": true,
  "data": {
    "items": [
      {
        "userId": "USR-000318",
        "displayName": "Analista QA 07",
        "type": "INTERNAL",
        "status": "ACTIVE",
        "roles": [
          "QA"
        ],
        "areas": [
          "QA-CONTENIDO"
        ],
        "sections": [
          "2001"
        ],
        "businesses": [
          "MER",
          "SUB"
        ],
        "origin": "FORO",
        "lastLoginAt": "2026-10-17T22:10:05Z"
      }
    ],
    "page": 1,
    "size": 50,
    "total": 1
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERRORQuien pide no tiene ACCESS-ADMIN
400VALIDATION_ERRORUn filtro trae un valor que no existe
POST /api/v2/users/plans · Preparar un cambio de usuario
CampoValor
APIAPI-13-004 · MS-13 Identidad y acceso
Para quéPrepara una invitación, un bloqueo, un desbloqueo, una baja, un cambio de membresías con alcance y vigencia, o el registro de un equipo del estudio, y dice qué roles y pantallas gana o pierde cada quien, sin escribir todavía.
En esta épicaInvitar, bloquear, dar de baja, cambiar membresías o registrar un equipo
Quién la llamaBFF del portal
PermisoACCESS-ADMIN
CabecerasAuthorization, X-Request-Id, Idempotency-Key
También la usanFT-USR-02

Request

{
  "operation": "SET_MEMBERSHIPS",
  "userId": "USR-000318",
  "version": 12,
  "memberships": [
    {
      "roleId": "QA",
      "scope": {
        "businesses": [
          "MER"
        ],
        "sections": [
          "2001"
        ]
      },
      "validFrom": "2026-11-01T06:00:00Z",
      "validTo": "2027-10-31T23:59:59Z"
    }
  ],
  "reason": "Cambio de área"
}

Response · 200

{
  "success": true,
  "data": {
    "planId": "pln-a41c07",
    "expiresAt": "2026-10-18T15:14:05Z",
    "summary": {
      "ok": 1,
      "blocked": 0
    },
    "items": [
      {
        "userId": "USR-000318",
        "rolesBefore": [
          "CATEGORY"
        ],
        "rolesAfter": [
          "QA"
        ],
        "screensGained": [
          "BANDEJA_QA"
        ],
        "screensLost": [
          "ARBOL_CATEGORIAS"
        ],
        "identityProviderActions": []
      }
    ],
    "applyUrl": "/api/v2/identity-plans/pln-a41c07/apply"
  }
}

Errores

HTTPCódigoCuándo
422VALIDATION_ERROREl rol o la sección no existen, o la vigencia termina antes de empezar
409VERSION_CONFLICTEl usuario cambió desde que se leyó
403AUTHORIZATION_ERRORQuien pide no tiene ACCESS-ADMIN
POST /api/v2/identity-plans/{planId}/apply · Confirmar un plan de identidad
CampoValor
APIAPI-13-007 · MS-13 Identidad y acceso
Para quéConfirma cualquier plan de MS-13 (usuarios, equipos, roles, hoja de roles o terceros): escribe, hace lo que toque en el proveedor de identidad (invitar, bloquear, crear o desactivar clientes), publica el aviso y deja un recibo.
En esta épicaConfirmar cualquier plan de identidad
Quién la llamaBFF del portal
PermisoEl mismo que pidió el plan
CabecerasAuthorization, X-Request-Id, Idempotency-Key
ParámetrosplanId = pln-a41c07
Escribe enusers, roles, partners, identity_outbox
Publicacatalog.identity.changed/USER_CHANGED, catalog.identity.changed/ROLE_CHANGED, catalog.identity.changed/PARTNER_CHANGED
También la usanFT-USR-02, FT-USR-03

Request

{}

Response · 202

{
  "success": true,
  "data": {
    "requestId": "req-3f90d1",
    "status": "ACCEPTED",
    "receiptUrl": "/api/v2/identity-receipts/req-3f90d1"
  }
}

Errores

HTTPCódigoCuándo
409PLAN_EXPIREDPasaron más de 10 minutos desde la vista previa
409VERSION_CONFLICTEl usuario, el rol o el tercero cambió después de la vista previa
409IDEMPOTENCY_MISMATCHSe repite la llave de idempotencia con otro plan
GET /api/v2/identity-receipts/{requestId} · Recibo de identidad
CampoValor
APIAPI-13-008 · MS-13 Identidad y acceso
Para quéDice si un cambio de identidad confirmado ya terminó, qué cambió en cada usuario, rol o tercero y qué respondió el proveedor de identidad.
En esta épicaVer el recibo de un cambio de identidad
Quién la llamaBFF del portal
PermisoQuien hizo la operación, o ACCESS-ADMIN
CabecerasAuthorization, X-Request-Id
ParámetrosrequestId = req-3f90d1

Request

null

Response · 200

{
  "success": true,
  "data": {
    "requestId": "req-3f90d1",
    "status": "DONE",
    "finishedAt": "2026-10-18T15:04:07Z",
    "items": [
      {
        "object": "USER",
        "id": "USR-000318",
        "result": "APPLIED",
        "version": 13
      }
    ],
    "identityProvider": [
      {
        "action": "NONE",
        "result": "OK"
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
404NOT_FOUNDNo existe el recibo o no es de quien llama
POST /internal/identity/bulk-load/users · Carga conciliada del directorio
CampoValor
APIAPI-13-017 · MS-13 Identidad y acceso
Para quéMS-03 carga los usuarios de P360, Entrada Única y Foro ya conciliados por su cuenta en el proveedor de identidad. Actualiza por esa cuenta, guarda los ID de cada sistema de origen y avisa sólo cuando cambia el estado o las membresías.
En esta épicaCargar el directorio conciliado de P360, Entrada Única y Foro
Quién la llamaMS-03 Migración y convivencia
PermisoSólo la cuenta de servicio de MS-03 (MIG-ADMIN)
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Escribe enusers, identity_outbox
Publicacatalog.identity.changed/USER_CHANGED

Request

{
  "runId": "run-users-0042",
  "source": "EU",
  "records": [
    {
      "idpSubject": "idp|5f2c9a71e0",
      "legacyIds": {
        "EU": "eu-88412",
        "P360": null,
        "FORO": null
      },
      "type": "SUPPLIER",
      "status": "ACTIVE",
      "businesses": [
        "MER"
      ],
      "supplierIds": [
        "PROV-0001"
      ],
      "profiles": [
        "PROVEEDOR"
      ]
    }
  ]
}

Response · 200

{
  "success": true,
  "data": {
    "runId": "run-users-0042",
    "received": 1,
    "created": 0,
    "updated": 1,
    "unchanged": 0,
    "invited": 0,
    "conflicts": []
  }
}

Errores

HTTPCódigoCuándo
409IDEMPOTENCY_MISMATCHEl mismo lote llega otra vez con contenido distinto
422VALIDATION_ERRORUn registro no trae cuenta del proveedor ni ID de origen, o dos cuentas apuntan a la misma persona
GET /api/v2/directory/display-names · Nombres visibles
CampoValor
APIAPI-13-018 · MS-13 Identidad y acceso
Para quéDa, para una lista de identificadores, el nombre visible de personas, áreas y proveedores o sellers con usuarios en el directorio, para que el BFF pinte bandejas e historias sin bajar el directorio. A un proveedor o seller sólo le devuelve nombres de áreas, no de personas.
En esta épicaNombres visibles de personas, áreas y proveedores para bandejas e historias
Quién la llamaBFF del portal
PermisoCualquier usuario con sesión
CabecerasAuthorization, X-Request-Id
ParámetrosuserIds = USR-000231,USR-000318, areaIds = COMPRAS-HOGAR,LOGISTICA, partnerIds = PROV-0001,SELLER-0001
También la usanFT-ARQ-02, FT-PRD-06

Request

null

Response · 200

{
  "success": true,
  "data": {
    "users": [
      {
        "userId": "USR-000231",
        "displayName": "Comprador Hogar 03"
      },
      {
        "userId": "USR-000318",
        "displayName": "Analista QA 07"
      }
    ],
    "areas": [
      {
        "areaId": "COMPRAS-HOGAR",
        "name": "Compras Hogar"
      },
      {
        "areaId": "LOGISTICA",
        "name": "Logística"
      }
    ],
    "partners": [
      {
        "partnerId": "PROV-0001",
        "name": "Proveedor 0001"
      },
      {
        "partnerId": "SELLER-0001",
        "name": "Seller Demo 01"
      }
    ]
  }
}

Errores

HTTPCódigoCuándo
400VALIDATION_ERRORPide más de 200 identificadores en una llamada
GET /api/v2/audit/access · Historial de accesos
CampoValor
APIAPI-05-004 · MS-05 Auditoría
Para quéLos inicios y cierres de sesión, intentos fallidos, bloqueos, cambios de membresía e intentos negados de un usuario o de un tercero en un periodo.
En esta épicaHistorial de accesos de un usuario o de un tercero
Quién la llamaBFF del portal
PermisoACCESS-ADMIN
CabecerasAuthorization, X-Request-Id
ParámetrosuserId = USR-000318, partnerId = `, from = 2026-09-18, to = 2026-10-18, kind = , page = 1, size = 50`

Request

null

Response · 200

{
  "success": true,
  "data": {
    "items": [
      {
        "at": "2026-10-17T22:10:05Z",
        "kind": "LOGIN_OK",
        "app": "PORTAL",
        "source": "PROVEEDOR_DE_IDENTIDAD"
      },
      {
        "at": "2026-10-17T22:31:40Z",
        "kind": "ACCESS_DENIED",
        "action": "FLU-ACCEPT",
        "resource": {
          "type": "PRODUCT",
          "id": "PRD-0004812"
        },
        "reason": "SIN_CAPACIDAD",
        "module": "MS-02",
        "requestId": "req-77ab10"
      },
      {
        "at": "2026-10-18T15:04:07Z",
        "kind": "MEMBERSHIP_CHANGED",
        "requestId": "req-3f90d1"
      }
    ],
    "page": 1,
    "size": 50,
    "total": 3
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERRORQuien pide no tiene ACCESS-ADMIN
POST /internal/audit/idp-logs · Bitácora del proveedor de identidad
CampoValor
APIAPI-05-005 · MS-05 Auditoría
Para quéRecibe de MS-13, cada minuto, los registros del proveedor de identidad (inicios y cierres de sesión, intentos fallidos, bloqueos) y los guarda una sola vez por su identificador. Así no se abre una cuarta puerta en la entrada.
En esta épicaGuardar la bitácora del proveedor de identidad
Quién la llamaMS-13 Identidad y acceso
PermisoSólo la cuenta de servicio de MS-13
CabecerasAuthorization, X-Request-Id, Idempotency-Key
Escribe enaudit_events

Request

{
  "batchId": "idplog-20261018-1503",
  "records": [
    {
      "logId": "lg-90020261018150301",
      "type": "LOGIN_OK",
      "subject": "idp|5f2c9a71e0",
      "at": "2026-10-18T15:03:01Z",
      "app": "PORTAL",
      "country": "MX"
    },
    {
      "logId": "lg-90020261018150322",
      "type": "LOGIN_FAILED",
      "subject": "idp|0c41de88b2",
      "at": "2026-10-18T15:03:22Z",
      "app": "PORTAL",
      "country": "MX"
    }
  ]
}

Response · 200

{
  "success": true,
  "data": {
    "batchId": "idplog-20261018-1503",
    "stored": 2,
    "duplicates": 0
  }
}

Errores

HTTPCódigoCuándo
403AUTHORIZATION_ERRORNo llama la cuenta de servicio de MS-13
409IDEMPOTENCY_MISMATCHEl mismo lote llega otra vez con contenido distinto

Las que usa y construye otra épica (3)

Su request y su response están en la página de la épica que la construye.

APIMétodo y rutaPara qué, aquíLa construye
API-02-001POST /api/v2/products/searchEjemplo de llamada a un módulo que revisa el tokenFT-PRD-01 · Modelo canónico de producto
API-11-004POST /api/v2/assets/uploadsEjemplo de llamada del agente del estudio con credencial de equipoFT-ACT-02 · Registro, congelado y publicación de URLs de activos
API-03-001POST /api/v2/migration/runsLanzar la corrida de usuarios de la migraciónFT-MIG-01 · Perfilado y limpieza previa

6. Eventos

Publica

EventoCuándoQuién lo consume
catalog.identity.changed/USER_CHANGEDAlta, bloqueo, baja o cambio de membresías, o la carga conciliada de MS-03 cambia el estado o las membresías de alguienFT-PRD-06, FT-USR-02

Consume

EventoPara quéQuién lo publica
catalog.identity.changed/USER_CHANGEDCada módulo y el BFF vacían la caché de roles de esa persona; MS-05 lo guarda en el historial de accesosesta misma épica

7. Datos

Cada colección tiene un solo dueño, el único que escribe en ella.

ColecciónDueñoQué guardaEsta épica
usersMS-13Cada usuario interno, proveedor o seller, su liga con el proveedor de identidad y sus roles.escribe
identity_outboxMS-13Los cambios de identidad que esperan salir como evento.escribe
identity_receiptsMS-13Los planes de identidad por confirmar (vencen a los 10 minutos) y el recibo de cada cambio confirmado de usuarios, roles y terceros, con lo que respondió el proveedor de identidad.escribe
audit_eventsMS-05Quién cambió qué, cuándo, desde dónde, con el antes y el después.escribe
rolesMS-13Perfiles y roles, con sus membresías y su alcance (negocio, sección, proveedor o seller, vigencia). Los permisos de dominio los decide el servicio dueño con estos roles (decisión 19).lee

8. Historias que cubre

HistoriaPrioridadCómo la cubre
FT-USR-01·H1 · Entrar al nuevo PIM con una sola identidadP1pasos 1, 2, 3, 4, 5, 6, 7, 8, 9; flujo «Del directorio de Entrada Única al directorio único (R1 a R2)», «Bloquear a un usuario y ver sus accesos»; API-13-002, API-13-017
FT-USR-01·H2 · Que cada servicio valide el token por sí mismoP1pasos 9, 10, 11; API-13-001
FT-USR-01·H3 · Que cada sistema se autentique con su propia credencial y sólo con los…P1flujo «Un equipo entra con su propia credencial»; API-13-004, API-13-001
FT-USR-01·H4 · Entrar con mi propia cuentaP2pasos 7, 8, 11; API-13-002, API-13-001
FT-USR-01·H6 · Usuarios, roles y perfiles dentro del PIMP1pasos 12, 13; flujo «Del directorio de Entrada Única al directorio único (R1 a R2)», «Bloquear a un usuario y ver sus accesos»; API-13-003, API-13-004, API-13-007, API-BFF-505, API-05-004

9. Decisiones de esta épica

Las tomó el TL como arquitecto; quedan como [Propuesta] hasta que el equipo de la épica las revise.

  • D-USR-01-1. Un solo proveedor de identidad y un solo directorio. El proveedor de identidad de Entrada Única autentica a personas y emite los tokens de máquina; MS-13 es el directorio único (usuarios, tipo, negocios, proveedor o seller, áreas, secciones, estado y roles) y es el único módulo que habla con la administración del proveedor. El inicio de sesión de Omega y los directorios de Foro no se heredan. Por qué: Dos directorios significan altas y bajas que no se propagan; Entrada Única ya usa ese proveedor y ADR-12 da a la identidad un módulo propio. Se apoya en PD-26, ADR-05, ADR-12, DMS-71, PD-08.
  • D-USR-01-2. La sesión vive en el BFF: inicia sesión con el proveedor (código con PKCE), guarda los tokens en una cookie cifrada HttpOnly, Secure y SameSite=Lax, sin base de datos; vence a los 30 minutos sin uso y a las 8 horas como máximo; toda escritura lleva cabecera contra falsificación de peticiones y CORS sólo existe en el BFF, con el origen del portal. Por qué: El navegador nunca ve el token y se conserva la regla de sesión de hoy; la decisión 19 deja la sesión y la validación en el BFF. Se apoya en PD-26, PD-30, ADR-05.
  • D-USR-01-4. Cada módulo guarda los roles efectivos (API-13-001) 5 minutos y los de un tercero 60 segundos; USER_CHANGED, ROLE_CHANGED y PARTNER_CHANGED los vacían. Si MS-13 no responde, se lee con la caché hasta 15 minutos, se rechazan escrituras con 503 y nadie entra por primera vez: falla cerrada. Por qué: ADR-05 pide caché y deja su vigencia a esta épica; un bloqueo debe valer en segundos y una caída del directorio no debe abrir permisos. Se apoya en ADR-05, PD-26.
  • D-USR-01-5. El directorio se construye en R1 y es la fuente desde R2. En R1, MS-03 concilia cada 15 minutos los usuarios de Entrada Única, Foro y P360 por su cuenta del proveedor de identidad, y el BFF toma el contexto de GET /users/auth de Entrada Única. En R2 las pantallas de usuarios pasan a MS-13, el BFF toma el contexto del directorio y la conciliación se apaga. Los 199 usuarios de P360 sin cuenta reciben una invitación; no se migran contraseñas. Por qué: Hacer fuente al directorio en R1 obligaría a cambiar los backends de Foro y Entrada Única para tirar ese código en R2; los dos ya guardan la cuenta del proveedor, que sirve de llave. Se apoya en PD-26, PD-30, DUD-08.
  • D-USR-01-6. Cada sistema entra con su credencial y un solo rol: los equipos del estudio son usuarios de tipo SYSTEM con el rol de subir fotos de su estación; los terceros van en el registro de terceros (FT-USR-03); entre módulos se usa la identidad de carga de trabajo del clúster. Ninguna credencial vive en código ni en git: se guardan en el gestor de secretos, se rotan, y la integración continua falla si encuentra una. Por qué: Foro acepta hoy cualquier petición y hay llaves de cuentas de servicio en git; corregir lo de hoy no basta si nada impide que vuelva a pasar. Se apoya en RSG-37, RSG-40, RSG-41, DUD-33.
  • D-USR-01-7. Un proveedor híbrido tiene en el directorio los dos negocios con su proveedor SAP y su seller; el negocio se elige en cada alta y el módulo lo valida contra los negocios del usuario. Por qué: El token no debe cargar negocios; el directorio ya los tiene y así un alta nunca cae en un negocio ajeno. Se apoya en PEN-55.
  • D-USR-01-8. MS-13 lee cada minuto la bitácora del proveedor de identidad (inicios y cierres de sesión, intentos fallidos) y la entrega a MS-05 (API-05-005); la entrada no abre una cuarta puerta para recibirla. Por qué: El historial de accesos es de MS-05 y la relación con el proveedor es de MS-13; leerla desde dentro no expone una ruta nueva a internet. Se apoya en ADR-05, ADR-12.
  • D-USR-01-9. Los límites de llamadas se ponen en la entrada, por puerta: el portal por usuario, el agente por equipo y los terceros por cliente, con sus cuotas en el gateway (FT-USR-03). Por qué: Así ningún usuario, equipo o tercero puede saturar a los demás, y cada puerta tiene su propio ritmo. Se apoya en PD-26, RN-GEN-08.

Qué falta decidir

IDQué falta
PD-26Arquitectura con Seguridad ratifica ADR-05 el 30-oct, incluida la cuota del proveedor de identidad para tokens de máquina.
DUD-33Seguridad con los equipos de la entrada de hoy, Entrada Única y Foro: inventario de credenciales, rotación de las expuestas y cierre de la Contingencia de P360 en R0.
DUD-08Confirmar con Arquitectura que no queda ninguna ruta de red hacia los módulos fuera de las tres puertas.
DUD-09No hay ERF de usuarios: falta responsable y fecha para escribirla.

También siguen abiertos: PEN-55, Negocio confirma cómo elige su negocio el proveedor híbrido en cada alta (aquí se elige en el alta).

Fuentes

  1. [D] trazabilidad/features/FT-USR-01-identidad-y-autenticacion.md: la ficha de la épica, con sus historias, reglas y bloqueos.
  2. [D] ADR-12 · Un solo sistema: backend compartido y una sola base (sección 3.4).
  3. [D] docs/arquitectura/por-epica/base/: piezas, colecciones, eventos y el hilo de punta a punta.
  4. [D] docs/arquitectura/omega-a-pim-headless/contratos-api.md: convenciones y endpoints de partida.
  5. [D] docs/arquitectura/maquina-de-estados-to-be/propuesta-maquina-de-estados.md §7: estados, tareas y canales.
  6. [I] Las decisiones de la sección 9 son del TL sobre esas fuentes.