# Propiedad de sesiones de agentes en tmux: aprobaciones y auditorías

Los multiplexores de terminal resuelven un problema operativo real: mantienen el trabajo activo aunque se interrumpa una conexión SSH, el portátil entre en reposo o se cierre por error una ventana de terminal. Esa misma persistencia puede ocultar quién controla un agente de IA, si su aprobación sigue siendo válida y qué proceso envió realmente una solicitud autenticada.

El error consiste en tratar una ventana de tmux como una sesión de seguridad. No lo es. tmux es un gestor de procesos para sesiones de terminal. Su servidor puede seguir activo después del cliente de terminal, y sus paneles pueden sobrevivir a la persona que los creó. GNU screen tiene la misma propiedad básica. Si tu modelo de aprobación, tus notas de incidentes o tu proceso de auditoría usan la expresión «la sesión de tmux» como si identificara a un único actor y una única ejecución del agente, ya has complicado la investigación más de lo necesario.

Esto importa especialmente cuando un agente puede acceder a APIs o servidores SSH a través de una pasarela controlada por una persona. Alguien puede iniciar un agente en un panel, desconectarse, compartir el nombre de la sesión con un compañero, volver a conectarse desde otra máquina y después iniciar un segundo agente en el mismo panel. Para el operador, cada evento parece una continuación. En la tabla de procesos son hechos distintos.

## Una sesión de tmux no es una ejecución del agente

Una sesión de tmux es un conjunto con nombre de ventanas y paneles que mantiene un servidor de tmux de larga duración. Una ejecución del agente es un proceso y los procesos secundarios que crea, delimitados por su inicio y su finalización. Son objetos diferentes. Confundirlos produce ámbitos de aprobación demasiado amplios o imposibles de explicar después.

Cuando ejecutas `tmux new-session -s build`, tmux inicia un servidor o se conecta a uno existente. El servidor crea una pseudo-terminal para el panel inicial y lanza un shell. Cuando ese shell inicia un agente, el agente se convierte en descendiente del shell. Desconectarse elimina la conexión del cliente con tmux. Normalmente no termina el servidor, el shell ni el agente.

Una secuencia habitual parece inofensiva:

1. Maya inicia `tmux new -s release` y lanza un agente en el panel 0.
2. Maya se desconecta para asistir a una reunión mientras el agente sigue trabajando.
3. Más tarde, su compañero se conecta a `release`, lee la salida del panel y lanza un comando de seguimiento.
4. Esa noche, Maya reutiliza el panel 0 para otro proceso de agente.

El nombre de la sesión siguió siendo `release`. Las entidades relevantes para la seguridad no. Hubo al menos dos procesos de agente, dos interacciones humanas y posiblemente eventos de autorización distintos. El historial de la terminal no puede convertir todo eso en una sola identidad coherente.

GNU screen se comporta de forma parecida. Un servidor de screen separado administra ventanas de terminal y procesos secundarios. Los comandos exactos cambian, pero la conclusión de seguridad no: el estado de conexión describe el acceso a un multiplexor de terminal, no la propiedad de cada proceso que contiene.

El manual de tmux describe un modelo cliente-servidor y explica que el servidor administra sesiones, ventanas y paneles. No es solo un detalle de implementación. Indica dónde reside la continuidad: en el servidor, no en la aplicación de terminal que una persona ve en ese momento. Basa la autorización en el proceso que solicita una acción, no en el contenedor del multiplexor que lo aloja.

## La ascendencia de procesos responde preguntas que los nombres de paneles no pueden responder

Un árbol de procesos puede mostrar cómo se inició un agente y qué shell y servidor de tmux fueron sus padres. El título de un panel solo muestra una etiqueta que alguien puede haber cambiado, copiado o dejado obsoleta.

En macOS o Linux, comienza la investigación con una vista reducida de los procesos mientras el proceso siga activo:

```sh
ps -axo pid,ppid,lstart,tty,stat,command | grep -E '[t]mux|[s]creen|[a]gent'
```

Importa más la forma de la salida que los nombres exactos de los comandos:

```text
 8421     1 Tue Mar 12 09:14:03 2025 ??       Ss   tmux new-session -s release
 8430  8421 Tue Mar 12 09:14:04 2025 ttys002  S    -zsh
 9917  8430 Tue Mar 12 10:02:51 2025 ttys002  S+   agent-tool run deploy check
```

El PID 9917 es el proceso de agente candidato. El PID 8430 es el shell que lo inició. El PID 8421 es el servidor de tmux. El valor de `tty` puede ayudar a relacionar un proceso con un panel mientras existe, pero no lo uses como identidad permanente. Las asignaciones de pseudo-terminales pueden desaparecer cuando termina un proceso y verse diferentes después de recrear la terminal.

En macOS, `pstree` no viene instalado de forma predeterminada. Este comando ofrece una vista útil de la relación entre padres e hijos sin añadir software:

```sh
ps -axo pid,ppid,user,lstart,command | sort -n
```

Para un PID concreto, inspecciona repetidamente su proceso padre hasta llegar al servidor de tmux o a un servicio de lanzamiento:

```sh
ps -p 9917 -o pid=,ppid=,user=,lstart=,tty=,command=
ps -p 8430 -o pid=,ppid=,user=,lstart=,tty=,command=
```

Registra estos valores antes de matar nada. Un operador que ejecuta primero `tmux kill-session` puede borrar las pruebas activas más útiles: líneas de comandos, relaciones entre padres e hijos y horas de inicio. Matar una sesión puede seguir siendo la medida de contención correcta, pero, si la situación lo permite, toma antes una instantánea breve.

La ascendencia de procesos tiene límites. Un proceso puede convertirse en demonio, crear procesos secundarios o cambiar deliberadamente de padre. Un agente también puede pedir a un asistente externo que haga el trabajo, creando un árbol que termina en ese asistente. Considera la ascendencia una prueba del contexto de inicio, no una demostración de la intención de una persona. Aún necesitas registros de acciones que identifiquen el proceso solicitante y la autorización que permitió la acción.

## La aprobación debe seguir al proceso del agente, no a la terminal conectada

La autorización por sesión debería aplicarse a una sola ejecución del proceso del agente y terminar cuando ese proceso finalice. Conectar o desconectar, enfocar un panel y reiniciar el emulador de terminal no deben conceder, renovar ni transferir silenciosamente esa aprobación.

La autorización por sesión de Sallyport sigue este principio: la primera llamada de un proceso de agente nuevo solicita aprobación, identifica el proceso mediante su autoridad de firma de código y conserva la aprobación solo durante esa ejecución. La aprobación no se convierte en una propiedad del nombre de una sesión de tmux ni del indicador del shell.

Este límite resuelve varios casos confusos. Si una persona se desconecta y vuelve a conectarse mientras el mismo proceso de agente continúa, el proceso no ha cambiado. Su autorización de sesión puede seguir siendo válida, sujeta al bloqueo del almacén y a cualquier credencial que requiera aprobación en cada llamada. Si el agente termina, un shell del panel inicia otro agente y el panel parece idéntico, el proceso nuevo debe recibir una nueva decisión de aprobación.

No intentes convertir la conexión a tmux en el evento de aprobación. La idea resulta atractiva porque una acción humana, `tmux attach`, parece una señal útil. Es la señal equivocada para el uso de credenciales. La conexión puede ocurrir después de que el agente haya comenzado, puede proceder de otra persona que use la misma cuenta local o puede servir únicamente para inspeccionar la salida. Además, un proceso puede seguir actuando aunque no haya ningún cliente de tmux conectado.

También aparece el error contrario en los equipos: tratar cada comando escrito en un panel conectado como si estuviera supervisado por una persona. Alguien puede conectarse, alejarse y dejar al agente trabajando. Una terminal visible no confirma la presencia de nadie.

Para las credenciales sensibles, la aprobación en cada uso tiene otro objetivo. No establece quién controla el proceso. Exige una decisión humana en el momento en que se solicita una acción concreta con una credencial. Mantén separadas estas ideas:

- El bloqueo del almacén decide si puede continuar alguna acción mientras los secretos siguen protegidos.
- La autorización por proceso decide si esta ejecución del agente puede realizar llamadas.
- La aprobación por credencial decide si un uso concreto de una credencial necesita una nueva decisión humana.

Estos controles responden preguntas distintas. Un equipo que usa una única aprobación amplia para una sesión de terminal de larga duración ha elegido la comodidad en lugar de un límite que pueda defenderse.

## Un panel reutilizado puede arrastrar confusión sobre la aprobación entre ejecuciones

El problema suele empezar con una sesión persistente llamada «work» que se ha convertido en un cajón compartido para comandos sin terminar. Alguien inicia un agente, se desconecta, vuelve horas después, lo detiene y lanza otro agente en el mismo shell. El panel aún contiene la transcripción anterior, las variables de entorno y el indicador del shell. Las personas deducen una continuidad que el sistema operativo no tiene.

Imagina un incidente en el que una API recibe una solicitud destructiva a las 16:43. El registro de actividad identifica un proceso de agente. El equipo abre tmux y encuentra un panel llamado `prod-fix`, cuya salida comienza a las 09:00. Supone que el ingeniero que creó `prod-fix` aprobó la solicitud. Esa conclusión puede ser falsa por varios motivos:

- El agente original pudo haber terminado a las 10:15 y otro proceso pudo haber comenzado a las 16:40.
- Un segundo ingeniero pudo haberse conectado y haber emitido el nuevo comando de inicio.
- El título del panel pudo heredarse de una tarea anterior.
- Un archivo de inicio del shell pudo haber exportado credenciales o un entorno de destino que ya no coincide con el trabajo actual.
- El proceso pudo haberse iniciado fuera de tmux y haber escrito la salida en el panel mediante otro mecanismo.

La pregunta correcta es más concreta: qué proceso ejecutable solicitó la acción a las 16:43, quién aprobó ese proceso y qué autoridad de firma de código mostró la interfaz de aprobación. Después, pregunta cómo entró ese proceso en el árbol de procesos de la máquina.

No reacciones prohibiendo tmux. Una sesión nueva y con un nombre específico puede mejorar el trabajo durante un incidente porque ofrece a los operadores un espacio visible y conserva la salida durante una conexión inestable. El riesgo aparece al reutilizar una sesión general como contenedor de ejecuciones de agentes sin relación entre sí.

Usa nombres que indiquen un propósito y un identificador breve de ejecución, como `deploy-4812` en lugar de `work` o `main`. El nombre ayuda a las personas, pero no es un dato de autorización. Retira la sesión cuando termine la ejecución.

## El trabajo desconectado necesita un responsable y una decisión de caducidad

Una sesión separada de tmux o screen solo puede ejecutarse de forma segura cuando alguien ha aceptado explícitamente que continuará sin una terminal conectada. «Pensé que se había detenido» no es un modelo de responsabilidad.

Antes de desconectar un agente que puede realizar acciones autenticadas, anota cuatro datos en el ticket, la nota del incidente o el registro de entrega: el PID del proceso del agente, el nombre de la sesión de tmux, la tarea declarada y la persona responsable de detenerlo. Añade una hora en la que alguien deba revisar si debe continuar. Es un trabajo sencillo y evita más problemas que los elaborados esquemas para nombrar paneles.

Un patrón de inicio útil crea un espacio de nombres de socket nuevo para cada ejecución en lugar de añadir otra ventana a un servidor personal permanente:

```sh
tmux -L agent-4812 new-session -d -s agent-4812 \\
  'exec agent-tool run "verify deployment 4812"'

tmux -L agent-4812 display-message -p \\
  '#{session_name} #{session_created} #{pane_pid} #{pane_tty}'
```

El primer comando inicia una sesión separada. `exec` importa porque reemplaza el proceso del shell por el comando del agente, por lo que el PID del panel se convierte en un punto de partida más directo para la investigación. Sin `exec`, el panel pertenece inicialmente a un shell que después crea el agente como proceso secundario. Sigue siendo gestionable, pero añade una capa más que inspeccionar.

El segundo comando muestra metadatos con una salida parecida a esta:

```text
agent-4812 1731000000 9917 /dev/ttys002
```

Guarda esa salida donde se haga el seguimiento de la tarea. Más tarde, el proceso puede crear procesos secundarios o terminar, por lo que esto no es un registro de auditoría completo. Sí proporciona un punto de referencia inicial cuando hay que comparar los datos de procesos con los registros de acciones.

Cuando termine la tarea, finaliza deliberadamente el socket con nombre:

```sh
tmux -L agent-4812 kill-session -t agent-4812
```

Después, comprueba que el PID esperado del agente haya terminado. No supongas que `kill-session` ha eliminado todos los procesos descendientes. Los programas que crean sus propias sesiones o asistentes en segundo plano pueden sobrevivir a su pseudo-terminal original. Vuelve a inspeccionar la lista de procesos y usa la pasarela de acciones para revocar la ejecución activa del agente si sus registros indican que sigue autorizada.

## Screen tiene la misma trampa de identidad, con menos pistas

GNU screen crea una sesión separada que puede reanudarse más tarde, y sus conocidos identificadores numéricos pueden parecer más precisos de lo que son. Identifican una instancia del servidor de screen, no un proceso concreto del agente ni una aprobación humana.

El manual de GNU screen documenta las sesiones separadas y comandos como `screen -ls` y `screen -r`. Esos comandos responden si hay un servidor de screen disponible para conectarse. No indican si el proceso de una ventana es el mismo que se ejecutó antes ni si el operador actual es la persona que tomó la decisión de autorización anterior.

Comienza con estas comprobaciones cuando screen intervenga en un incidente:

```sh
screen -ls
ps -axo pid,ppid,lstart,tty,stat,command | grep -E '[s]creen|[a]gent'
```

Un resultado como `12345.build (Detached)` identifica una sesión de screen que merece ser examinada. Compárala con las horas de inicio y las terminales antes de conectarte. La conexión puede cambiar lo que ve un usuario, activar funciones del shell o hacer que un programa interactivo continúe. En un incidente sensible, conserva primero las pruebas y deja que la persona designada decida si es necesaria la interacción.

El modo multiusuario de screen requiere especial cautela. Puede conceder a otros usuarios locales acceso a una sesión de terminal compartida. Puede ser adecuado en una máquina controlada, pero debilita cualquier afirmación informal de que «la persona que se conectó» controla los procesos. La autorización debe seguir identificando el proceso de agente solicitante y exigir una decisión de la persona local que controla la pasarela de credenciales.

## Los registros de auditoría necesitan un punto de unión fuera de tmux

Una investigación defendible relaciona tres registros: el registro de procesos del sistema operativo, el registro de autorización y el registro de cada acción. La salida de tmux o screen puede complementar esas pruebas, pero no sustituir ninguna de ellas.

Para cada acción de credenciales que se investigue, establece esta secuencia:

1. Identifica en el registro de actividad la hora, el destino, el método y el resultado de la acción.
2. Identifica la ejecución del agente que la solicitó y la decisión de autorización asociada.
3. Compara los detalles y la hora de inicio del proceso de la ejecución con el árbol de procesos activo o capturado.
4. Usa los metadatos de la sesión de tmux o screen únicamente para reconstruir el espacio de trabajo y los relevos del operador.
5. Verifica que el registro de auditoría no haya cambiado desde su captura.

La diferencia entre un diario de acciones y el historial de desplazamiento de una terminal es clara. El historial puede omitir salida, rotarse, contener texto pegado desde otro proceso o ser alterado por un usuario con acceso a la sesión. Un diario de acciones debe indicar la operación intentada y su resultado. Si ofrece evidencias de manipulación, los investigadores pueden comprobar que el conjunto de registros se ha mantenido intacto sin confiar en la terminal que lo mostró.

Sallyport registra las ejecuciones de los agentes y las llamadas individuales en un registro de auditoría cifrado y encadenado mediante hashes. `sp audit verify` puede verificar esa cadena sin conexión y sin una clave del almacén. Esa verificación demuestra la integridad de la secuencia registrada, no que un título de tmux identifique correctamente a la persona que escribió un comando. Mantén separadas esas afirmaciones en los informes de incidentes.

Una nota de incidente útil evita frases como «la sesión de tmux de release lo hizo». Escribe: «A las 16:43, la ejecución del agente [identificador] solicitó [acción]. La solicitud procedía del proceso [identificador], iniciado a las [hora]. En el momento de la captura, el proceso era descendiente de [shell o servicio] y estaba asociado al servidor de tmux [PID]. [Persona] aprobó la ejecución después de revisar la autoridad de proceso mostrada». Incluye solo hechos que puedas respaldar.

Esa redacción también deja al descubierto las carencias. Si nadie capturó la cadena de padres antes de la contención, dilo. Si el sistema no conserva la identidad de proceso necesaria, no rellenes el vacío con el nombre de un panel.

## La identidad de firma de código y la identidad de la cuenta local resuelven problemas distintos

Una cuenta local de macOS identifica a un usuario del sistema operativo. La autoridad de firma de código identifica quién firmó un ejecutable. Una sesión de tmux identifica un servidor de terminal. Ninguno de estos identificadores significa lo mismo y cada uno detecta un fallo diferente.

La identidad de la cuenta local ayuda a responder qué cuenta era propietaria del proceso. No indica si un binario procede del editor esperado ni si otra persona utilizó una cuenta desbloqueada. La autoridad de firma de código ayuda a reconocer el ejecutable que solicita acceso. No indica si el proceso se inició en el panel de tmux correcto ni si la tarea era apropiada.

Por eso resulta útil que una tarjeta de aprobación muestre primero la autoridad de firma de código cuando un proceso nuevo del agente solicita actuar. Ofrece a quien aprueba una señal estable que sobrevive a los paneles renombrados, las configuraciones de tmux copiadas y el reinicio del emulador de terminal. También hace visibles los ejecutables inesperados, sin firma o con una firma diferente en el momento importante.

No reduzcas esto a la regla ciega «el mismo firmante equivale a seguridad». Un firmante de confianza puede distribuir una versión defectuosa, un envoltorio local puede invocar un binario aprobado en un contexto inseguro y un proceso firmado puede recibir instrucciones peligrosas. La identidad del proceso acota el objetivo de la aprobación. La aprobación por llamada para determinadas credenciales y un registro completo de acciones gestionan riesgos que la identidad por sí sola no puede resolver.

Para investigaciones en macOS, puedes inspeccionar la información de firma de un binario con `codesign`:

```sh
codesign -dv --verbose=4 "$(command -v agent-tool)" 2>&1 | \\
  grep -E 'Identifier=|TeamIdentifier=|Authority='
```

La salida normalmente incluye líneas como `Identifier=`, `TeamIdentifier=` y una o más entradas `Authority=`. Captúrala cuando necesites explicar por qué una interfaz de aprobación reconoció un proceso. No sustituyas las pruebas del firmante por una ruta como `/usr/local/bin/agent-tool`. Las rutas son fáciles de ocultar, reemplazar y enlazar mediante enlaces simbólicos.

## Deja de usar sesiones compartidas permanentes para el trabajo de agentes privilegiados

Un servidor de tmux permanente llamado `dev`, `main` o `shared` es un mal lugar para ejecutar agentes que puedan acceder a credenciales de producción. Facilita el trabajo activo, pero mezcla personas, tareas, historial del shell, estado del entorno y ciclos de vida de los procesos hasta que nadie puede decir dónde terminó una ejecución.

Mantén separado el multiplexado interactivo personal de la ejecución de agentes. Asigna a cada ejecución su propia sesión o socket. Iníciala con un comando registrado, captura su PID y hora de inicio y designa a una persona responsable antes de desconectarla. Si otro ingeniero necesita continuar la tarea, debe iniciar un proceso de agente nuevo y recibir una nueva decisión de autorización, en lugar de heredar por costumbre un panel antiguo.

Los equipos suelen resistirse porque reutilizar sesiones parece eficiente. Lo es hasta que un agente envía una solicitud después de que terminara la tarea original y el equipo de respuesta pasa una hora leyendo el historial. Los límites nuevos entre procesos cuestan segundos. Reconstruir un límite borroso cuesta mucho más y a menudo termina en una suposición en lugar de una respuesta.

El primer cambio operativo es sencillo: prohíbe las sesiones de tmux y screen sin nombre y de larga duración para agentes con acceso autenticado. Crea una sesión de corta duración por ejecución, registra la identidad de inicio y ciérrala cuando termine. Esa política ofrece a los sistemas de aprobación y a los investigadores un límite real con el que trabajar.
