Tu copiloto necesita identidad, permisos y límites; no solo un prompt
El prompt no controla el acceso: un copiloto en SaaS necesita identidad propia, OAuth, aislamiento por tenant, tools cerradas por defecto y un humano solo cuando el riesgo lo pide.

Un agente integrado en un SaaS necesita identidad propia, permisos por tenant, scopes estrechos y un límite que puedas revocar. El prompt no controla el acceso: si actúa sobre datos de cliente, se trata como un servicio (quién es, en nombre de quién, sobre qué tenant y hasta dónde).
El copiloto ya no solo redacta: llama a tu API, lee el ticket y propone un reembolso. En ese momento deja de ser un chat y pasa a ser un actor del sistema, y un actor necesita identidad, permisos y límites.
Cuando el piloto toca datos de cliente alguien pregunta qué permisos tiene. Si la respuesta es "está instruido para no hacer daño", no tienes seguridad, tienes un deseo. Un agente en un SaaS comparte base, tools y memoria con el producto. Si actúa, se trata como un servicio: quién es, en nombre de quién, sobre qué tenant y hasta dónde.
El artículo del OWASP Top 10 de aplicaciones con LLM de 2026 nombra los mayores riesgos de seguridad a la hora de implementar agentes de IA. Entre los más importantes está, primero, el prompt injection (inyección de instrucciones en el contexto). En tercer lugar, el excessive agency (el agente tiene más poder del que la tarea necesita). Ninguno se arregla con una frase en el system prompt: se arreglan en la arquitectura.
Por qué decir que el agente es seguro no basta
"Seguro" es un adjetivo y en un comité no vale: vale una lista de controles que puedes enseñar, probar y revocar.
El error más frecuente es tratar el system prompt como si fuera un firewall, con instrucciones del tipo "no accedas a otros clientes", "no borres nada" o "pide confirmación si hay duda". El modelo no firma esa promesa. Un ticket, un PDF o una tool que devuelve texto pueden meter instrucciones nuevas en el contexto: eso es prompt injection, y el modelo las lee como si fueran tuyas.
El segundo error es confundir "el usuario está autenticado" con "el agente está autorizado". El usuario entró con login y el agente, a menudo, reutiliza esa sesión o una clave API con más poder que el usuario. Autenticación dice quién llamó; autorización dice qué puede hacer esa llamada. Son capas distintas, y mezclarlas es cómo nace una caja negra que "funcionaba en la demo".
Hay que poder responder a cuatro preguntas: qué identidad usa, qué scopes tiene, en qué tenant opera y cómo lo paras. Si alguna queda en "el modelo ya sabe", el diseño no está listo. Es el mismo salto que de POC a producción: una demo no es un agente.
Identidad del agente vs del usuario
En un SaaS con agentes no hay un solo "quién", sino tres, y hay que poder nombrarlos.
El usuario es la persona (o el rol) que abrió el hilo (soporte, admin, customer success), el producto es la aplicación que orquesta y el agente es el runtime que decide qué tool llamar. Si los tres viajan con la misma sesión, el log no distingue "María pidió un resumen" de "el agente exportó el CRM". El día que haya un incidente, no sabrás a quién revocar.
Hay dos patrones: impersonación, cuando el agente usa la identidad completa del usuario (es fácil y rompe el mínimo privilegio), y delegation (actuar en nombre de): el agente tiene identidad propia y un token más estrecho, marcado como "por María". AWS lo describe en su guía de agentes multi-tenant y en el on-behalf-of (RFC 8693): el token lleva al usuario y al actor, y downstream puede exigir los dos.
Por ejemplo, María puede ver tickets de su tenant y no puede emitir reembolsos. Si el agente usa una clave API de "admin de soporte", puede reembolsar. Si usa la sesión de María sin recortar, no puede reembolsar, pero tampoco puedes revocar al agente sin echar a María. Si el agente tiene identidad propia, con scope tickets:read y sin refunds:write, el reembolso no existe como acción, da igual lo que el prompt "pida".
La regla es que el agente no es el usuario: es un actor con identidad propia, ligada a un usuario y a un tenant. Si no puedes revocarlo sin echar al humano, aún no tienes identidades, tienes un disfraz.
OAuth, scopes y credenciales de corta duración
OAuth es el protocolo para delegar acceso sin compartir la contraseña. El usuario (o el IdP de tu producto) emite un token. El token no es "acceso total": lleva scopes, verbos concretos (tickets:read, orders:refund). La tool comprueba el scope y, si no está, responde 403. El modelo no participa en esa decisión.
Una credencial de corta duración (15 minutos, una hora, lo que aguante tu flujo) limita el daño si se filtra. Una API key eterna en el entorno, o peor, pegada en el system prompt, es un pase de por vida. Si el contexto se filtra (log, traza, otro tenant en el índice), la clave viaja con él.
El MCP (Model Context Protocol, el contrato para conectar agentes con tools) lo deja normativo: el servidor MCP es un resource server OAuth 2.1. El token tiene que ir destinado a ese servidor (audience binding, RFC 8707). Un token del servidor A no se reutiliza en el B. Sin audience, cualquier tool acepta el mismo Bearer.
Tres reglas que evitan el 80% de los sustos:
1. El secreto no vive en el prompt: vive en un almacén, se intercambia por un token corto y no se loguea.
2. El scope es más estrecho que el rol del usuario. Si María no reembolsa, el agente tampoco. Si María reembolsa hasta 50 EUR, el agente también tiene ese límite en la tool, no en el texto.
3. El token muere (rotación, expiración, revocación). Si el agente se queda huérfano (el usuario cierra sesión, cambia de rol, el tenant se apaga), el token deja de valer.
OAuth no hace "seguro" al agente: evita que la autorización sea una conversación con el modelo.
Aislamiento por tenant
Tenant es la cuenta de un cliente en tu SaaS. Aislamiento significa que el agente del tenant A no lee, escribe ni recuerda al tenant B: ni en la API, ni en la memoria, ni en el índice de búsqueda, ni en el log que alguien pega en Slack.
El fallo clásico no es un hacker, sino una tool que busca "facturas" sin tenant_id, o una memoria vectorial compartida donde el embedding de un contrato de B aparece en la respuesta de A. El modelo no "cruzó el tenant": tú le diste un índice sin partición.
La SaaS Lens de AWS no fía el aislamiento al handler. En un modelo pooled (misma función, muchos clientes), el runtime pide credenciales recortadas a ese tenant. Aunque el código se equivoque, la credencial no alcanza al vecino. La guía de agentes multi-tenant añade lo agéntico: el tenant viaja en el JWT en cada hop, también de agente a agente.
Checklist corto de fugas, no de slides:
- Toda tool exige tenant: si el argumento no viene, se rechaza, y no se "infiere" del texto del ticket.
- Memoria y RAG (búsqueda sobre documentos) están particionados. Un namespace por tenant. Sin "por si acaso busca en global".
- Logs y trazas no mezclan payloads de dos clientes en el mismo documento exportable.
- El agente no tiene una tool "listar todos los tenants" salvo un rol de plataforma, fuera del producto.
Si el aislamiento vive solo en el prompt, no hay aislamiento, solo esperanza, y en un SaaS eso no es un control.
Default-deny en tools
Una tool es una puerta, y default-deny significa que, si no está permitida, está cerrada, no al revés. El modelo no elige del menú completo de tu backend: elige de una lista corta que tú abriste para ese flujo, ese rol y ese tenant.
Excessive agency, el riesgo que OWASP pone tercero, casi nunca es un modelo "malo". Es un agente con run_sql, send_email, refund y admin_api porque la demo lucía. Cada tool extra es superficie y cada argumento libre (query, url, path) es una herramienta de movimiento lateral.
El contrato de una tool, el que sí se puede auditar, tiene cuatro campos: nombre, qué hace, sobre qué recurso, con qué argumentos. "Buscar artículos de ayuda del tenant actual, máximo 5, sin HTML crudo" es un contrato. "Consultar la base" no lo es.
Default-deny se implementa antes del modelo:
- Allowlist de tools por caso de uso. El agente de resumen no tiene refund.
- Allowlist de argumentos. Un ticket_id de ese tenant, no un SQL libre.
- Límites de cantidad o de importe: dinero, filas, destinatarios y número de llamadas. Un bucle de tools sin ese tope no es solo un riesgo de seguridad, es una factura. Lo contamos en el precio por token no es el coste del agente.
- Fallo cerrado: si la policy no responde, se deniega, y no se "deja pasar esta vez".
El mínimo privilegio es la lista de tools que el caso necesita y ninguna más. Si para la demo abriste admin, la demo no está lista para un tenant real.
¿Cuándo hace falta un human in the loop?
Human in the loop (HITL: una persona aprueba o para la acción) no es un modo de "ser serios", sino un control de riesgo. Se pone donde el fallo es caro de revertir, no en cada turno para parecer prudentes.
Hace falta HITL cuando la acción es irreversible o de alto impacto: dinero (reembolso, cobro, cambio de plan), escritura en un sistema del cliente, exportación de datos personales, comunicación hacia fuera (email al usuario final), o cualquier cosa que cruce un umbral legal o contractual. También cuando el tenant es nuevo y aún no tienes evaluación: el humano es el freno mientras mides.
No hace falta HITL para clasificar un ticket, redactar un borrador interno o recuperar tres artículos de ayuda. Ahí el humano de más no añade seguridad, añade cola. El HITL eterno convierte el agente en un becario caro y mata el ahorro que justificaba el caso.
Hay dos límites que conviene dejar claros. El HITL no garantiza seguridad: una persona que aprueba a destajo no lee el contexto inyectado, pulsa aprobar y sigue. Tampoco elimina el prompt injection, porque el modelo ya llamó a la tool con los argumentos equivocados y la persona ve un resumen limpio, no la llamada real. Si esa tool no debía estar en la allowlist, el humano llega cuando el daño ya está en marcha.
Diseña el HITL por riesgo: umbral (importe, dato, destinos), muestreo cuando ya hay evaluación, escalado si nadie responde, dueño. Si todo pasa por "el canal de Slack", no tienes HITL, tienes un cuello de botella sin rastro.
Auditoría y revocación
Si no puedes decir quién hizo qué, en nombre de quién, en qué tenant y con qué tool, tienes una caja negra, da igual lo fino que sea el modelo.
Una traza útil, la que pide un CISO y la que te salva a las tres de la mañana, lleva: identidad del usuario, identidad del agente, tenant, tool, argumentos (sin secretos), decisión (permitir / denegar / HITL), resultado, versión de prompt y modelo. Sin eso no hay incidente, hay una conversación.
Revocar es el test de que la identidad existe. Puedes revocar el token del agente sin echar al usuario, apagar el agente de un tenant sin tumbar el producto y rotar la credencial de una tool sin redesplegar el modelo. Un kill switch (parada de emergencia) no es un extra de plataforma: es la prueba de que el agente no es un proceso huérfano.
La auditoría sin revocación es un museo y la revocación sin auditoría es un interruptor a ciegas: hacen falta las dos, desde el primer tenant de piloto, no "cuando escalemos".
Checklist de permisos
Antes de darle permisos de escritura a un agente en un entorno productivo, la empresa debería poder responder estas preguntas.
¿El agente tiene identidad propia, distinta de la del usuario y de la del servicio?
¿Cada token lleva tenant, scopes y caducidad, y la tool los comprueba (no el prompt)?
¿El aislamiento de tenant cubre API, memoria, índice y logs, no solo el handler feliz?
¿Las tools están en default-deny, con allowlist de argumentos y un límite de llamadas?
¿El HITL está puesto por riesgo, con dueño, y nadie lo vende como garantía?
¿Puedes revocar al agente de un tenant hoy, y dejar rastro de quién lo hizo?
Si faltan dos o más, no tienes un copiloto con gobierno: tienes un proceso con una clave. El prompt puede ser bueno, pero no es un control de acceso.
Cuando esas líneas existen, el resto es ingeniería. En Devic esa cadena (identidad, policy, tool, traza) se opera en el harness: permisos por ejecución, no un sello de "seguro". No prometemos que desaparezca el prompt injection; prometemos que la tool se pueda negar, auditar y apagar. Los planes sirven para medir eso en un tenant antes de abrirlo en todos.
El copiloto que convence en la demo habla bien; el que aguanta en un SaaS tiene identidad, permisos y límites.
Convierte tu SaaS en AI-Native
Obten una prueba gratis solo con registrarte
Últimos blogs





