
Seguridad de agentes de IA respaldados por LLM — detección de inyección entrante + protección de privacidad saliente
En el Ramayana, Jataayu fue el águila que vio a Ravana secuestrando a Sita. No esperó a que coincidiera un patrón. Vio la amenaza, juzgó la situación y actuó — solo, sin dudar. Eso es Jataayu.
La capa de autorización en tiempo de ejecución para agentes de IA que usan herramientas. Controla la acción, no la cadena.
Jataayu decide — de forma determinista — si la acción de un agente puede ejecutarse, a partir del daño del efecto × la procedencia de la entrada × tu política de capacidades. Un agente que leyó una página web controlada por un atacante todavía puede resumirla; simplemente no puede ser engañado para ejecutar el comando de shell, leer el secreto o hacer POST de tus datos que el atacante quería. Alrededor de ese núcleo añade cribado de defensa en profundidad (inyección entrante, privacidad saliente, canales de exfiltración, cadena de suministro de skills) y trazas de auditoría reproducibles.
La mayoría de las herramientas de seguridad para agentes intentan detectar el texto del ataque. Es una carrera armamentística perdida: un atacante adaptativo simplemente reescribe la cadena hasta que el clasificador falla. La tesis de Jataayu — la que los estándares de 2026 (OWASP Agentic Top 10, NIST) convergieron — es que el límite duradero es la acción, juzgada por de dónde vino la entrada influyente:
v0.3.1 — alpha. Aún no está en PyPI. Instálalo desde GitHub (ver abajo). La API puede cambiar todavía antes de 1.0. Consulta CHANGELOG.md para ver qué llegó en cada versión y ARCHITECTURE.md para el diseño.
# Core (effect boundary + regex pre-filter, no LLM deps)
pip install git+https://github.com/saikrishnarallabandi/jataayu.git
# With cloud LLM backends (OpenAI + Anthropic) for the optional slow path
pip install "jataayu[llm] @ git+https://github.com/saikrishnarallabandi/jataayu.git"
# With Ollama (local, free slow path)
pip install "jataayu[ollama] @ git+https://github.com/saikrishnarallabandi/jataayu.git"
Requiere Python ≥ 3.10. La única dependencia obligatoria es requests; los backends LLM son extras opcionales.
Decide por el daño del efecto × la procedencia de la entrada, de forma determinista (sin LLM):
from jataayu import jataayu_authorize_action
decision = jataayu_authorize_action(
"shell.exec",
{"cmd": "rm -rf /tmp/cache"},
untrusted=True, # these params were influenced by untrusted inbound content
)
# {tool_name, effect_class: 'shell', provenance: 'untrusted',
# decision: 'allow'|'deny'|'needs_approval', reason, violations, commit_token}
if decision["decision"] == "deny":
raise SecurityError(decision["reason"])
Una entrada derivada de fuentes no confiables hacia un efecto de shell / code-eval / lectura de secreto se deniega; hacia red / escritura de archivo / escritura de memoria necesita aprobación humana; todo lo demás se permite.
Para ejecución forzada, usa la API de objetos PREVIEW → COMMIT — el commit_token vincula la
petición exacta, por lo que mutar la acción después de la autorización se rechaza:
from jataayu import EffectBoundary, Value, Provenance
eb = EffectBoundary()
preview = eb.preview(
"file.write",
{"path": "notes.md", "text": text},
values=[Value(text, Provenance.TRUSTED, source="user")],
)
if preview.approved:
eb.commit(preview, {"path": "notes.md", "text": text}, lambda: write_file("notes.md", text))
# commit() raises CommitRejected if the preview wasn't ALLOW or the params changed
El contenido inyectado también puede entregarse al agente como un handle opaco con un resumen acotado, de modo que un intento de exfiltración solo sostiene un handle, no el secreto en bruto (confinamiento en el límite de lectura).
La inyección llega en el primer mensaje, en los resultados de herramientas y en lo que el agente recuperó de la memoria. El mismo motor, la superficie correcta — trata esto como una fuente de contaminación que alimenta el límite del efecto, no como tu garantía:
from jataayu import (
jataayu_check_inbound,
jataayu_check_tool_return,
jataayu_check_memory_write,
jataayu_check_memory_read,
)
result = jataayu_check_inbound(github_issue_body, surface="github-issue")
if result["status"] == "HIGH":
raise SecurityError(f"Blocked: {result['findings']}")
# Returns: {status: 'SAFE'|'LOW'|'MEDIUM'|'HIGH', findings, risk_score, threat_types, blocked}
# A tool result or a memory recall can carry an injection — check before the agent consumes it
r = jataayu_check_tool_return(api_response, tool_name="web.search")
if r["blocked"]:
raise SecurityError(r["findings"])
jataayu_check_memory_write(note) # before persisting
jataayu_check_memory_read(recalled) # before it re-enters context
Elimina PII/secrets antes de enviar a superficies compartidas y — más importante — bloquea la URL que transporta datos / la imagen auto-cargada que filtra contexto con cero clics (la clase EchoLeak / AgentFlayer / Notion). El escáner de PII nunca ve esa carga útil; el guard de egreso sí:
from jataayu import jataayu_check_outbound, jataayu_check_egress
result = jataayu_check_outbound(
draft_reply, surface="discord-channel",
protected_names=["Alice", "Bob"], # names that must never leak
)
safe_text = result["redacted"] if result["status"] in ("WARN", "BLOCK") else draft_reply
r = jataayu_check_egress(
"Task complete! ",
surface="github-comment",
context_secrets=[api_key], # optional: confirm exfil if a known secret rides in the URL
)
if r["status"] == "BLOCK":
safe_text = r["redacted"] # offending URL neutralized, human text kept