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
| De | Qué |
|---|---|
| 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 PIM | La corrida de usuarios de MS-03 que concilia P360, Entrada Única y Foro por la cuenta del proveedor de identidad. |
Entrega
| A | Qué |
|---|---|
| PE-T · Usuario con permisos y bitácora | Quien 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 terceros | El 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 headless | Cada llamada a la API de producto llega autenticada y con los roles efectivos de quien llama. |
| FT-PRD-09 · Contrato de propuestas con Entrada Única | La 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
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.
Los pasos en texto
| Paso | De | A | Qué hace | API o evento |
|---|---|---|---|---|
| 1 | Compras | Entrada Única · Vendor Center | Abre el portal de catalogación | — |
| 2 | Entrada Única · Vendor Center | Entrada del clúster | Entra por la puerta del portal, con límite por usuario | — |
| 3 | Entrada del clúster | BFF del portal | Pide iniciar sesión | API-BFF-501 |
| 4 | BFF del portal | Proveedor de identidad | Lo manda a identificarse con su cuenta | — |
| 5 | Proveedor de identidad | BFF del portal | Regresa con un código de un solo uso | API-BFF-502 |
| 6 | BFF del portal | Proveedor de identidad | Cambia el código por el token y revisa su firma | — |
| 7 | BFF del portal | MS-13 Identidad y acceso | Pregunta quién es y qué pantallas le tocan | API-13-002 |
| 8 | MS-13 Identidad y acceso | Base pim | Revisa el token otra vez y que esté activo | — |
| 9 | Entrada Única · Vendor Center | BFF del portal | Pide la sesión y el menú de su perfil | API-BFF-503 |
| 10 | Entrada Única · Vendor Center | MS-02 Producto (por el BFF) | Busca productos; el BFF reenvía el token | API-02-001 |
| 11 | MS-02 Producto | MS-13 Identidad y acceso | Revisa el token y pide sus roles, con caché | API-13-001 |
| 12 | MS-13 Identidad y acceso | Proveedor de identidad | Lee cada minuto los inicios de sesión | — |
| 13 | MS-13 Identidad y acceso | MS-05 Auditoría | Entrega los accesos a la bitácora | API-05-005 |
3.1 Un equipo entra con su propia credencial
3.2 Del directorio de Entrada Única al directorio único (R1 a R2)
3.3 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
| Campo | Valor |
|---|---|
| API | API-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 épica | Empezar el inicio de sesión con el proveedor de identidad |
| Quién la llama | Entrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF) |
| Permiso | Cualquiera, todavía sin sesión |
| Cabeceras | X-Request-Id |
| Parámetros | returnTo = /catalogacion/propuestas |
Request
null
Response · 302
null
Errores
| HTTP | Código | Cuándo |
|---|---|---|
| 400 | VALIDATION_ERROR | returnTo no es una ruta del portal |
| 429 | RATE_LIMITED | La entrada frenó demasiados intentos desde el mismo origen |
GET /bff/v1/session/callback · Regreso del proveedor de identidad
| Campo | Valor |
|---|---|
| API | API-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 épica | Recibir el código, revisar el token y dejar la sesión cifrada |
| Quién la llama | Entrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF) |
| Permiso | Quien regresa del proveedor de identidad con un código válido |
| Cabeceras | X-Request-Id |
| Parámetros | code = (código de un solo uso), state = st-91c2 |
Request
null
Response · 302
null
Errores
| HTTP | Código | Cuándo |
|---|---|---|
| 401 | AUTHORIZATION_ERROR | El código venció, ya se usó o el state no coincide |
| 403 | AUTHORIZATION_ERROR | El usuario no está activo en el directorio |
| 503 | DEPENDENCY_UNAVAILABLE | El proveedor de identidad o el directorio no responden |
GET /bff/v1/session · Sesión y menú
| Campo | Valor |
|---|---|
| API | API-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 épica | La sesión y el menú según las pantallas de sus roles |
| Quién la llama | Entrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF) |
| Permiso | Cualquier usuario con sesión |
| Cabeceras | X-Request-Id |
| También la usan | FT-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
| HTTP | Código | Cuándo |
|---|---|---|
| 401 | AUTHORIZATION_ERROR | No hay sesión o ya venció |
POST /bff/v1/session/logout · Cerrar sesión
| Campo | Valor |
|---|---|
| API | API-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 épica | Cerrar la sesión y revocar la renovación |
| Quién la llama | Entrada Única · Vendor Center (por el BFF), Foro · portal del estudio (por el BFF) |
| Permiso | Cualquier usuario con sesión |
| Cabeceras | X-Request-Id, X-CSRF-Token |
Request
{}
Response · 200
{
"success": true,
"data": {
"loggedOut": true
}
}
Errores
| HTTP | Código | Cuándo |
|---|---|---|
| 403 | AUTHORIZATION_ERROR | Falta la cabecera contra falsificación de peticiones |
GET /bff/v1/access-admin/users/{userId} · Ficha de un usuario con sus accesos
| Campo | Valor |
|---|---|
| API | API-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 épica | La ficha de un usuario con su historial de accesos |
| Quién la llama | Entrada Única · Vendor Center (por el BFF) |
| Permiso | ACCESS-ADMIN (permiso de pantalla; cada módulo vuelve a revisar el suyo) |
| Cabeceras | X-Request-Id |
| Parámetros | userId = 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
| HTTP | Código | Cuándo |
|---|---|---|
| 403 | AUTHORIZATION_ERROR | El perfil no tiene la pantalla de administración de accesos |
| 404 | NOT_FOUND | El usuario no existe |
GET /internal/identity/permissions?userId= · Roles efectivos de quien llama
| Campo | Valor |
|---|---|
| API | API-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 épica | Los roles efectivos de quien llama, que cada módulo guarda 5 minutos |
| Quién la llama | MS-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 |
| Permiso | Sólo las cuentas de servicio de los módulos del PIM |
| Cabeceras | Authorization, X-Request-Id |
| Parámetros | userId = idp/5f2c9a71e0 |
| También la usan | FT-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
| HTTP | Código | Cuándo |
|---|---|---|
| 404 | NOT_FOUND | El sujeto no está en el directorio; el módulo responde 401 a quien llamó |
| 403 | AUTHORIZATION_ERROR | El usuario está bloqueado, dado de baja o fuera de vigencia; el módulo responde 401 |
| 503 | DEPENDENCY_UNAVAILABLE | El directorio no responde; el módulo lee con su caché hasta 15 minutos y rechaza escrituras |
GET /api/v2/me · Quién soy
| Campo | Valor |
|---|---|
| API | API-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 épica | Quién es el usuario de la sesión y qué pantallas le tocan |
| Quién la llama | BFF del portal |
| Permiso | Cualquier usuario con sesión válida, sobre su propio registro |
| Cabeceras | Authorization, 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
| HTTP | Código | Cuándo |
|---|---|---|
| 401 | AUTHORIZATION_ERROR | El token venció, no es válido o el usuario no está activo |
GET /api/v2/users · Buscar usuarios
| Campo | Valor |
|---|---|
| API | API-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 épica | Buscar usuarios en la administración de accesos |
| Quién la llama | BFF del portal |
| Permiso | ACCESS-ADMIN |
| Cabeceras | Authorization, X-Request-Id |
| Parámetros | type = 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
| HTTP | Código | Cuándo |
|---|---|---|
| 403 | AUTHORIZATION_ERROR | Quien pide no tiene ACCESS-ADMIN |
| 400 | VALIDATION_ERROR | Un filtro trae un valor que no existe |
POST /api/v2/users/plans · Preparar un cambio de usuario
| Campo | Valor |
|---|---|
| API | API-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 épica | Invitar, bloquear, dar de baja, cambiar membresías o registrar un equipo |
| Quién la llama | BFF del portal |
| Permiso | ACCESS-ADMIN |
| Cabeceras | Authorization, X-Request-Id, Idempotency-Key |
| También la usan | FT-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
| HTTP | Código | Cuándo |
|---|---|---|
| 422 | VALIDATION_ERROR | El rol o la sección no existen, o la vigencia termina antes de empezar |
| 409 | VERSION_CONFLICT | El usuario cambió desde que se leyó |
| 403 | AUTHORIZATION_ERROR | Quien pide no tiene ACCESS-ADMIN |
POST /api/v2/identity-plans/{planId}/apply · Confirmar un plan de identidad
| Campo | Valor |
|---|---|
| API | API-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 épica | Confirmar cualquier plan de identidad |
| Quién la llama | BFF del portal |
| Permiso | El mismo que pidió el plan |
| Cabeceras | Authorization, X-Request-Id, Idempotency-Key |
| Parámetros | planId = pln-a41c07 |
| Escribe en | users, roles, partners, identity_outbox |
| Publica | catalog.identity.changed/USER_CHANGED, catalog.identity.changed/ROLE_CHANGED, catalog.identity.changed/PARTNER_CHANGED |
| También la usan | FT-USR-02, FT-USR-03 |
Request
{}
Response · 202
{
"success": true,
"data": {
"requestId": "req-3f90d1",
"status": "ACCEPTED",
"receiptUrl": "/api/v2/identity-receipts/req-3f90d1"
}
}
Errores
| HTTP | Código | Cuándo |
|---|---|---|
| 409 | PLAN_EXPIRED | Pasaron más de 10 minutos desde la vista previa |
| 409 | VERSION_CONFLICT | El usuario, el rol o el tercero cambió después de la vista previa |
| 409 | IDEMPOTENCY_MISMATCH | Se repite la llave de idempotencia con otro plan |
GET /api/v2/identity-receipts/{requestId} · Recibo de identidad
| Campo | Valor |
|---|---|
| API | API-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 épica | Ver el recibo de un cambio de identidad |
| Quién la llama | BFF del portal |
| Permiso | Quien hizo la operación, o ACCESS-ADMIN |
| Cabeceras | Authorization, X-Request-Id |
| Parámetros | requestId = 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
| HTTP | Código | Cuándo |
|---|---|---|
| 404 | NOT_FOUND | No existe el recibo o no es de quien llama |
POST /internal/identity/bulk-load/users · Carga conciliada del directorio
| Campo | Valor |
|---|---|
| API | API-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 épica | Cargar el directorio conciliado de P360, Entrada Única y Foro |
| Quién la llama | MS-03 Migración y convivencia |
| Permiso | Sólo la cuenta de servicio de MS-03 (MIG-ADMIN) |
| Cabeceras | Authorization, X-Request-Id, Idempotency-Key |
| Escribe en | users, identity_outbox |
| Publica | catalog.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
| HTTP | Código | Cuándo |
|---|---|---|
| 409 | IDEMPOTENCY_MISMATCH | El mismo lote llega otra vez con contenido distinto |
| 422 | VALIDATION_ERROR | Un 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
| Campo | Valor |
|---|---|
| API | API-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 épica | Nombres visibles de personas, áreas y proveedores para bandejas e historias |
| Quién la llama | BFF del portal |
| Permiso | Cualquier usuario con sesión |
| Cabeceras | Authorization, X-Request-Id |
| Parámetros | userIds = USR-000231,USR-000318, areaIds = COMPRAS-HOGAR,LOGISTICA, partnerIds = PROV-0001,SELLER-0001 |
| También la usan | FT-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
| HTTP | Código | Cuándo |
|---|---|---|
| 400 | VALIDATION_ERROR | Pide más de 200 identificadores en una llamada |
GET /api/v2/audit/access · Historial de accesos
| Campo | Valor |
|---|---|
| API | API-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 épica | Historial de accesos de un usuario o de un tercero |
| Quién la llama | BFF del portal |
| Permiso | ACCESS-ADMIN |
| Cabeceras | Authorization, X-Request-Id |
| Parámetros | userId = 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
| HTTP | Código | Cuándo |
|---|---|---|
| 403 | AUTHORIZATION_ERROR | Quien pide no tiene ACCESS-ADMIN |
POST /internal/audit/idp-logs · Bitácora del proveedor de identidad
| Campo | Valor |
|---|---|
| API | API-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 épica | Guardar la bitácora del proveedor de identidad |
| Quién la llama | MS-13 Identidad y acceso |
| Permiso | Sólo la cuenta de servicio de MS-13 |
| Cabeceras | Authorization, X-Request-Id, Idempotency-Key |
| Escribe en | audit_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
| HTTP | Código | Cuándo |
|---|---|---|
| 403 | AUTHORIZATION_ERROR | No llama la cuenta de servicio de MS-13 |
| 409 | IDEMPOTENCY_MISMATCH | El 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.
| API | Método y ruta | Para qué, aquí | La construye |
|---|---|---|---|
| API-02-001 | POST /api/v2/products/search | Ejemplo de llamada a un módulo que revisa el token | FT-PRD-01 · Modelo canónico de producto |
| API-11-004 | POST /api/v2/assets/uploads | Ejemplo de llamada del agente del estudio con credencial de equipo | FT-ACT-02 · Registro, congelado y publicación de URLs de activos |
| API-03-001 | POST /api/v2/migration/runs | Lanzar la corrida de usuarios de la migración | FT-MIG-01 · Perfilado y limpieza previa |
6. Eventos
Publica
| Evento | Cuándo | Quién lo consume |
|---|---|---|
catalog.identity.changed/USER_CHANGED | Alta, bloqueo, baja o cambio de membresías, o la carga conciliada de MS-03 cambia el estado o las membresías de alguien | FT-PRD-06, FT-USR-02 |
Consume
| Evento | Para qué | Quién lo publica |
|---|---|---|
catalog.identity.changed/USER_CHANGED | Cada módulo y el BFF vacían la caché de roles de esa persona; MS-05 lo guarda en el historial de accesos | esta misma épica |
7. Datos
Cada colección tiene un solo dueño, el único que escribe en ella.
| Colección | Dueño | Qué guarda | Esta épica |
|---|---|---|---|
users | MS-13 | Cada usuario interno, proveedor o seller, su liga con el proveedor de identidad y sus roles. | escribe |
identity_outbox | MS-13 | Los cambios de identidad que esperan salir como evento. | escribe |
identity_receipts | MS-13 | Los 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_events | MS-05 | Quién cambió qué, cuándo, desde dónde, con el antes y el después. | escribe |
roles | MS-13 | Perfiles 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
| Historia | Prioridad | Cómo la cubre |
|---|---|---|
| FT-USR-01·H1 · Entrar al nuevo PIM con una sola identidad | P1 | pasos 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í mismo | P1 | pasos 9, 10, 11; API-13-001 |
| FT-USR-01·H3 · Que cada sistema se autentique con su propia credencial y sólo con los… | P1 | flujo «Un equipo entra con su propia credencial»; API-13-004, API-13-001 |
| FT-USR-01·H4 · Entrar con mi propia cuenta | P2 | pasos 7, 8, 11; API-13-002, API-13-001 |
| FT-USR-01·H6 · Usuarios, roles y perfiles dentro del PIM | P1 | pasos 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
| ID | Qué falta |
|---|---|
| PD-26 | Arquitectura con Seguridad ratifica ADR-05 el 30-oct, incluida la cuota del proveedor de identidad para tokens de máquina. |
| DUD-33 | Seguridad 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-08 | Confirmar con Arquitectura que no queda ninguna ruta de red hacia los módulos fuera de las tres puertas. |
| DUD-09 | No 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
- [D]
trazabilidad/features/FT-USR-01-identidad-y-autenticacion.md: la ficha de la épica, con sus historias, reglas y bloqueos. - [D] ADR-12 · Un solo sistema: backend compartido y una sola base (sección 3.4).
- [D]
docs/arquitectura/por-epica/base/: piezas, colecciones, eventos y el hilo de punta a punta. - [D]
docs/arquitectura/omega-a-pim-headless/contratos-api.md: convenciones y endpoints de partida. - [D]
docs/arquitectura/maquina-de-estados-to-be/propuesta-maquina-de-estados.md§7: estados, tareas y canales. - [I] Las decisiones de la sección 9 son del TL sobre esas fuentes.