# Cuentas de servicio para agentes de IA sin responsabilidad compartida

Los agentes de IA necesitan cuentas de servicio, pero una cuenta de servicio nunca debe convertirse en el nombre que usas cuando no sabes quién autorizó una acción. Dale a cada flujo duradero su propia identidad, vincula a esa identidad con una persona identificada y elimínala cuando el flujo termine. Cualquier cosa más débil crea una responsabilidad compartida, que es otra forma de decir que nadie puede dar una respuesta completa después de una mala decisión.

He visto este problema repetirse de una forma muy conocida. Un equipo crea una cuenta llamada `automation`, le concede permisos suficientes para desbloquear varios trabajos de programación y considera que la configuración es temporal. Meses después, un trabajo de despliegue, un actualizador de dependencias y un agente que modifica la infraestructura la usan. La cuenta sigue activa porque desactivarla podría romper algo. Cuando cambia una configuración de producción, los registros identifican perfectamente a `automation` y explican muy poco.

La solución no es un gran programa de identidad. Son unos pocos límites firmes: una identidad de flujo para un propósito de permisos, un propietario humano que pueda aprobarlo o detenerlo, pruebas que relacionen cada uso con una ejecución concreta y una vía de salida diseñada antes de conceder acceso a la cuenta.

## Una cuenta de servicio identifica la autoridad, no al actor

Una cuenta de servicio indica qué conjunto de permisos aceptó una API o un sistema; no demuestra qué agente, prompt, revisión del código o persona provocó la solicitud. Los equipos suelen mezclar estas dos funciones y luego descubren que su historial de auditoría no puede explicar un incidente.

Supón que `release-publisher` puede publicar artefactos de compilación. Una solicitud correcta autenticada como esa cuenta demuestra que se usó la autoridad de publicación. No indica si la solicitud la hizo un flujo de lanzamiento aprobado, si un desarrollador ejecutó un script local o si un agente reintentó una tarea antigua después de que su propietario humano se hubiera marchado. El registro de autenticación responde «¿qué autoridad?». No responde «¿por qué esta llamada, en esta ejecución y ahora?».

Mantén las capas separadas:

- La identidad del flujo contiene una autoridad definida de forma precisa.
- La sesión del agente identifica una ejecución concreta del proceso.
- La aprobación humana o el activador automático explican quién inició o permitió esa ejecución.
- El registro de la acción captura el objetivo, la operación solicitada, el resultado y la hora.

Esta distinción cambia la forma de investigar. Si una llamada de despliegue parece incorrecta, desactiva primero la identidad del flujo para detener nuevas acciones con esa autoridad. Después revisa el registro de sesión para encontrar el proceso que la usó, la revisión del código que ejecutó y la persona o sistema que autorizó la sesión. Un solo nombre de cuenta no puede contener todo ese historial sin convertirse en un contenedor compartido.

RFC 6749 hace una afirmación útil, aunque limitada, al describir la concesión de credenciales de cliente de OAuth 2.0: un cliente puede usar sus credenciales como concesión de autorización cuando actúa en su propio nombre. Eso es correcto para una carga de trabajo automática y delimitada. No significa que todo proceso capaz de presentar la credencial tenga el mismo propósito legítimo. El problema aparece cuando se trata la concesión como una atribución completa.

Un agente también tiene un perfil de riesgo diferente al de un trabajo convencional. Un trabajo convencional suele seguir una ruta de código fija. Un agente puede elegir comandos, construir solicitudes, reintentarlas con argumentos modificados o dejarse guiar por material que leyó en un repositorio. La cuenta de servicio sigue necesitando un propósito estable aunque varíen las decisiones del agente. Si no puedes escribir ese propósito en una sola frase sencilla, probablemente la cuenta ha acumulado trabajos que no guardan relación.

## Un flujo necesita una identidad delimitada

Un flujo merece su propia identidad cuando tiene un propósito, límite de permisos, propietario, entorno o condición de finalización distintos. No crees una cuenta para cada prompt o tarea breve. Eso produce ruido sin mejorar el control. Crea identidades al nivel en el que puedas revocar una unidad de autoridad sin detener trabajos que no tienen relación.

«Actualizar los manifiestos de dependencias en repositorios aprobados» y «publicar artefactos firmados en producción» no deberían usar la misma identidad. El primer flujo cambia archivos fuente y abre solicitudes de revisión. El segundo cambia un canal de lanzamiento. Aunque un mismo agente pueda iniciar ambos, los permisos son distintos, la persona que debería aprobarlos puede ser diferente y la respuesta ante una acción sospechosa también lo es.

El error contrario también hace perder tiempo: dividir un único flujo limitado en decenas de nombres de cuenta porque cada ejecución del agente crea uno. Los identificadores de ejecución ya describen ejecuciones breves. Las identidades de cuentas de servicio deben describir un propósito de autorización duradero. Usa registros de sesión para las ejecuciones individuales y cuentas para la autoridad que persiste entre ejecuciones.

Un patrón de nombres práctico es:

```text
<environment>.<product-or-repository>.<workflow-purpose>

prod.payments.release-publisher
dev.docs.dependency-updater
prod.data.backfill-reader
```

Los nombres ayudan a las personas, pero no aplican el alcance. Vincula cada identidad solo con las acciones que necesita su flujo. Concede al actualizador de dependencias permiso para crear una rama y enviar una solicitud de revisión si eso es todo lo que hace. No le concedas permisos de lanzamiento porque quizá algún día los necesite. Los «quizás» han creado más accesos permanentes que cualquier requisito real.

Usa identidades separadas para entornos distintos. Un agente de desarrollo puede ejecutar experimentos, reintentar de forma agresiva y trabajar con datos desechables. Ese comportamiento no corresponde a una identidad de producción. Copiar una credencial de producción en una configuración de desarrollo invierte el límite: el entorno menos controlado pasa a tener la autoridad más fuerte.

Hay una excepción legítima a la separación estricta: dos invocaciones pueden compartir una identidad cuando forman parte del mismo flujo documentado, tienen el mismo propietario, usan el mismo conjunto de permisos y terminan bajo la misma condición de retirada. La prueba es práctica. Si al desactivar la cuenta te preguntas «¿cuál de estos trabajos sin relación acaba de romperse?», la cuenta abarca demasiado.

## El propietario debe ser una persona capaz de detener el trabajo

Toda identidad de flujo necesita un propietario humano identificado que tenga la autoridad y la obligación de responder por ella. Un contacto técnico puede ayudar a operar el flujo y un equipo puede aportar continuidad, pero ninguno sustituye a un propietario concreto.

El propietario hace cuatro cosas concretas. Confirma que el flujo sigue teniendo un propósito, aprueba cambios en sus accesos, responde cuando aparece una llamada sospechosa y retira la identidad cuando termina el trabajo. Si la persona indicada no puede hacer esas tareas, el registro es decorativo.

NIST SP 800-53 Revision 5, control AC-2 sobre gestión de cuentas, exige que las organizaciones definan tipos de cuenta, establezcan condiciones para la pertenencia a grupos y roles y desactiven las cuentas cuando ya no estén asociadas a un usuario o dejen de ser necesarias. El control se aplica claramente a las cuentas no humanas, aunque muchas personas lo lean solo como una guía para cuentas de empleados. Una identidad de máquina sin un responsable que responda por ella no tiene a nadie que establezca esas condiciones o decida que ya no hace falta.

Coloca el registro de la cuenta en un repositorio o registro que use el proceso de revisión de accesos. No lo escondas en una página wiki que se aleje de la vinculación real. Este registro mínimo contiene suficientes campos para una revisión seria:

```yaml
identity: prod.payments.release-publisher
owner: "Morgan Lee"
technical_contact: "Release engineering on-call"
purpose: "Publish approved signed payment service artifacts to production"
allowed_actions:
  - "upload signed artifact to production release repository"
  - "read release metadata for the payment service"
environments:
  - production
permission_bindings:
  - "artifact-repository/publish-payments-prod"
credential_method: "short lived workload token"
source_repository: "payments-service"
review_after: "2026-06-30"
retire_when: "The payment service stops using this release workflow"
incident_contact: "Release engineering on-call"
```

El registro hace visible la ambigüedad. Si `allowed_actions` se convierte en un párrafo con varios sistemas y verbos vagos como «gestionar» o «administrar», divide el flujo. Si `retire_when` dice «nunca» o no tiene ninguna condición, la cuenta ha entrado en el montón de accesos permanentes. Si el campo del propietario contiene una lista de distribución, asigna una persona antes de conceder acceso.

Los cambios de propietario necesitan su propio control. Una persona que se marcha no debería seguir siendo la propietaria nominal porque transferir el registro parezca tedioso. Exige que el nuevo propietario acepte la cuenta, lea su propósito y sus vinculaciones y establezca la próxima fecha de revisión. Si nadie la acepta, desactívala. Los sistemas no quedan exentos de tener propietario solo porque sigan funcionando.

## Las cuentas compartidas convierten un incidente pequeño en un ejercicio de adivinación

Una cuenta compartida suele fallar con mayor claridad durante un incidente aparentemente rutinario, no durante una brecha espectacular. Imagina un equipo que usa `prod.agent-ops` para tres flujos: un agente de lanzamientos, un agente que resume incidentes y un agente de reparación de infraestructura. La cuenta puede leer el estado de los despliegues, modificar una variable de entorno y activar una reversión.

A las 16:20, alguien observa que una variable de entorno ha cambiado a un valor no válido. El registro de la API dice que la solicitud la hizo `prod.agent-ops`. El equipo de lanzamientos afirma que su ejecución había terminado antes. El equipo de incidentes dice que su agente estaba leyendo el estado, pero no cree que escriba configuraciones. El responsable de infraestructura dice que esa tarde se probó un prompt de reparación, pero nadie conservó la sesión exacta. Las tres afirmaciones pueden ser ciertas y el registro de la cuenta no puede resolver el conflicto.

La respuesta habitual consiste en buscar en mensajes de chat, historial del repositorio, historiales de shell y transcripciones del modelo. Puede que así aparezca una respuesta, pero el proceso es lento e incompleto. Además, la misma cuenta sigue activa porque desactivarla podría detener la recuperación del lanzamiento. El incidente ha unido la detección, la contención y operaciones de producción que no tenían relación.

Las identidades separadas cambian la secuencia. Si `prod.payments.release-publisher` hace una llamada inesperada, desactiva esa identidad. La cuenta del resumen de incidentes y la cuenta de reparación conservan sus propias autoridades. El registro de la acción debe incluir una identidad de flujo y una referencia de ejecución, para que los investigadores encuentren la sesión exacta sin discutir a partir de recuerdos. Por eso «una cuenta por equipo» no es un compromiso. Es una decisión de fusionar los dominios de fallo.

Algunos equipos defienden las cuentas compartidas porque centralizarlas facilita la rotación. Parece cierto porque solo hay que sustituir una credencial. El ahorro operativo es pequeño, mientras que el coste aparece cuando necesitas una revocación específica, una revisión de permisos o una explicación. Automatiza la emisión de credenciales y la gestión de vinculaciones en lugar de ampliar el límite de la cuenta hasta que resulte cómoda.

No confundas una cuenta compartida con un rol de permisos compartido. Varias identidades pueden recibir el mismo rol definido de forma precisa si realizan la misma operación permitida. Las identidades siguen siendo distintas, por lo que los registros y la revocación continúan funcionando. Reutilizar un rol facilita la gestión; reutilizar una identidad destruye la atribución.

## El alcance de los permisos debe seguir las acciones, no las ambiciones del agente

Concede acceso para la ruta de acción exacta que pretendes permitir y haz que el agente demuestre que necesita cualquier otra cosa. La capacidad general de un agente no justifica una autoridad general.

Empieza por los verbos y objetos del flujo. «Leer los problemas abiertos del repositorio A y crear una rama en el repositorio A» describe acciones. «Mantener el repositorio A» no. La primera frase permite encontrar un alcance de lectura y otro para crear ramas. La segunda suele terminar en un acceso de escritura amplio porque nadie puede convertirla en un permiso preciso.

La misma disciplina se aplica a los permisos de API. Si un flujo lee un informe y publica un comentario, no le concedas acceso a la gestión de cuentas porque la API agrupe esos endpoints en un rol amplio y atractivo. Crea un conjunto de permisos más pequeño si el proveedor lo permite. Si no lo permite, coloca delante de la credencial amplia un intermediario específico para esa acción o reconsidera si el agente debe realizarla sin supervisión.

Aquí muchos despliegues de agentes cometen un error sutil. Conceden acceso amplio porque el agente necesita inspeccionar el contexto antes de actuar. Leer el contexto y cambiar un objetivo son autoridades distintas. Concede acceso de lectura cuando sea posible y exige después una identidad o ruta de aprobación separada para los cambios de estado. Que un modelo pueda leer una configuración de producción no significa que necesite permiso para editarla.

Prueba el límite con solicitudes deliberadamente incorrectas antes de poner el flujo en uso habitual. Para un publicador de lanzamientos, intenta publicar un artefacto de otro producto, eliminar un lanzamiento y modificar la configuración del repositorio. Cada solicitud debería fallar en la capa de autorización. Una prueba correcta solo demuestra que concediste acceso suficiente. Las acciones adyacentes rechazadas demuestran que no concediste demasiado.

Conserva el resultado de la prueba junto con el registro de propiedad. Puede ser una tabla sencilla:

| Intento | Resultado esperado | Resultado de la revisión |
| --- | --- | --- |
| Publicar un artefacto de pagos aprobado | Permitido | Confirmado |
| Publicar un artefacto de otro servicio | Denegado | Confirmado |
| Eliminar un lanzamiento de producción | Denegado | Confirmado |
| Cambiar la pertenencia al repositorio | Denegado | Confirmado |

No permitas que un agente elija una identidad de un menú de cuentas potentes. El ejecutor del flujo debe asociar la identidad que corresponde al trabajo. Un agente que puede elegir entre autoridades sin relación a menudo puede rodear el límite que diseñaste.

## Las credenciales deben caducar antes que los flujos olvidados

Las credenciales de larga duración dificultan la retirada porque una copia olvidada puede seguir funcionando después de que desactives un trabajo visible. Prefiere credenciales de carga de trabajo de corta duración emitidas a un entorno de ejecución verificado, o haz que un componente controlado realice la acción autenticada mientras el agente recibe solo el resultado.

Este es un problema separado del diseño de identidades. Puedes tener una cuenta de servicio con un nombre impecable y un propietario claro, y aun así perder el control si su credencial está en un repositorio, un archivo de entorno local, una transcripción del agente o un registro de compilación. El registro de la cuenta indica quién puede usar la autoridad. La gestión de credenciales decide quién puede presentarla realmente.

La secuencia preferida es sencilla:

1. Verifica el entorno de ejecución o la sesión del agente que realiza la llamada.
2. Emite una credencial con caducidad breve y el alcance limitado del flujo, o ejecuta la acción solicitada en su nombre.
3. Registra la acción solicitada y la decisión de autorización.
4. Termina la sesión e invalida la autoridad que solo pertenece a esa sesión.

No entregues un secreto en texto plano al agente solo porque necesite llamar a una API. Así conviertes cada prompt, salida de herramienta, traza y registro accidental en una posible vía de distribución de credenciales. Ocultar los valores secretos en la salida de la consola ayuda después de una exposición, pero no evita que el agente los reciba y reutilice.

Sallyport sigue la segunda ruta en sus canales HTTP y SSH compatibles: el agente solicita una acción a través de su conexión MCP, mientras la aplicación mantiene las credenciales API y SSH en su bóveda cifrada y ejecuta la acción por sí misma. Esta configuración puede mantener las credenciales fuera del contexto del agente, pero no elimina la necesidad de diseñar identidades y propietarios separados para los flujos.

En los sistemas que deben usar una credencial directamente, registra dónde se emite, cómo se entrega, su duración máxima y quién puede revocarla. La rotación no debería depender de que alguien recuerde una fecha en el calendario. Incluye la emisión y sustitución en el proceso de despliegue del flujo y prueba una rotación antes de que la cuenta se vuelva importante.

Una credencial de corta duración no permite ignorar los registros. Un agente puede causar daños reales durante una sesión breve. La caducidad limita la persistencia después de un uso indebido; el alcance, la aprobación y el registro de acciones limitan lo que ocurre durante la sesión.

## Los registros de auditoría deben relacionar la autoridad con una ejecución concreta

Un historial de auditoría útil permite reconstruir una acción sin tratar la cuenta de servicio como toda la historia. Guarda en registros que puedan correlacionarse la identidad del flujo, el identificador de ejecución del agente, el activador inicial, la decisión de autorización, el objetivo, la operación, el resultado y la marca de tiempo.

Usa una estructura de eventos coherente. El siguiente JSON no depende de ningún proveedor, pero incluye los campos que normalmente se echan de menos después de un incidente:

```json
{
  "event_id": "act_01J8Q7M6K4",
  "time": "2026-04-14T16:20:31Z",
  "workflow_identity": "prod.payments.release-publisher",
  "run_id": "run_8f3c1d",
  "trigger": {
    "type": "approved_ci_job",
    "initiator": "morgan.lee",
    "source_revision": "a1b2c3d4"
  },
  "authorization": {
    "decision": "approved",
    "approved_by": "morgan.lee",
    "approval_ref": "apr_31fa"
  },
  "action": {
    "target": "production artifact repository",
    "operation": "publish",
    "resource": "payments-service/2.4.1"
  },
  "result": "success"
}
```

No introduzcas credenciales, prompts completos con material sensible ni cargas sin restricciones en un registro de auditoría solo porque quieras conservar detalles forenses. Registra el contexto estable suficiente para establecer la causalidad y aplica después las mismas reglas de tratamiento de datos que usarías para cualquier registro operativo. Un sistema de auditoría que se convierte en un segundo almacén de secretos crea su propia vía de incidentes.

La integridad también importa. Los registros que un agente o un flujo comprometido puede modificar no resuelven una disputa. Usa almacenamiento de solo anexado, separa los permisos de escritura de los permisos de lectura y administración y verifica la integridad periódicamente. Conserva las pruebas después de retirar una cuenta. La retirada elimina la autoridad futura, pero no debe borrar el historial necesario para explicar acciones pasadas.

Los diarios de sesiones y actividad de Sallyport se proyectan desde un registro de auditoría cifrado, encadenado mediante hashes y protegido contra escritura, y su comando `sp audit verify` comprueba esa cadena sin conexión y sin necesitar una credencial de la bóveda. Es una prueba útil para las acciones que intermedia, pero los sistemas que la rodean también deben conservar el propietario del flujo, el activador y el contexto de aprobación empresarial.

Diseña la revisión alrededor de preguntas que alguien pueda responder en minutos: ¿qué flujo tenía esta autoridad? ¿Quién era su propietario en ese momento? ¿Qué ejecución la usó? ¿Qué aprobó esa ejecución? ¿Qué operación exacta tuvo éxito o falló? Si alguna respuesta requiere reconstruir una historia a partir del historial de chat, tus registros están incompletos.

## La retirada es un flujo, no una tarea anual de limpieza

Retira una cuenta de servicio cuando termine su flujo, cuando no puedas sustituir a su propietario o cuando un cambio importante haga falso su propósito original. Las revisiones anuales detectan cuentas obsoletas, pero son demasiado lentas para eventos que ya conoces.

Incluye las condiciones de retirada en el registro original de la cuenta. Un flujo de migración puede retirarse cuando termina la migración. Una automatización de repositorio puede retirarse cuando se archiva el repositorio. Una integración con un proveedor puede retirarse cuando termina el contrato. Estas condiciones facilitan la decisión porque la cuenta ya tiene un final acordado.

Usa esta secuencia al retirar una identidad:

1. Desactiva el uso nuevo de la cuenta y revoca las credenciales o vinculaciones activas.
2. Observa los fallos esperados durante un periodo definido e identifica cualquier dependencia no documentada.
3. Restaura solo el acceso mínimo necesario para una dependencia verificada, con un nuevo propietario y un nuevo registro si el flujo sigue siendo legítimo.
4. Conserva el registro de propiedad, el historial de accesos y los registros de acciones según tus reglas de conservación.
5. Elimina la identidad y sus credenciales restantes cuando termine el periodo de observación.

No empieces eliminando la cuenta. La eliminación puede borrar configuraciones útiles y hacer más difícil diagnosticar los fallos. Desactivarla te proporciona contención y permite que la supervisión habitual revele quién la usa sin que esté documentado. También obliga a mantener una conversación útil: si se rompe un flujo, ¿quién se hace responsable y por qué no aparecía en el registro?

La marcha del propietario de una cuenta requiere atención inmediata. Antes de su último día, transfiere la propiedad solo después de que el sustituto acepte la responsabilidad. Si no existe un sustituto, desactiva la cuenta. Un equipo puede decidir reactivarla más adelante por una necesidad operativa documentada, pero una cuenta huérfana no debe conservar autoridad porque alguien quizá la necesite.

La retirada también se aplica cuando un flujo se amplía. Si un actualizador de dependencias empieza a desplegar código, no edites su propósito hasta que describa dos trabajos sin relación. Retira o reduce la identidad antigua y crea después una identidad de despliegue con su propio propietario, alcance, pruebas y registro de revisión. Así conservas el significado de auditoría de ambas cuentas.

## La responsabilidad solo sobrevive si las revisiones pueden revocar el acceso

Una revisión de cuentas de servicio solo tiene valor cuando los revisores pueden ver las vinculaciones reales, identificar al propietario actual y desactivar el acceso sin una semana de negociaciones. Incorpora esa autoridad al proceso operativo antes de necesitarla.

Revisa con más frecuencia los flujos de mayor riesgo, pero no conviertas cada revisión en un trámite de documentación. Pregunta si el propósito declarado sigue existiendo, si el propietario indicado conserva la autoridad, si las acciones recientes encajan con el propósito y si el alcance sigue correspondiendo al uso observado. Si la respuesta no está clara, reduce o desactiva la cuenta mientras el propietario lo aclara.

Mide la salud con hechos que revelen una autoridad descuidada: cuentas sin propietario, fechas de revisión vencidas, ausencia de historial de acciones durante un periodo relevante, credenciales próximas a superar o que ya superaron su duración prevista y flujos cuyas operaciones recientes quedan fuera del propósito documentado. Son colas de revisión, no métricas decorativas.

La primera acción práctica es exportar las identidades de agentes existentes y escribir una frase junto a cada una: «Este flujo puede hacer X para Y, tiene como propietario a Z y dura hasta la condición W». Las cuentas que se resistan a esa frase son las que contienen una responsabilidad compartida oculta. Desactívalas o divídelas antes de añadir más capacidades al agente.
