# ¿Sobrevive la aprobación de sesión al ejecutar un reemplazo?

Una aprobación de sesión debe seguir una identidad de ejecución verificada, no un identificador de proceso del sistema operativo. Cuando un proceso llama a `exec`, el núcleo puede conservar su PID mientras reemplaza el código, los argumentos, el entorno y, a menudo, la finalidad práctica del proceso. Si permites que la aprobación anterior sobreviva a ese reemplazo, das a código no revisado la autoridad que una persona concedió a otra cosa.

La regla que implementaría es sencilla: si el reemplazo tiene una identidad de ejecutable diferente, debe volver a pedir aprobación antes de realizar acciones que usen credenciales. Conserva la continuidad solo en una repetición de `exec` verificada y limitada al mismo archivo ejecutable. Esta política añade alguna solicitud adicional en un flujo legítimo. A cambio, cierra una brecha mucho más peligrosa en cualquier flujo donde un agente, un envoltorio, un actualizador o una dependencia comprometida pueda elegir qué se ejecuta después.

## Una aprobación vincula a un actor, no a un PID

Un PID identifica una posición administrativa del núcleo, mientras que una aprobación debe identificar el programa que puede gastar una decisión humana. Son funciones diferentes, y tratarlas como si fueran el mismo objeto causa problemas en cuanto el código empieza a ejecutar otro código.

Sallyport describe la autorización por sesión como una aprobación para un proceso de agente nuevo que dura hasta que termina esa ejecución. Es una regla útil para la persona usuaria, pero la implementación necesita una definición interna más precisa: la ejecución aprobada debe seguir siendo el ejecutable aprobado, no limitarse a conservar el mismo PID.

La diferencia importa porque los secretos permanecen en la pasarela y el agente recibe resultados, no material de credenciales. Este diseño elimina el problema habitual de que un proceso hijo lea un token de una variable de entorno. No elimina la capacidad de un proceso sustituido para pedir a la pasarela que llame a una API o ejecute SSH con una credencial almacenada. Si ese proceso sustituido hereda la aprobación, puede causar el mismo daño externo sin llegar a ver el secreto.

Haz explícito el sujeto de la aprobación. Debe incluir una identidad estable del ejecutable, el evento de creación del proceso o un nonce de sesión, la autoridad de firma de código que ve la persona y suficiente contexto de inicio para explicar por qué existe el proceso. Usa el PID como atributo de auditoría y como ayuda práctica para resolver problemas. No lo uses como credencial portadora.

Esta distinción también mantiene honesta la revocación. Si una persona revoca una ejecución, la pasarela debe rechazar las llamadas posteriores de esa ejecución aunque vuelva a ejecutarse mediante `exec`. Si un reemplazo recibe una aprobación nueva, debe obtener un registro de sesión nuevo que la persona pueda revocar de forma independiente.

## `exec` cambia el ejecutable aunque conserve el PID

`exec` debe restablecer la autorización cuando carga un programa diferente, porque reemplaza la imagen del programa aunque el sistema operativo pueda conservar el PID. POSIX dice que una función exec «reemplaza la imagen del proceso actual». La frase es breve, pero acierta en lo importante: la continuidad es administrativa, no una prueba de que siga presente el mismo actor.

Un shell puede hacer que esto pase desapercibido. Un desarrollador inicia un agente aprobado, el agente invoca un asistente y el asistente llama a `exec` para no dejar otro proceso principal alrededor. Las listas de procesos pueden mostrar el mismo PID antes y después del reemplazo. Si la consulta de sesión dice `pid 4127 is approved`, el nuevo asistente ahora tiene la autoridad del agente anterior.

El cambio de ejecutable también puede modificar el riesgo de maneras que un PID no puede describir. El reemplazo puede comunicarse con otro host, interpretar un archivo no confiable de un repositorio, cargar extensiones, aceptar datos por la entrada estándar o existir únicamente para retransmitir solicitudes de acción. Ninguno de esos hechos aparece en un número de proceso.

No bases la decisión en que la nueva línea de comandos parezca conocida. Los argumentos son un contexto útil, pero un programa puede modificarlos y un envoltorio puede hacer que un comando aparentemente inofensivo inicie un objetivo no relacionado. Establece la identidad del ejecutable a partir de la imagen que el sistema operativo inició realmente y conserva la ruta y los argumentos observados como pruebas para la persona que revisa la solicitud.

`posix_spawn` pertenece a la misma conversación de diseño, pero da un resultado diferente. Crea un proceso hijo en lugar de reemplazar la imagen del proceso que llama. De forma predeterminada, el hijo no debe tener aprobación de sesión. Un `fork` seguido de `exec` debe terminar igual: el proceso nuevo solicita aprobación para la imagen que finalmente se ejecuta.

## Un ejecutable nuevo necesita una aprobación nueva

Una pasarela debe exigir una aprobación nueva antes de que un ejecutable diferente pueda realizar cualquier acción a través de una sesión ya autorizada. Define «diferente» mediante una identidad de imagen verificada, no mediante un nombre de archivo ni un nombre mostrado.

Un registro de identidad práctico puede contener el identificador inmutable del ejecutable proporcionado por la plataforma, un resumen criptográfico del código firmado cuando esté disponible, la autoridad de firma y la ruta concreta del ejecutable observada al iniciarse. Los dos primeros campos responden si la imagen cambió. El firmante indica a la persona que revisa quién asumió la responsabilidad del código. La ruta muestra de dónde provino el inicio. Cada campo responde a una pregunta distinta, así que no los combines en una sola cadena.

Este es el fallo que hace que la herencia permisiva parezca atractiva hasta que ya es demasiado tarde. Un agente de programación aprobado llama a un asistente del repositorio. El asistente ve una configuración de entorno y se reemplaza por una utilidad compilada localmente en la misma ruta prevista. La utilidad no necesita extraer una credencial de API. Pide una acción HTTP que elimina una implementación, cambia una configuración de facturación o publica una versión. La pasarela ve el PID anterior y acepta la llamada. La persona aprobó el agente de programación, no la utilidad que se eligió a sí misma después de la aprobación.

El argumento habitual para heredar la aprobación es el cansancio ante tantas solicitudes. Esa preocupación es real, pero permitir cualquier reemplazo no la resuelve. Oculta una decisión a la única persona que puede juzgar si el reemplazo tiene sentido. Mantén escasas las tarjetas de aprobación haciendo estable la ejecución normal del agente y vuelve a preguntar en el momento en que cambia el actor.

La comprobación debe producirse antes de inyectar credenciales, ejecutar SSH o realizar cualquier otra acción saliente. También debe ocurrir antes de que la pasarela devuelva metadatos que puedan ayudar a un reemplazo a preparar una acción. Una aprobación pendiente no es un estado parcialmente autorizado.

## La repetición de `exec` con la misma imagen es la excepción limitada

Una repetición verificada de `exec` con exactamente la misma imagen ejecutable puede conservar la aprobación de sesión, porque no introduce un actor nuevo. Los programas usan esta técnica para reinicios limpios, cambios en los descriptores de archivo o una transferencia deliberada después de actualizar su propio entorno. Mostrar otra tarjeta en ese caso añade ruido sin aportar una decisión relevante.

Mantén la excepción limitada. La pasarela debe comparar la imagen observada actual con la imagen que recibió la aprobación. Si la identidad es idéntica, puede conservar el nonce de sesión y escribir un evento de continuidad en el registro de auditoría. Si la pasarela no puede establecer esa identidad, debe volver a preguntar. La ambigüedad no demuestra que el reemplazo sea seguro.

Tampoco conviertas esto en una excepción para toda la autoridad de firma. Un firmante puede publicar un agente, un instalador, una herramienta de diagnóstico y una utilidad de red. Esos programas pueden tener permisos de acción muy diferentes. La autoridad de firma visible ayuda a la persona a valorar la solicitud, pero no debe extender silenciosamente la aprobación a todos los binarios que llevan la misma autoridad.

Tampoco lo conviertas en una excepción para toda la ruta. Una actualización puede reemplazar los bytes de una ruta fija. Un enlace simbólico puede apuntar a otro lugar después de la aprobación. Un script puede conservar el nombre de archivo mientras cambia su contenido. La comparación de identidad debe resistir los tres casos.

Cuando una actualización legítima instala una versión nueva del agente, deja que vuelva a pedir aprobación. Esa solicitud comunica un hecho real: el ejecutable que actuará ha cambiado. Una persona que considere rutinaria la actualización puede aprobarla con un clic. Quien no esperara el cambio tiene la oportunidad de detenerlo.

## La autoridad de firma de código ayuda a valorar el programa, pero no concede permisos

Muestra la autoridad de firma de código de forma destacada porque responde a una pregunta que las personas realmente tienen: ¿quién distribuyó este ejecutable? No confundas esa respuesta con una regla completa de autorización.

El modelo de firma de código de Apple ofrece a macOS una forma de identificar el código firmado y verificar su integridad según las reglas de confianza aplicables. Es una prueba sólida para la tarjeta de aprobación. No dice que todo el código de una autoridad tenga la misma finalidad operativa ni indica a la pasarela si un proceso principal eligió el ejecutable mediante una configuración no confiable de un repositorio.

Una buena tarjeta de aprobación muestra primero el nombre y la ruta del ejecutable, y después la autoridad de firma, la identidad del proceso principal y el motivo de la nueva solicitud. En un reemplazo mediante `exec`, debe indicar ambos lados del cambio en una sola frase: el agente aprobado se reemplazó por este ejecutable. La persona no debería tener que deducir la transición comparando dos solicitudes separadas.

Los casos firmados y sin firmar merecen el mismo límite. Una compilación local sin firma puede ser una parte esperada de un flujo de desarrollo, y una utilidad firmada puede seguir siendo el proceso equivocado para heredar autoridad. La tarjeta debe describir las pruebas disponibles sin fingir que una firma convierte un ejecutable nuevo en el anterior.

Evita etiquetas vagas como «proceso confiable». Animan a las personas a aprobar una categoría en lugar de una solicitud concreta. Nombra el ejecutable y muestra su relación con el proceso ya aprobado. Así, quien revisa tiene algo que puede reconocer o rechazar.

## Los scripts y los iniciadores dejan al descubierto el límite débil

Un inicio controlado por un script necesita dos identidades: el intérprete que lo ejecuta y el script cuyo contenido lo controla. Si inspeccionas solo el intérprete, todos los scripts de shell parecen el mismo shell. Si inspeccionas solo el script, puedes pasar por alto un intérprete elegido mediante una línea shebang o un envoltorio.

En un script de shell, registra la identidad del ejecutable del intérprete, la ruta resuelta del script y un resumen criptográfico de su contenido. Si el script se ejecuta mediante un shell aprobado y ese shell hace `exec` de otro binario, el reemplazo del binario sigue requiriendo una aprobación nueva. Un script no debe convertirse en un túnel que atraviese el límite de la sesión.

Los iniciadores plantean un problema relacionado. Un iniciador aprobado puede inspeccionar un archivo de configuración, descubrir una herramienta en `PATH`, descargar un asistente o elegir un directorio de versión. Es habitual aprobar el iniciador y tratar su objetivo seleccionado como parte de la misma ejecución. Esa regla es incorrecta cuando el iniciador toma una decisión relevante para la seguridad después de que la persona lo haya aprobado.

Usa uno de estos dos enfoques. Si el iniciador conoce su objetivo antes de realizar su primera llamada a la pasarela, deja que la tarjeta muestre el objetivo final y aprueba esa identidad de ejecución. Si lo elige más tarde, deja que se ejecute sin autoridad de acción y exige aprobación cuando el objetivo seleccionado intente actuar por primera vez. La segunda opción produce un registro de auditoría más honesto.

La misma regla se aplica a los complementos del entorno de ejecución y a los intérpretes integrados. Un host nativo puede no cambiar mientras carga código desde un directorio del proyecto. Si ese código cargado puede formular solicitudes a la pasarela, la identidad de la imagen del host por sí sola no describe al actor real. La pasarela no puede inspeccionar de forma segura todos los entornos de ejecución, así que la opción más segura es limitar la aprobación de sesión a un ejecutable de agente definido y exigir una decisión nueva cuando este entregue el control de las acciones a un programa externo.

## Los procesos hijos y los reemplazos mediante `exec` son casos de delegación distintos

Un proceso hijo no debe heredar la aprobación de sesión solo porque su proceso principal la tenga. Crear un proceso introduce un actor nuevo, mientras que `exec` reemplaza al actor actual. Ambos casos necesitan una aprobación nueva cuando un ejecutable diferente vaya a realizar llamadas a la pasarela, pero sus relaciones de auditoría son distintas.

Para un hijo, crea un candidato a sesión nuevo con una referencia a la sesión principal. Muestra el proceso principal en la tarjeta de aprobación porque aporta contexto útil, no porque conceda permiso. Si la persona aprueba el hijo, dale su propio nonce de sesión y su propio control de revocación.

En un `exec`, cierra o reemplaza la identidad del ejecutable anterior y crea un candidato de reemplazo vinculado a la sesión anterior. Si la nueva imagen coincide exactamente con la aprobada, conserva la continuidad y registra el resultado. Si es diferente, detente en la barrera y espera una decisión. Así evitas un único registro de sesión demasiado grande que contenga varios programas sin relación.

No crees un token de delegación general para que un proceso principal lo entregue a sus hijos o reemplazos. Un token que diga «cualquier cosa que inicie puede actuar» se convierte en un premio fácil para un agente comprometido o un envoltorio confundido. Una referencia al proceso principal en el registro basta para contar la historia sin convertir la ascendencia en autoridad.

Esta separación también mejora la revisión de incidentes. Puedes responder si el proceso principal inició un hijo, si se reemplazó a sí mismo y si una persona aprobó el ejecutable resultante. Un registro plano de solicitudes permitidas no puede responder a esas preguntas después de una acción dañina.

## Registra el reemplazo como un evento propio

Un registro de auditoría debe mostrar un reemplazo mediante `exec` como un evento independiente, tanto si la pasarela conservó la aprobación como si volvió a pedirla. Sin ese evento, quien revisa ve acciones de una misma sesión y puede suponer que un único ejecutable estable realizó todas.

Un contrato de diseño podría tener este aspecto. Es un ejemplo de la información que conviene conservar, no un formato de comunicación obligatorio:

```json
{
  "event": "execution_replaced",
  "session_id": "sess_8f2c",
  "previous_image": {
    "identity": "image:4f19...",
    "path": "/work/agent/bin/agent"
  },
  "current_image": {
    "identity": "image:b66a...",
    "path": "/work/agent/bin/release-helper",
    "signing_authority": "Example Development Team"
  },
  "decision": "approval_required",
  "parent_relation": "exec"
}
```

El evento necesita las identidades anterior y actual, no solo una indicación de que ocurrió un `exec`. También necesita el resultado de la decisión. Un registro de acción posterior debe referirse a la identidad de sesión actual para que una persona investigadora pueda vincular la acción con la aprobación que la permitió.

Conserva este registro como una secuencia de solo anexado junto con el resto del historial de acciones. El registro de auditoría cifrado y encadenado mediante hashes de Sallyport, junto con la comprobación sin conexión `sp audit verify`, resulta especialmente útil aquí porque el evento de reemplazo y las acciones posteriores pueden compartir una secuencia verificable. El resultado de la verificación demuestra que la secuencia almacenada no ha cambiado. No convierte en aceptable una política de aprobación demasiado amplia.

Cuando una persona revoque una sesión, registra la revocación contra la identidad del ejecutable que tenía la sesión. Si un reemplazo recibió una aprobación nueva, debe seguir apareciendo por separado. Ese detalle evita que un control de revocación sugiera una cobertura más amplia de la que realmente tiene.

## Una tarjeta de aprobación necesita los datos anteriores y posteriores

Una tarjeta de aprobación nueva después de `exec` debe explicar el reemplazo de un vistazo y facilitar la decisión segura. Las solicitudes genéricas hacen que la gente las acepte sin leer. Una tarjeta que nombra el ejecutable cambiado les da un motivo para detenerse solo cuando algo ha cambiado.

Empieza con la identidad del ejecutable nuevo y el canal de acción que quiere usar. Después muestra que un proceso ya aprobado lo inició, el nombre y la ruta del ejecutable anterior, la nueva ruta y la autoridad de firma de código. Si el reemplazo procede de un script o un iniciador, incluye esa relación con palabras sencillas.

Usa un modelo de decisión que exponga exactamente qué está aprobando la persona. Aprobar el reemplazo debe autorizar la ejecución de ese ejecutable hasta que termine, sujeto a la barrera del almacén y a cualquier credencial marcada para aprobación en cada llamada. No debe autorizar retroactivamente procesos hermanos, reemplazos futuros ni un archivo actualizado en la misma ruta.

Hay una prueba útil para el texto: ¿podría un desarrollador cansado distinguir entre un asistente esperado y un descargador inesperado? Si no, a la tarjeta le faltan los datos importantes. Más lenguaje de seguridad decorativo no solucionará el problema.

Mantén bajo el número de solicitudes mediante una ejecución estable, no mediante una herencia amplia. Un agente normal que conserva una imagen debe mostrar una tarjeta de sesión. Un proceso que cambia de actor debe mostrar una tarjeta porque ha cruzado exactamente el límite que el concepto de sesión existe para hacer cumplir.

## Diseña las pruebas en torno a las evasiones que se usan en la práctica

Prueba el límite de autorización con reemplazos que conserven identificadores superficiales. Las pruebas del caso ideal con un binario estable no encontrarán los errores que entregan autoridad al ejecutable equivocado.

Empieza con estos casos:

- Un binario aprobado hace `exec` de una copia exacta de sí mismo. La pasarela conserva la sesión y registra un evento de continuidad.
- El binario hace `exec` de un ejecutable firmado diferente de la misma autoridad. La pasarela rechaza las acciones hasta que la persona aprueba la nueva ejecución.
- Un enlace simbólico conserva la misma cadena de ruta, pero resuelve a un ejecutable diferente. La pasarela vuelve a pedir aprobación.
- Un script de shell cambia de contenido después de comenzar la sesión. La siguiente solicitud controlada por el script no reutiliza la decisión anterior.
- Un iniciador comienza un hijo y el hijo intenta realizar una acción HTTP o SSH. El hijo necesita su propia decisión de sesión.

Después prueba el orden de las operaciones. Haz que el reemplazo emita una solicitud de acción inmediatamente después de `exec`. Confirma que la pasarela la rechaza o la mantiene pendiente, y confirma que ni la inyección de credenciales ni la ejecución de SSH comienzan antes de recibir el resultado de la aprobación. Esto detecta implementaciones que actualizan el registro después de haber enviado el trabajo.

Prueba la revocación en la misma batería. Revoca una ejecución aprobada, intenta una repetición de `exec` con la misma imagen y confirma que prevalece el estado revocado. Aprueba un reemplazo nuevo, revoca solo la sesión original y confirma que los dos registros se comportan según los controles declarados por el producto. Un modelo de sesión genera confianza cuando sus casos límite se comportan como su lenguaje visible.

Por último, inspecciona la salida de auditoría como lo haría una persona. Debes poder seguir una acción hasta el evento de reemplazo y desde ahí hasta la tarjeta de aprobación que cubría el ejecutable. Si para responder necesitas correlacionar PIDs, adivinar a partir de las marcas de tiempo o confiar en una ruta que pudo haber cambiado, el modelo todavía tiene un agujero.

Un reemplazo de proceso es el momento de ser estricto. El código anterior tenía una decisión. El código nuevo necesita la suya.
