> ## Documentation Index
> Fetch the complete documentation index at: https://internal.softcrum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Impersonación de soporte

> Cuando esto se entregue, un operador podrá ver exactamente lo que ve un cliente atascado — y ese cliente podrá ver que ocurrió, cuándo y por qué.

> Traducción. Autoritativo: [`fs-idn-0009-impersonation.md`](/modules/identity/features/fs-idn-0009-impersonation).

## Contexto

El soporte no puede depurar lo que no puede ver. Las capturas de pantalla y las sesiones compartidas
son lentas y muchas veces imposibles, así que toda plataforma B2B seria termina con alguna forma de
impersonación. La pregunta nunca es si, sino si rinde cuentas.

Hecho a la ligera —un flag de superusuario, sin registro— es una lectura indetectable de los datos de
todos los clientes por cualquiera con cuenta interna. Eso es una brecha esperando a un empleado
molesto, y bajo la Ley 21.719 es exactamente el tipo de acceso por el que pregunta una auditoría.

El diseño lo convierte de pasivo en señal de confianza haciéndolo **imposible sin razón y sin ventana
de tiempo, y visible para el tenant en su propio rastro de auditoría**. El tenant es quien tiene el
incentivo de notar una sesión inexplicada, así que es quien puede verla.

Va deliberadamente última en el módulo: no debería existir antes que el rastro de auditoría que la
limita.

## Alcance *(normativo)*

* `identity.impersonations`, append-only, con operador, objetivo, razón y ventana de tiempo.
* Una sesión que es explícitamente una impersonación, nunca indistinguible de una real.
* Banner visual permanente en la consola durante toda la duración.
* Expiración automática y término manual.
* Visibilidad completa en el propio rastro de auditoría del tenant.
* Conjunto de acciones restringido: solo lectura por defecto.

## Fuera de alcance *(normativo)*

* Impersonación entre tenants. Nunca, bajo ninguna configuración.
* Suplantar la identidad de un usuario específico. El operador actúa **como operador acotado a la
  organización**, no como esa persona — atribuir acciones de un operador a un empleado del cliente es
  falsificar un rastro de auditoría.
* Acceso silencioso o invisible. No existe configuración que lo oculte.

## Comportamiento *(normativo)*

1. Iniciar una impersonación exige el permiso `identity.impersonation.start` —solo Ops— **más
   reautenticación, más una razón de texto libre de al menos 20 caracteres**. El mínimo existe porque
   "depurando" no es una razón.
2. Toda impersonación está **acotada en el tiempo**, 60 minutos por defecto, máximo duro de 4 horas.
   Expira sola; no hay extender, solo una nueva con una razón nueva.
3. La sesión está marcada como impersonación y toda acción bajo ella se atribuye al **operador**,
   nunca a un usuario del tenant. El actor de auditoría es el operador, con el id de impersonación.
4. **Solo lectura por defecto.** Las escrituras exigen un permiso aparte
   `identity.impersonation.write` y quedan auditadas individualmente con visibilidad reforzada. La
   mayoría de los problemas de soporte se diagnostican mirando.
5. Cierta información **nunca es visible bajo impersonación**: documentos de identidad completos,
   secretos de API keys, secretos de MFA y códigos de recuperación. Un operador que ve la pantalla de
   un cliente no necesita los documentos de identidad de los clientes de ese cliente.
6. La consola muestra un **banner permanente e imposible de ignorar** durante toda la sesión, con la
   organización y el tiempo restante.
7. El tenant ve toda impersonación en **su propio rastro de auditoría**, con operador, razón, duración
   y acciones. No se filtra jamás.
8. Iniciar una notifica por correo a los owners de la organización. Que un tenant se entere solo si
   va a buscar no es transparencia.
9. `identity.impersonations` es **append-only**. Un registro no lo puede editar ni borrar nadie,
   incluido Ops.
10. Una impersonación nunca alcanza otra organización, ni el realm de member.

## Datos *(normativo)*

| Tabla                     | Invariantes clave                                                                                                                                                                                                        |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `identity.impersonations` | append-only; `operator_user_id`, `organization_id`; `reason` NOT NULL con largo mínimo; `started_at`, `expires_at`, `ended_at`; `is_write_enabled`; `actions_count`; nunca se actualiza salvo `ended_at`, nunca se borra |

## API *(normativo)*

| Endpoint                                    | Clase      | Permiso                                          | Presupuesto  |
| ------------------------------------------- | ---------- | ------------------------------------------------ | ------------ |
| `POST /v1/identity/impersonations`          | Management | `identity.impersonation.start`, reauth           | p95 \<1 s    |
| `POST /v1/identity/impersonations/{id}/end` | Management | operador o owner del tenant                      | p95 \<300 ms |
| `GET /v1/identity/impersonations`           | Management | `identity.impersonation.read` u owner del tenant | p95 \<1 s    |

Un **owner del tenant puede terminar una impersonación de su propia organización**. Si no está cómodo
con lo que ve ocurrir, puede detenerlo.

## Eventos *(normativo)*

`identity.impersonation.started` y `identity.impersonation.ended`. El evento `started` dispara una
notificación inmediata a los owners por `messaging`.

## Criterios de aceptación *(normativo)*

1. Iniciar sin razón, con una razón bajo 20 caracteres, o sin reautenticación se rechaza en cada caso.
2. Una impersonación expira automáticamente en su ventana; los requests posteriores se rechazan.
3. Más allá del máximo de 4 horas, la creación se rechaza.
4. Toda acción bajo impersonación se audita con el operador como actor y el id de impersonación
   adjunto — nunca con un usuario del tenant como actor.
5. Un intento de escritura sin `identity.impersonation.write` se rechaza.
6. Documentos completos, secretos de keys y secretos de MFA son ilegibles bajo impersonación,
   cualesquiera sean los roles del operador.
7. El rastro de auditoría del tenant muestra la impersonación con razón y duración.
8. Los owners reciben notificación en segundos desde el inicio.
9. Un owner del tenant puede terminar una impersonación de su organización.
10. **Negativo:** ninguna configuración, flag ni endpoint oculta una impersonación al tenant, y
    ningún registro se puede editar ni borrar.

## Ejecución

Un solo slice, comando síncrono. F1b, y última del módulo por diseño. El banner es asunto de
`frontend/console` guiado por el flag de sesión; las notificaciones van por `messaging`.

## Preguntas abiertas

| # | Pregunta                                                                                                     | Decide | Para             |
| - | ------------------------------------------------------------------------------------------------------------ | ------ | ---------------- |
| 1 | ¿Un tenant puede desactivar la impersonación por completo para su organización, aceptando soporte más lento? | Daniel | antes de aprobar |
| 2 | Ventana por defecto — ¿60 minutos, o 30 con renovación fácil?                                                | Daniel | antes de aprobar |

## Changelog

| Versión | Fecha      | Cambio           | Por qué | Autor                  |
| ------- | ---------- | ---------------- | ------- | ---------------------- |
| 0.1.0   | 2026-08-17 | Borrador inicial | —       | daniel + claude-opus-5 |

## Registro de entrega

*Aún no implementado.*
