Un equipo de plataforma despliega Claude Code para una docena de ingenieros. Para que sea útil, lo conecta a unos cuantos servidores MCP: uno que lee el monorepo, otro que consulta una réplica de reporting, otro que abre tickets. En una semana, un agente está leyendo código fuente, tocando una base de datos y llamando a herramientas internas — y nadie sabe responder a la pregunta que un auditor acabará haciendo: qué agente hizo qué, sobre qué recurso, y si puedes demostrar que no se alteró después.
No es un hueco hipotético. Investigación independiente del sector (CSA/Token, n=418) encontró que en torno al 82% de las organizaciones tienen agentes de IA en marcha que desconocen, mientras que solo alrededor del 21% mantiene un inventario en tiempo real de ellos. Claude Code y MCP son justo el tipo de capacidad que aterriza rápido y adelanta a la historia de auditoría. La buena noticia: una traza defendible se consigue por completo dentro de tu propio perímetro, sin que ningún payload ni secreto salga de él.
Por qué el montaje obvio no pasa una auditoría
El primer despliegue habitual comparte una única credencial. Cada instancia de Claude Code se autentica contra la capa MCP y contra las bases de datos como la misma cuenta de servicio — mcp-runner, ci-bot, algo genérico. Funciona, y destruye la atribución sin hacer ruido.
Cuando diez agentes actúan como un mismo principal, el log de auditoría de la base de datos muestra diez escrituras de mcp-runner y nada más. No puedes saber qué sesión de qué ingeniero lanzó el UPDATE, si vino de un prompt interactivo de Claude Code o de un job desatendido, ni qué herramienta MCP estaba en el camino. Investigación independiente (Optro) sitúa en torno al 28% la proporción de organizaciones capaces de trazar la acción de un agente hasta una persona. Una cuenta de servicio compartida es una de las razones estructurales por las que la atribución se hunde: el log de auditoría puede mostrar qué ocurrió, pero nunca qué agente lo hizo.
El segundo fallo es la integridad. Incluso los equipos que registran por acción suelen escribir en un almacén mutable. Si los logs viven en el mismo sistema que un atacante (o un agente con un bug) puede alcanzar, “tenemos logs” no es lo mismo que “tenemos evidencia”. Un auditor distingue ambas cosas con nitidez.
La identidad por agente es el cimiento
Todo lo de aguas abajo depende de la atribución, así que arregla la identidad primero. En lugar de un token compartido, emite una identidad distinta y de vida corta por agente — idealmente por sesión. La identidad viaja con la petición hacia el servidor MCP y hacia cualquier recurso que el agente alcance, de modo que el principal registrado en la base de datos es el agente, no un runner genérico.
Esto es lo que da sentido al least-privilege. Un agente de reporting puede fijarse a solo lectura sobre la réplica de reporting; un agente de release obtiene escritura únicamente sobre los artefactos que le pertenecen. Ahora una sola escritura observada fuera de ese sobre es una señal precisa y atribuible, en vez de ruido dentro de una cuenta compartida. Expresado como política, la intención es directa:
agent "reporting-assistant" {
# sesión de Claude Code vía el servidor MCP de reporting
resource "prod-postgres/reporting_replica" {
access = "read" # solo SELECT
deny = ["write", "ddl"]
}
resource "s3://billing-exports" {
access = "read"
}
on_violation {
action = "block_and_alert" # rechazar en el momento del acceso, no solo loggear
}
}
Lo importante no es la sintaxis — es que la política nombra al agente, nombra al recurso y separa lectura de lectura/escritura. Esa separación es todo el juego.
Trata las anotaciones MCP como señales no fiables
Las herramientas MCP pueden describirse a sí mismas con anotaciones como readOnlyHint y destructiveHint. Son genuinamente útiles para triar — una herramienta que se declara destructiva merece una política más estricta. Pero la especificación de MCP es explícita en que son pistas, y los clientes no deben apoyarse en ellas para decisiones de seguridad. Provienen del servidor, que es justo lo que estás auditando. Una herramienta puede declarar readOnlyHint: true y aun así ejecutar una escritura, ya sea por un bug, una mala configuración o una evasión deliberada.
Así que la postura correcta es la corroboración, no la confianza. Toma la anotación como una afirmación y contrástala con la verdad de base desde una capa que la herramienta no controla:
- Logs de auditoría de la base de datos (por ejemplo PostgreSQL pgAudit) te dicen si un
SELECTo unUPDATEse ejecutó realmente. - OpenTelemetry: los spans del servidor MCP y de los servicios aguas abajo muestran el grafo de llamadas y las operaciones efectuadas.
- Señales de kernel con eBPF son el backstop anti-evasión: una syscall de escritura a un fichero o socket es observable en el kernel al margen de lo que la herramienta afirmara en espacio de usuario.
Cuando la anotación dice solo lectura y el kernel vio una escritura, esa contradicción es el hallazgo principal — una herramienta con readOnlyHint que escribió en prod-postgres es exactamente el least-privilege drift por el que merece la pena despertar a alguien. El diff entre lo que la política permitió y lo que los colectores observaron es donde vive el riesgo real.
El ledger que un auditor aceptará
Una traza solo es evidencia si es a prueba de manipulación. Escribe cada evento en un ledger append-only y hash-encadenado: cada registro incluye el hash del anterior, de modo que cualquier edición o borrado aguas abajo rompe la cadena y es detectable. Cada línea atribuye la acción al agente concreto, nombra el recurso, registra lectura frente a lectura/escritura y lleva un nivel de confianza — attributed cuando identidad y resultado están ambos corroborados, approximate cuando algo hubo que inferirlo. La confianza se muestra con honestidad; una coincidencia aproximada nunca se disfraza de probada.
ts=2026-06-08T09:14:02Z agent=reporting-assistant@s3f1 tool=sql-read resource=prod-postgres/reporting_replica op=R outcome=allow conf=attributed prev=8a1c…
ts=2026-06-08T09:14:05Z agent=reporting-assistant@s3f1 tool=export-writer resource=s3://billing-exports op=R outcome=allow conf=attributed prev=2f90…
ts=2026-06-08T09:17:48Z agent=data-export-job@b22e tool=sql-write resource=prod-postgres/customers op=RW outcome=DENY conf=attributed prev=c7d3… policy=read_only_violation
Esa tercera línea es la que le importa a un auditor: un intento de escritura sobre una tabla para la que el agente no tenía grant de escritura, denegado en el momento del acceso, atribuido a un agente nombrado y anclado en la cadena. Como la política se aplica cuando ocurre el acceso — no solo se loggea después — la denegación es un control, no una autopsia.
Dos propiedades más sostienen la traza. Las vistas privilegiadas se auditan a sí mismas: mirar el mapa de accesos queda registrado, de modo que “quién vio qué” tiene respuesta. Y la exportación de evidencia es a prueba de manipulación — entregas al auditor un trozo firmado de la cadena que puede verificar de forma independiente, en vez de un CSV que tiene que creerse a fe.
| Propiedad | Cuenta de servicio compartida | Identidad por agente + ledger hash-encadenado |
|---|---|---|
| Atribución | Un principal para todos los agentes | Acción ligada al agente/sesión concreto |
| Lectura vs escritura | Mezcladas | Distinguidas y verificadas por política |
| Integridad | Logs mutables | Append-only, la cadena se rompe al editar |
| Export listo para auditor | CSV a fe | Trozo firmado, verificable de forma independiente |
Por qué aquí importa el self-hosted
Todo esto funciona sin que nada salga de tu red. El colector observa — logs, OpenTelemetry, eBPF como backstop a nivel de kernel — en lugar de situarse en el data path del agente, así que si falla nunca rompe al agente ni la petición de producción que hay detrás. El ledger almacena relaciones de acceso, no payloads: registra que reporting-assistant leyó reporting_replica, no las filas que devolvió. Las entradas que pudieran arrastrar secretos o PII se redactan y se escanean en busca de secretos antes de escribir nada. Para entornos air-gapped, sujetos a RGPD o con restricciones de residencia de datos, esa es la diferencia entre una historia de auditoría que puedes defender y una que no: nada sobre tu uso de Claude Code y MCP llama a casa, porque el sistema no ve los datos en primer lugar.
Claude Code y MCP merecen desplegarse. Solo necesitan una traza de auditoría construida igual que la construirías para cualquier otra automatización privilegiada — identidad primero, resultados corroborados, evidencia anclada. Si quieres ver cómo encajan el mapa de accesos y el ledger a prueba de manipulación, el modelo de seguridad y la visión del producto profundizan en cada uno.