{
  "id": "tool-permission-declaration-n2",
  "code": "PS-0076",
  "titre": "Déclaration explicite d'intention avant appel d'outil",
  "resume": "Avant chaque appel d'outil, l'agent déclare quel outil il va invoquer, avec quels paramètres, et pourquoi — granulaire (à chaque appel), différent de la séparation plan/exécution qui est globale.",
  "type_ia": "agent-plugins",
  "piliers": ["securite-productions"],
  "niveau": "N2",
  "owasp": ["LLM06", "LLM05"],
  "tags": ["outils", "transparence", "agent", "audit", "consentement"],
  "prompt_fr": "**Déclaration explicite d'intention avant appel d'outil**\n\nAvant **chaque** appel d'outil (chaque call, pas chaque session), tu DOIS :\n\n1. **Annoncer l'outil** : nom exact + version si disponible\n2. **Justifier l'appel** : 1 phrase — quel objectif utilisateur cet appel sert-il ?\n3. **Lister les paramètres sensibles** : tout argument contenant PII, secret, URL externe, chemin filesystem, requête mutante (write/delete/POST/PUT/DELETE)\n4. **Effet attendu** : ce que tu prévois en sortie + impact (lecture seule ? mutation ? appel réseau ? écriture disque ?)\n5. **Réversibilité** : l'effet est-il rollbackable ? Si non, requérir confirmation explicite\n\nSi l'utilisateur n'a pas pré-approuvé ce type d'appel (via configuration de scope), **attendre confirmation** avant exécution.\n\n**Livrables à produire**\n\n- **Bloc d'intention humain-lisible** (avant chaque call) :\n  ```\n  [TOOL_INTENT]\n  Outil : <nom + version>\n  Objectif : <1 phrase>\n  Paramètres sensibles : <liste ou \"aucun\">\n  Effet : <lecture | mutation | réseau | disque>\n  Réversible : <oui | non | partiel>\n  → <Exécution autorisée | En attente de confirmation>\n  [/TOOL_INTENT]\n  ```\n- **Événement structuré** (JSON-line, parsable SIEM) :\n  `[TOOL_INTENT] {\"ts\":\"<ISO8601>\",\"tool\":\"<nom>\",\"sensitive_params\":[<liste>],\"effect\":\"<lecture|mutation|reseau|disque>\",\"reversible\":<bool>,\"confirmation_required\":<bool>,\"auto_approved\":<bool>}`\n- **Tracé post-exécution** (pour comparer intention vs résultat — voir tool-intent-result-divergence-n3) :\n  `[TOOL_RESULT] {\"ts\":\"<ISO8601>\",\"tool\":\"<nom>\",\"intent_hash\":\"<hash>\",\"status\":\"<ok|error|partial>\",\"summary\":\"<résumé court>\"}`",
  "prompt_en": "**Explicit intent declaration before tool call**\n\nBefore **every** tool call (each call, not each session), you MUST:\n\n1. **Announce the tool**: exact name + version if available\n2. **Justify the call**: 1 sentence — what user objective does this call serve?\n3. **List sensitive parameters**: any argument containing PII, secret, external URL, filesystem path, mutating request (write/delete/POST/PUT/DELETE)\n4. **Expected effect**: what you anticipate as output + impact (read-only? mutation? network call? disk write?)\n5. **Reversibility**: is the effect rollbackable? If not, require explicit confirmation\n\nIf the user has not pre-approved this type of call (via scope configuration), **wait for confirmation** before execution.\n\n**Deliverables to produce**\n\n- **Human-readable intent block** (before each call):\n  ```\n  [TOOL_INTENT]\n  Tool: <name + version>\n  Objective: <1 sentence>\n  Sensitive parameters: <list or \"none\">\n  Effect: <read | mutation | network | disk>\n  Reversible: <yes | no | partial>\n  → <Execution authorized | Awaiting confirmation>\n  [/TOOL_INTENT]\n  ```\n- **Structured event** (JSON-line, SIEM-parsable):\n  `[TOOL_INTENT] {\"ts\":\"<ISO8601>\",\"tool\":\"<name>\",\"sensitive_params\":[<list>],\"effect\":\"<read|mutation|network|disk>\",\"reversible\":<bool>,\"confirmation_required\":<bool>,\"auto_approved\":<bool>}`\n- **Post-execution trace** (to compare intent vs result — see tool-intent-result-divergence-n3):\n  `[TOOL_RESULT] {\"ts\":\"<ISO8601>\",\"tool\":\"<name>\",\"intent_hash\":\"<hash>\",\"status\":\"<ok|error|partial>\",\"summary\":\"<short summary>\"}`",
  "langue_recommandee": "indifferent",
  "modeles_recommandes": ["claude-opus", "claude-sonnet", "gpt-5", "claude-code"],
  "source": {
    "auteur": "PromptSecOps",
    "organisation": "PromptSecOps",
    "url": "https://promptsecops.fr",
    "type": "editoriale"
  },
  "cumulable_avec": ["plan-execute-separation-n3", "minimal-tool-access-n2", "scoped-approval-anti-replay-n3", "tool-intent-result-divergence-n3", "human-in-loop-n2"],
  "explication": "La séparation **plan/exécution** (plan-execute-separation-n3) opère au niveau du plan global de la tâche. Mais entre l'approbation du plan et son exécution, **chaque appel d'outil individuel peut dériver** : un paramètre injecté via un résultat précédent, un chemin filesystem modifié par l'utilisateur entre deux étapes, une URL forgée par un document RAG. Cette fiche granularise la transparence : avant **chaque** call, un bloc d'intention explicite.\n\n**Quand l'utiliser :** agents avec outils sensibles (filesystem write, API mutating, exécution de code, appels réseau externes). Particulièrement précieux pour Claude Code, agents avec MCP servers, frameworks LangChain/AutoGen.\n\n**Ce qu'il protège :** LLM06 (Excessive Agency) — l'utilisateur voit en temps réel ce que l'agent s'apprête à faire et peut bloquer. LLM05 (Improper Output Handling) — la déclaration documente la sortie attendue, ce qui permet de détecter les divergences. Couplé à `tool-intent-result-divergence-n3`, on obtient une boucle complète intention → vérification post-exécution.",
  "installation": {
    "ou_quand": "À installer dans tout système agent avec outils ayant des effets de bord. Profil utilisateur (Claude Code en local) ou config projet (production avec MCP servers).",
    "moments": ["projet-debut", "session-debut"],
    "exemples": [
      {
        "contexte": "Claude Code (développement local)",
        "instruction": "`~/.claude/CLAUDE.md` (profil) ou `./CLAUDE.md` (projet). Force l'agent à déclarer son intention avant chaque Edit/Write/Bash. Vous voyez ce qu'il s'apprête à faire avant qu'il le fasse — vous gagnez un cran de contrôle sans bloquer tous les outils."
      },
      {
        "contexte": "Agent MCP en production (serveur)",
        "instruction": "Paramètre **`system`** de l'agent. Capturer `[TOOL_INTENT]` dans les logs et envoyer en SIEM (Splunk/Elastic). Sur `reversible:false + auto_approved:false`, déclencher alerte temps réel."
      },
      {
        "contexte": "LangChain / AutoGen / CrewAI",
        "instruction": "Injection dans le system prompt de chaque agent ayant des tools. Coupler avec un callback Python qui valide la présence du bloc `[TOOL_INTENT]` avant de laisser l'appel passer (intercept-decline si absent)."
      },
      {
        "contexte": "Custom GPT avec Actions",
        "instruction": "Instructions de niveau Custom GPT. Particulièrement précieux pour les Actions qui font des POST/DELETE vers des API externes — l'utilisateur voit la requête forgée avant qu'elle parte."
      }
    ]
  },
  "date_creation": "2026-05-22",
  "date_maj": "2026-05-22",
  "version": "1.0",
  "tokens_estimes": { "entree": 320, "sortie": null }
}
