Cómo funciona la atribución de una cuenta de API compartida entre sesiones de agentes
La atribución de cuentas de API compartidas mantiene la responsabilidad de las sesiones de agentes incluso cuando varios agentes locales usan una misma credencial del proveedor para realizar acciones externas.

A veces una cuenta de API compartida es la opción operativa adecuada. Los proveedores pueden emitir un único token para toda la organización, los límites de uso pueden pertenecer a esa cuenta y sustituirla por un montón de claves casi idénticas puede crear más secretos sin mejorar el control.
El error consiste en tratar esa cuenta como si fuera un actor. Es el principal de credenciales externo, es decir, la identidad que reconoce el proveedor. Cuando varios agentes locales la utilizan, necesitas un segundo registro que indique qué proceso local hizo cada solicitud, qué trabajo estaba autorizado a realizar y cómo obtuvo la autoridad para usar la credencial. Si no recopilas ese registro durante la ejecución, después solo podrás hacer suposiciones.
Esto es menos vistoso que ponerle un nombre a cada agente y crear un panel lleno de colores. También es lo que resiste cuando dos agentes compiten, uno reintenta, una persona revoca una ejecución a mitad de camino y la página de auditoría del proveedor solo muestra automation-service.
Una cuenta del proveedor y un actor son identidades distintas
Una cuenta compartida del proveedor responde a la pregunta: «¿Qué credencial aceptó el proveedor?». La atribución del actor responde a otra: «¿Qué principal local provocó esta operación concreta?». A menudo las respuestas son distintas, y meterlas en un solo campo produce registros de auditoría deficientes.
Mantén separadas al menos estas cuatro identidades:
- Cuenta externa: el tenant del proveedor, el usuario de servicio, el cliente OAuth o la identidad de la clave de API visible para la API remota.
- Sesión de ejecución: un proceso de agente iniciado, con un ID de sesión nuevo, impredecible y exclusivo.
- Principal iniciador: la persona, el trabajo de CI o el servicio principal que inició esa sesión.
- Referencia del trabajo: el issue, la solicitud de cambio, el despliegue, el repositorio o la tarea explícita que explica por qué se hizo la llamada.
La cuenta externa puede permanecer estable durante meses. La sesión de ejecución no debería hacerlo. Una referencia de tarea puede repetirse en varias sesiones. El iniciador puede ser una persona frente al teclado un día y una compilación automatizada al siguiente. Cada campo tiene una duración distinta y responde a una pregunta diferente.
Esta distinción no es una cuestión de terminología. Supón que vendor-prod elimina un despliegue remoto. El proveedor puede afirmar correctamente que vendor-prod hizo la eliminación. Tu registro local debe mostrar si la sesión s_7f3... procedía de un agente de lanzamientos iniciado por Maya, si tenía aprobación para esa ejecución y si la eliminación fue una llamada directa o un reintento después de un tiempo de espera. Un único campo actor=vendor-prod oculta todos los datos que podrían cambiar la respuesta al incidente.
RFC 8693 establece una distinción relacionada en la delegación OAuth. Separa el sujeto en cuyo nombre existe la autoridad del actor actual que utiliza la declaración JWT act. También indica que los servidores de recursos deben tomar las decisiones de acceso a partir de las declaraciones del token en el nivel superior y del actor actual, no de actores históricos anidados. Este límite también resulta útil para los sistemas locales de agentes: conserva la cadena de procedencia para investigar, pero toma las decisiones de autorización a partir de una identidad clara de la sesión actual, no de una historia larga y ambigua de llamadas anteriores.
No llames «el agente» a una cuenta del proveedor. La cuenta puede ser utilizada por agentes, scripts, operadores de emergencia y trabajos de migración. Dale un nombre preciso, como external_principal, y convierte la sesión local en el actor de tu propio registro de auditoría.
La identidad de la sesión debe proceder del lanzador
El proceso que inicia un agente debe crear su identidad de sesión antes de que el agente pueda solicitar una acción externa. No dejes que el agente la elija. Un agente que pueda escoger session_id=release-approved puede hacer que una revisión posterior resulte engañosa.
Un registro práctico de sesión contiene suficiente información para identificar el ejecutable y suficiente contexto para explicar el trabajo:
{
"session_id": "ses_01JQ6EXAMPLE3K5A",
"started_at": "2026-07-22T15:04:18Z",
"initiator": {
"kind": "human",
"id": "[email protected]"
},
"agent": {
"process_id": 48192,
"binary_authority": "signed-local-agent",
"launch_path": "/workspace/payments"
},
"work": {
"kind": "change_request",
"id": "CR-1842"
},
"parent_session_id": null
}
Los nombres exactos de los campos importan menos que quién los controla. El lanzador controla session_id, la hora de inicio, la identidad del ejecutable y la sesión principal. Una persona o el sistema que hace la llamada proporciona la referencia del trabajo, pero la pasarela debe registrar quién la proporcionó. El agente puede proponer una descripción de su tarea, pero ese texto nunca debe sustituir a la identidad proporcionada por el lanzador.
Los ID de proceso por sí solos son pruebas débiles. Los sistemas operativos los reutilizan, los registros sobreviven a los procesos y un ID de proceso dice poco sobre quién inició el binario. La autoridad de firma de código resulta más útil en un equipo local de desarrollo porque vincula la decisión de aprobación con la familia de procesos firmados. Aun así, registra la ruta del ejecutable y el contexto de inicio cuando estén disponibles. Una firma conocida no demuestra que todas las ejecuciones tuvieran el mismo propósito.
Usa una sesión nueva para cada proceso de agente nuevo. Reutilizar una sesión porque el número de tarea es el mismo convierte la aprobación de un experimento breve en un contenedor de permisos duradero. Los agentes de larga duración requieren una decisión explícita: conservar una sesión y hacer visible su duración, o renovarla en un límite definido, como una nueva solicitud de cambios o una ejecución reanudada desde el terminal. No hagas ambas cosas silenciosamente.
La atribución debe capturarse antes de inyectar la credencial
El lugar más seguro para vincular un actor a una solicitud es justo antes de que un componente de confianza aplique la credencial compartida y envíe la solicitud. Todo lo anterior puede ser modificado por el agente. Todo lo posterior puede no existir, resumirse o ser sobrescrito por el proveedor.
Crea un sobre de llamada que el agente no pueda redactar por completo. El agente proporciona la acción solicitada. La pasarela añade la identidad de la sesión, la decisión de autorización, el ID de llamada y la referencia de la credencial externa. Guarda el sobre antes de transmitir la solicitud y añade el resultado cuando llegue.
{
"call_id": "call_01JQ6F9K4W7D",
"session_id": "ses_01JQ6EXAMPLE3K5A",
"external_principal": "vendor-prod",
"channel": "http",
"request": {
"method": "POST",
"host": "api.vendor.example",
"path_template": "/v1/deployments/{id}",
"operation": "create_deployment"
},
"authorization": {
"vault_unlocked": true,
"session_authorized": true,
"per_call_approval": false
},
"work_id": "CR-1842",
"attempt": 1,
"created_at": "2026-07-22T15:08:34Z"
}
Fíjate en lo que falta: el bearer token, el cuerpo completo de la solicitud y una afirmación libre de que el agente es confiable. Un registro que guarda secretos para demostrar la atribución ha fallado en su primera tarea. Un registro que conserva cada byte del cuerpo también puede exponer datos de clientes, código fuente o registros regulados. Captura un nombre de operación normalizado, una plantilla de ruta, algunos identificadores no secretos y un resumen criptográfico del contenido cuando el propio contenido sea relevante para una revisión.
Este diseño también separa la intención del resultado. Un agente puede solicitar create_deployment, pero el servicio remoto puede devolver un error de validación. El diario de llamadas debe conservar ambos hechos. Después podrás responder si el agente intentó realizar la acción sin afirmar que tuvo éxito.
Sallyport sigue esta ubicación: el agente se conecta a través de su MCP shim, mientras la aplicación conserva el secreto y ejecuta la acción HTTP o SSH. De este modo, los registros de sesión y actividad pueden vincular una ejecución local con el uso de una credencial compartida sin introducir la credencial en el contexto del agente.
Los encabezados proporcionados por el agente son pruebas, no garantías
Los equipos suelen añadir encabezados como X-Agent-Name, X-Task-ID o X-Run-ID y dar por resuelto el problema. Esos campos pueden ayudar a relacionar los registros remotos, pero un agente que controla la solicitud también puede omitirlos, modificarlos o reproducirlos. Son etiquetas, no un límite de autoridad.
Puedes reenviar encabezados de atribución cuando el proveedor los acepte, siempre que la pasarela siga tres reglas. Primero, elimina cualquier versión de los encabezados reservados proporcionada por el agente. Segundo, genera los valores finales a partir de la sesión registrada y del sobre de llamada. Tercero, trata la recepción del encabezado por parte del proveedor como una prueba complementaria, no como la fuente de verdad.
Por ejemplo, reserva este pequeño conjunto de encabezados dentro de la pasarela:
X-Execution-Session: ses_01JQ6EXAMPLE3K5A
X-Action-Call: call_01JQ6F9K4W7D
X-Work-Reference: CR-1842
No pongas una dirección de correo, un prompt, un nombre de rama con datos de clientes ni un comando sin procesar en un encabezado solo porque resulte cómodo. Los encabezados pasan por proxies, sistemas de trazas, informes de errores y herramientas de soporte del proveedor. Usa ID opacos y resuélvelos después contra tu diario local protegido.
Algunos proveedores rechazan los encabezados desconocidos, los eliminan o no los muestran en sus vistas de auditoría. Es normal. La API remota no tiene por qué convertirse en tu sistema de identidad. Tu pasarela debe funcionar aunque el proveedor solo acepte su esquema de autorización habitual.
Hay otra trampa: un encabezado firmado no sustituye al registro local. Una firma de solicitud puede demostrar que una pasarela firmó una solicitud concreta, pero no conserva la aprobación humana, la identidad del proceso, el contexto de la tarea ni el resultado si no registras esos datos localmente. Las firmas protegen las afirmaciones del transporte. Por sí solas no crean un registro para investigar.
Los reintentos necesitan una cadena de procedencia, no una sola marca de tiempo
Los agentes autónomos reintentan. Los clientes HTTP reintentan. Los comandos SSH pueden ejecutarse de nuevo después de que se desconecte un terminal. Si tu registro de auditoría escribe una sola línea por cada acción prevista, oculta los mecanismos que provocan cambios duplicados. Si solo escribe las solicitudes sin procesar, hace que una única acción prevista parezca varias decisiones sin relación.
Modela ambos niveles. Asigna a la operación prevista un operation_id y da a cada intento de red un call_id independiente. Asocia los reintentos con el intento anterior y registra por qué ocurrió el reintento.
{
"operation_id": "op_01JQ6F8P0Z",
"call_id": "call_01JQ6F9K4W7D",
"attempt": 2,
"retries_call_id": "call_01JQ6F79S2M1",
"retry_reason": "connection_closed_before_response",
"idempotency_key": "idem_94c2e1",
"vendor_request_id": "req_8d71"
}
El campo retry_reason importa. Una respuesta 429 significa que el proveedor recibió la primera solicitud y la rechazó por superar el límite de uso. Un tiempo de espera después de que los bytes hayan salido de tu pasarela no indica si el proveedor completó la acción. Esos casos exigen respuestas operativas distintas y no deberían reducirse todos a failed.
Usa claves de idempotencia para las operaciones que crean o modifican estados remotos cuando el proveedor las admita. Genera la clave en la pasarela de confianza o haz que el lanzador la proporcione junto con el registro de trabajo. No permitas que un modelo cree una clave nueva cada vez que revisa su propio plan, porque perderás la capacidad de reconocer una operación repetida.
Un fallo habitual se desarrolla así. La sesión A solicita crear un despliegue, la conexión se interrumpe y su cliente reintenta. La sesión B comienza unos instantes después con la misma referencia de tarea, no ve ningún despliegue visible y vuelve a solicitarlo. Ahora el proveedor tiene dos despliegues. Un diario útil muestra dos sesiones, dos operaciones previstas, sus intentos individuales y cualquier clave de idempotencia compartida. Un diario deficiente muestra cuatro líneas POST /deployments bajo una sola cuenta de servicio y deja que el equipo reconstruya el resto a partir de las marcas de tiempo.
La aprobación debe vincularse a un proceso, no a un nombre amigable
Un mensaje que pregunta «¿Permitir que el agente de lanzamientos use producción?» parece razonable hasta que existen dos agentes de lanzamientos, uno iniciado desde un repositorio confiable y otro desde un directorio copiado. Un nombre es texto de presentación. La aprobación debe vincularse a la sesión de ejecución y a la autoridad del proceso que la creó.
La aprobación por sesión es un buen valor predeterminado para agentes que realizan varias llamadas relacionadas. Permite al operador ver quién solicita la acción y evita convertir una tarea breve en una página llena de avisos idénticos. La aprobación debe caducar cuando el proceso termine. Un proceso nuevo, incluso con el mismo texto de tarea, debe volver a solicitarla.
Usa la aprobación por llamada para operaciones de alto impacto o con un alcance inusualmente amplio. No sustituye a la aprobación de sesión. Responde a una pregunta más concreta: ¿debe continuar ahora este uso concreto de esta credencial? Un equipo que usa la aprobación por llamada para cada lectura inofensiva acabará aprobando sin leer. Eso es fatiga de aprobación diseñada, no un fallo humano.
Registra la decisión como un evento con una referencia estable:
{
"approval_id": "apr_01JQ6G3C",
"session_id": "ses_01JQ6EXAMPLE3K5A",
"scope": "session",
"decision": "approved",
"decided_at": "2026-07-22T15:06:11Z",
"process_authority": "signed-local-agent"
}
No registres un booleano aislado en cada llamada y finjas que demuestra el consentimiento. El booleano indica que existía una aprobación. El evento de aprobación muestra cuándo ocurrió, qué cubría y qué sesión autorizaba. Si un operador revoca después la sesión, conserva esa revocación como un evento nuevo. Borrar la aprobación anterior hace que el registro parezca más limpio y que el incidente resulte más difícil de entender.
Los registros de auditoría del proveedor deben corroborar tu registro
Los registros del proveedor son útiles, pero normalmente describen su propio modelo de identidad, no el tuyo. Un token compartido puede aparecer como un usuario de servicio, una aplicación OAuth, un hash del token, una instalación o una dirección IP. Eso puede ayudar a confirmar que ocurrió una llamada externa, pero rara vez indica qué sesión local del agente seleccionó la acción.
La documentación de GitHub ofrece un ejemplo concreto de esta distinción. Las llamadas realizadas con un usuario de GitHub App y un token de servidor pueden mostrar al usuario como actor de auditoría e identificar al mismo tiempo el tipo de acceso programático mediante ese tipo de token. Los eventos de auditoría empresarial de GitHub también muestran campos como el actor, la información del token, el ID de solicitud y el agente de usuario para muchos tipos de eventos. Es una prueba útil del lado del proveedor, pero el significado de esos campos pertenece al modelo de autorización de GitHub, no al modelo local de sesiones de agentes.
Relaciona los registros remotos y locales mediante correlacionadores estables cuando sea posible:
- Guarda el ID de solicitud del proveedor que devuelva en un encabezado o en el cuerpo de la respuesta.
- Guarda tu ID de llamada saliente y un nombre de operación normalizado.
- Registra el estado de la respuesta, la hora de finalización y los identificadores seguros de los recursos.
- Conserva el principal externo utilizado para la llamada.
- Mantén el ID de sesión local como identidad de ejecución autorizada.
Evita relacionar los registros principalmente por la hora. La diferencia entre relojes, el procesamiento asíncrono del proveedor, los reintentos y las colas hacen que una marca de tiempo cercana sea menos fiable de lo que parece. Las marcas de tiempo siguen siendo útiles para acotar una búsqueda, pero no deberían decidir la atribución cuando existe un ID de solicitud o una clave de idempotencia.
Algunos proveedores pueden emitir tokens delegados de corta duración, tokens OAuth en nombre de un usuario o tokens de instalación de una aplicación. Usa esas capacidades cuando proporcionen al proveedor una visibilidad significativa del actor y encajen con tu modelo de privilegios. GitHub, por ejemplo, documenta la diferencia entre una aplicación que actúa en nombre de un usuario y otros tipos de acceso programático. Eso ofrece una atribución mejor del lado del proveedor que un token estático compartido, pero no elimina la necesidad de identificar el proceso local que inició la llamada.
Separa las credenciales solo cuando creen un límite real
El consejo habitual es «dale a cada agente su propia clave de API». Es popular porque resulta fácil de explicar y porque hace que la pantalla de auditoría del proveedor parezca más ordenada. No siempre es el control adecuado.
Las credenciales independientes justifican su coste operativo cuando crean un límite significativo. Puede tratarse de alcances distintos para un agente de descubrimiento de solo lectura y un agente de despliegue, revocación independiente en el proveedor, facturación separada o un registro del proveedor que identifique al principal distinto de una manera útil para quienes responden a incidentes. Si cada clave tiene el mismo alcance amplio, el mismo responsable de rotación y la misma ruta de ejecución local, has multiplicado el inventario de secretos más de lo que has mejorado la atribución.
Haz esta comprobación antes de crear otra identidad en el proveedor:
- ¿La nueva credencial puede tener menos privilegios que la compartida?
- ¿Puedes revocarla sin interrumpir trabajos no relacionados?
- ¿El proveedor la registrará como un actor distinto de una forma que puedan utilizar quienes responden a incidentes?
- ¿Puedes rotarla y retirarla sin dejar copias olvidadas en las herramientas locales?
- ¿Elimina una decisión de autorización significativa de la pasarela local?
Si la respuesta es negativa en la mayoría de los casos, conserva la cuenta externa compartida y mejora el registro del actor local. Así proporcionarás a quienes responden a incidentes los datos que realmente necesitan: qué sesión de agente hizo la llamada, quién la inició, para qué elemento de trabajo, con qué aprobación y con qué resultado.
Este argumento tiene un límite. Si una credencial concede administración de producción y un agente experimental no necesita ese poder, no la compartas solo porque tus registros sean excelentes. La atribución explica una acción después de que ocurra. La limitación del alcance determina qué acciones pueden ocurrir.
Un diario resistente a manipulaciones debe conservar el orden y las denegaciones
Un registro de auditoría que solo conserva las llamadas exitosas al proveedor ofrece una historia incompleta. Las llamadas denegadas, los intentos con el almacén bloqueado, las aprobaciones rechazadas y las sesiones revocadas suelen explicar por qué un incidente no empeoró. También muestran que un agente siguió solicitando una acción después de perder su autoridad.
Escribe un evento cuando se inicie la sesión, cuando ocurra una decisión de autorización, cuando se prepare una llamada, cuando termine la acción externa y cuando se revoque o finalice una sesión. Vincula los registros mediante ID en lugar de copiar un objeto grande y mutable en cada línea. La cadena debe hacer visible la secuencia sin obligar a cada consumidor a reconstruir el estado a partir de prosa.
La resistencia a manipulaciones importa porque la atribución local suele ser la única fuente que distingue a varios agentes concurrentes que utilizan la misma cuenta del proveedor. Si una persona con acceso local puede modificar un registro de llamadas después de un incidente, el equipo ha reconstruido el mismo problema de confianza un nivel más cerca. Los registros encadenados mediante hashes ayudan a los revisores a detectar cambios, pero no deciden qué campos registrar. Aún necesitas un modelo completo de eventos.
Sallyport proyecta sus diarios Sessions y Activity desde un único registro de auditoría cifrado y encadenado mediante hashes, y puede verificar esa cadena sin conexión con sp audit verify. El punto operativo importante no es el nombre del comando. Es que la aprobación de una sesión, una acción individual y una revocación posterior pueden comprobarse dentro del mismo registro ordenado.
No uses la etiqueta de una cuenta del proveedor como respuesta final cuando una persona que revisa un incidente pregunte quién hizo algo. Sigue el registro desde el principal externo hasta el ID de llamada, del ID de llamada a la sesión de ejecución, de la sesión al iniciador y la aprobación, y después de la respuesta al propio identificador de solicitud del proveedor. Si falta cualquiera de esos vínculos, corrige ese punto de captura antes de que la siguiente credencial compartida se convierta en un misterio.
FAQ
¿Pueden varios agentes de IA usar de forma segura una sola cuenta de API?
Una cuenta de proveedor puede seguir siendo compartida si registras una identidad local independiente y confiable para cada llamada. El proveedor seguirá mostrando la cuenta compartida, salvo que admita identidades delegadas, pero tu propio registro puede indicar qué proceso de agente, tarea, sesión y aprobación dieron lugar a la solicitud.
¿Por qué una clave de API compartida pierde la atribución del actor?
Un token bearer identifica a quien posee el token, no a la persona o al agente que provocó una solicitud concreta. Si tres sesiones pueden leer el mismo token, el proveedor no tiene una base fiable para distinguirlas después de recibir la solicitud.
¿Qué campos debe incluir un registro de auditoría de la API de un agente?
Usa la identidad de la cuenta del proveedor como principal externo y añade una identidad de ejecución aplicada localmente, un ID de sesión, una referencia de tarea y un ID por llamada. Trátalos como campos distintos, porque una cuenta de API y una sesión de agente responden a preguntas diferentes.
¿Basta con un encabezado X-Agent-Name para atribuir una acción en la auditoría?
No. Un agente puede escribir cualquier encabezado que tenga permitido enviar, así que X-Agent-Name es texto declarado por el propio agente, a menos que una pasarela de confianza lo elimine y lo sustituya. Puede servir para depurar, pero no puede resolver una revisión de incidentes.
¿Cómo debo identificar sesiones locales independientes de agentes?
Asigna a cada proceso de agente iniciado un identificador de sesión nuevo y vincula la autorización a ese proceso, no a una etiqueta reutilizable. Cuando el proceso termine, su autoridad también debe terminar. Así evitas que una aprobación antigua cubra silenciosamente una ejecución nueva.
¿Cómo audito los reintentos realizados por agentes de IA?
Registra el ID de la llamada original, cada intento de reintento, la clave de idempotencia si existe y la respuesta o el ID de solicitud del proveedor. Un reintento forma parte de la misma operación prevista, pero puede producir varias solicitudes de red que los investigadores necesitan ver por separado.
¿Debe tener cada agente de IA su propia clave de API del proveedor?
Las credenciales de proveedor independientes son mejores cuando el proveedor admite el mínimo privilegio, la separación de facturación, registros de auditoría útiles y una gestión razonable de su ciclo de vida. No son automáticamente mejores cuando el equipo crea docenas de tokens de larga duración con el mismo acceso y sin un proceso para retirarlos.
¿Puede el intercambio de tokens OAuth conservar la identidad del agente?
El intercambio de tokens OAuth puede transportar un sujeto y un actor cuando el servidor de autorización y el servidor de recursos admiten ese modelo. No añade atribución a una clave de API estática normal ni obliga al proveedor a conservar campos que no reconoce.
¿Puedo confiar únicamente en el registro de auditoría del proveedor?
No lo uses como registro autorizado. Conserva primero tu propio registro inmutable de llamadas y guarda después el ID del evento del proveedor, el estado y los detalles relevantes de la respuesta como pruebas de corroboración, cuando el proveedor los ofrezca.
¿Cómo ayuda Sallyport cuando los agentes comparten credenciales?
Sallyport conserva un registro de sesiones y otro de actividad individual dentro de un único registro de auditoría cifrado y encadenado mediante hashes, de modo que una credencial compartida no borra la sesión local que la utilizó. Su control del almacén, la autorización de sesiones y la aprobación opcional por llamada también hacen que la decisión de autorización forme parte del registro, en lugar de dejarla como una suposición posterior al incidente.