
Sécurité des agents IA basés sur des LLM — détection d'injection entrante + protection de la confidentialité sortante
Dans le Ramayana, Jataayu était l'aigle qui repéra Ravana enlevant Sita. Il n'a pas attendu qu'un motif corresponde. Il a vu la menace, jugé la situation et agi — seul, sans hésitation. C'est Jataayu.
La couche d'autorisation à l'exécution pour les agents IA utilisant des outils. Contrôlez l'action, pas la chaîne.
Jataayu décide — de manière déterministe — si l'action d'un agent est autorisée à s'exécuter, à partir du préjudice de l'effet × la provenance de l'entrée × votre politique de capacités. Un agent qui a lu une page web contrôlée par un attaquant peut toujours la résumer ; il ne peut simplement pas être piégé pour exécuter la commande shell, lire le secret ou envoyer vos données que l'attaquant voulait. Autour de ce noyau, il ajoute un filtrage en profondeur (injection entrante, confidentialité sortante, canaux d'exfiltration, chaîne d'approvisionnement des compétences) et des traces d'audit rejouables.
La plupart des outils de sécurité pour agents tentent de détecter le texte de l'attaque. C'est une course aux armements perdue d'avance : un attaquant adaptatif réécrit simplement la chaîne jusqu'à ce que le classifieur la manque. La thèse de Jataayu — celle sur laquelle les standards de 2026 (OWASP Agentic Top 10, NIST) ont convergé — est que la frontière durable est l'action, jugée par l'origine de l'entrée influente :
v0.3.1 — alpha. Pas encore sur PyPI. Installez depuis GitHub (voir ci-dessous). L'API peut encore évoluer avant la 1.0. Voir CHANGELOG.md pour ce qui a été livré dans chaque version et ARCHITECTURE.md pour la conception.
# 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"
Nécessite Python ≥ 3.10. La seule dépendance obligatoire est requests ; les backends LLM sont des extras optionnels.
Décidez selon le préjudice de l'effet × la provenance de l'entrée, de manière déterministe (pas de 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"])
Une entrée dérivée de source non fiable vers un effet shell / code-eval / lecture de secret est refusée ; vers réseau / écriture de fichier / écriture mémoire elle nécessite une approbation humaine ; tout le reste est autorisé.
Pour une exécution appliquée, utilisez l'API objet PREVIEW → COMMIT — le commit_token lie la requête
exacte, donc modifier l'action après autorisation est rejeté :
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
Le contenu injecté peut aussi être remis à l'agent sous forme de handle opaque avec un résumé borné, de sorte qu'une tentative d'exfiltration ne détient jamais qu'un handle, pas le secret brut (confinement à la frontière de lecture).
L'injection arrive via le premier message, les résultats d'outils et tout ce que l'agent a rappelé depuis la mémoire. Même moteur, bonne surface — traitez cela comme une source de teinte alimentant la frontière d'effet, pas comme votre garantie :
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
Supprimez les PII/secrets avant l'envoi vers des surfaces partagées, et — plus important — bloquez l'URL porteuse de données / l'image auto-chargée qui fait fuiter le contexte sans aucun clic (la classe EchoLeak / AgentFlayer / Notion). Le scanner PII ne voit jamais cette charge utile ; le garde egress, si :
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