¿Sobrevive la aprobación de sesión al ejecutar un reemplazo?
La aprobación de sesión para reemplazar procesos necesita un límite claro: conserva la confianza solo para la misma imagen verificada y vuelve a preguntar cuando aparece un ejecutable nuevo.

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:
{
"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
execde una copia exacta de sí mismo. La pasarela conserva la sesión y registra un evento de continuidad. - El binario hace
execde 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.
FAQ
¿`exec` conserva la misma identidad del proceso a efectos de aprobación?
No. Por lo general, exec conserva el identificador del proceso en el sistema operativo, pero reemplaza la imagen del programa que ese identificador representa. Si tratas el PID como la identidad de aprobación, un programa diferente puede heredar una autoridad que nunca presentó ante una persona.
¿Una llamada a `exec` debe requerir una nueva aprobación?
Exige otra aprobación siempre que cambie la identidad del ejecutable. Una repetición de exec del mismo archivo ejecutable verificado puede conservar la sesión, pero coincidir solo en la ruta o en el firmante es demasiado amplio.
¿Basta la ruta del ejecutable para conservar una sesión?
No. Una ruta es una ubicación, no una prueba de lo que se ejecutará. Un actualizador, un cambio de destino de un enlace simbólico, un archivo reemplazado o un intérprete modificado pueden mantener la misma ruta y cambiar el código que recibe autoridad para realizar acciones con credenciales.
¿Basta la autoridad de firma de código para confiar en un ejecutable reemplazado?
Ayuda a la persona a reconocer quién publicó el programa y debe aparecer en la tarjeta de aprobación. No demuestra que todos los ejecutables de ese editor merezcan el mismo permiso ni indica qué script, argumentos o proceso principal lo inició.
¿Cómo debe gestionar la aprobación de sesión los scripts de shell?
Aprueba el intérprete como imagen ejecutable y muestra como contexto la identidad y el resumen criptográfico del script. Si el script cambia, trátalo como una solicitud modificada aunque el binario del intérprete siga siendo el mismo.
¿Cuál es la diferencia entre un proceso hijo y un reemplazo mediante `exec`?
Son decisiones independientes. Un proceso hijo comienza como un proceso nuevo y debe solicitar autorización con su propia identidad. Un reemplazo mediante exec cambia la imagen dentro de un proceso existente y debe restablecer la autorización cuando cambia esa imagen.
¿Qué debe registrar una auditoría cuando un proceso ejecuta otro programa mediante `exec`?
Registra la imagen anterior, la imagen reemplazada, la relación con el proceso principal, la marca de tiempo, la decisión de aprobación y cualquier identificador de sesión heredado. El registro de auditoría debe dejar claro si la pasarela permitió la continuidad o volvió a pedir aprobación.
¿Puede un iniciador aprobado transferir su sesión a otro programa?
No hagas que la aprobación sea transferible solo porque un iniciador tenga una firma o esté aprobado. Aprueba el ejecutable final que realizará las acciones o haz que el iniciador vuelva a pedir aprobación después de descubrir e iniciar ese ejecutable.
¿Qué casos de `exec` debo probar antes de publicar?
Prueba los reemplazos mediante un enlace simbólico, un script modificado, un intérprete diferente, una actualización en el mismo lugar y un iniciador que seleccione un asistente durante la ejecución. Comprueba también que los reemplazos rechazados no puedan usar ningún canal con credenciales antes de que termine la nueva aprobación.
¿Qué debe mostrar una solicitud de aprobación nueva después de `exec`?
Muestra los nombres y las rutas del ejecutable anterior y del nuevo, las autoridades de firma y el motivo por el que la pasarela considera nueva la solicitud. Una persona puede decidir rápido cuando la tarjeta explica el cambio con claridad en lugar de mostrar una solicitud genérica de confianza.