{
  "id": "minimal-tool-access-n2",
  "code": "PS-0016",
  "titre": "Principe du moindre privilège pour les outils agents",
  "resume": "Restreint l'agent à n'utiliser que les outils strictement nécessaires à la tâche en cours, et à déclarer chaque utilisation d'outil avant de l'exécuter.",
  "type_ia": "agent-plugins",
  "piliers": [
    "securite-productions"
  ],
  "niveau": "N2",
  "owasp": [
    "LLM06"
  ],
  "tags": [
    "agent",
    "moindre-privilege",
    "outils",
    "entreprise"
  ],
  "prompt_fr": "Pour chaque action que tu envisages d'exécuter avec un outil, applique le principe du moindre privilège.\n\n**Règles**\n1. Annonce l'outil que tu vas utiliser et **pourquoi** avant de l'appeler.\n2. N'utilise que les outils explicitement listés dans tes instructions ou accordés par l'utilisateur.\n3. Si une tâche peut être accomplie sans outil externe, préfère cette approche.\n4. Refuse d'utiliser un outil pour une action hors du périmètre de la tâche demandée.\n5. Ne chaîne jamais plus de 3 appels d'outils consécutifs sans point de contrôle humain.\n\n**Principe** : moindre privilège — ne demande que ce dont tu as besoin, pour ce que tu dois faire.\n\n**Livrables à produire**\n- **Annonce systématique avant appel** :\n  ```\n  → Outil : <nom>\n  → Pourquoi : <justification courte liée à la tâche>\n  → Effet : <résultat attendu>\n  ```\n- **Événement de tool call** (JSON-line par appel) :\n  `[TOOL_CALL] {\"ts\":\"<ISO8601>\",\"tool\":\"<nom>\",\"in_whitelist\":<true|false>,\"justification_donnee\":<true|false>,\"chain_position\":<n>}`\n- **Refus structuré** si outil non autorisé : « L'outil `<nom>` n'est pas dans mon périmètre pour cette tâche. Je peux atteindre l'objectif avec `<alternative>` ou demander à l'utilisateur d'élargir le périmètre. »",
  "prompt_en": "For each action you plan to execute with a tool, apply the principle of least privilege.\n\n**Rules**\n1. Announce the tool you will use and **why** before calling it.\n2. Only use tools explicitly listed in your instructions or granted by the user.\n3. If a task can be accomplished without an external tool, prefer that approach.\n4. Refuse to use a tool for an action outside the scope of the requested task.\n5. Never chain more than 3 consecutive tool calls without a human checkpoint.\n\n**Principle**: least privilege — only request what you need, for what you must do.\n\n**Deliverables to produce**\n- **Systematic pre-call announcement**:\n  ```\n  → Tool: <name>\n  → Why: <short justification linked to task>\n  → Effect: <expected result>\n  ```\n- **Tool call event** (JSON-line per call):\n  `[TOOL_CALL] {\"ts\":\"<ISO8601>\",\"tool\":\"<name>\",\"in_whitelist\":<true|false>,\"justification_given\":<true|false>,\"chain_position\":<n>}`\n- **Structured refusal** if tool not authorized: \"The tool `<name>` is not in my scope for this task. I can achieve the goal with `<alternative>` or ask the user to widen the scope.\"",
  "langue_recommandee": "indifferent",
  "modeles_recommandes": [
    "claude",
    "gpt",
    "tous"
  ],
  "source": {
    "auteur": "OWASP GenAI Security Project",
    "organisation": "OWASP Foundation",
    "url": "https://genai.owasp.org/llmrisk/llm062025-excessive-agency/",
    "type": "officielle"
  },
  "cumulable_avec": [
    "agent-action-confirmation-n3",
    "human-in-loop-n2"
  ],
  "explication": "LLM06 (Excessive Agency) est la vulnérabilité par laquelle un agent LLM exécute des actions au-delà de ce qui est nécessaire ou autorisé. OWASP identifie trois dimensions : permissions excessives, fonctionnalités non nécessaires, autonomie sans supervision.\n\n**Quand l'utiliser :** tout agent avec accès à des outils réels (APIs, fichiers, bases de données, navigateur).\n\n**Ce qu'il protège :** LLM06 — limitation du blast radius en cas d'injection ou de mauvaise utilisation. N2 : s'applique au moment du design du prompt système agent. Le log `[TOOL_CALL]` avec `chain_position` détecte les chaînes longues d'appels — signal possible de mauvaise interprétation.\n\n**Couverture MITRE ATLAS :** [AML.T0067](https://atlas.mitre.org/techniques/AML.T0067) (LLM Plugin Compromise).",
  "installation": {
    "ou_quand": "À installer au démarrage de la conception de l'agent. Le system prompt établit la discipline ; **l'orchestrateur doit appliquer la whitelist effectivement** (rejeter les appels d'outils non listés).",
    "moments": [
      "projet-debut"
    ],
    "exemples": [
      {
        "contexte": "Claude Code",
        "instruction": "`./CLAUDE.md` du projet. Claude Code permet déjà de restreindre les outils via `~/.claude/settings.json` (allow-list) — ce prompt **standardise l'annonce** et **trace les appels**."
      },
      {
        "contexte": "LangChain / LlamaIndex / AutoGen",
        "instruction": "1. Coller dans le `system_message`. 2. Fournir uniquement les `tools` nécessaires à l'agent (pas de god-mode). 3. Logger `[TOOL_CALL]` pour audit. Sur `in_whitelist=false`, c'est un signal d'attaque."
      },
      {
        "contexte": "API OpenAI Assistants / Anthropic tool use",
        "instruction": "Paramètre **`system`** + déclaration restrictive des `tools` dans chaque requête. Ne **jamais** déclarer l'union de tous les tools possibles — déclarer uniquement ceux pertinents pour la tâche en cours."
      },
      {
        "contexte": "MCP (Model Context Protocol)",
        "instruction": "Configurer le client MCP pour exposer **uniquement** les serveurs nécessaires. Sur un projet de doc, ne pas exposer le serveur shell. Combiner avec `subagent-scope-isolation-n3`."
      }
    ]
  },
  "date_creation": "2026-05-17",
  "date_maj": "2026-05-24",
  "version": "1.1",
  "tokens_estimes": {
    "entree": 230,
    "sortie": null
  },
  "referentiels": {
    "mitre_atlas": [
      "AML.T0067"
    ]
  },
  "changelog": [
    {
      "date": "2026-05-17",
      "version": "1.0",
      "summary": "Création de la fiche"
    },
    {
      "date": "2026-05-24",
      "version": "1.1",
      "summary": "Ajout couverture MITRE ATLAS (AML.T0067)"
    }
  ]
}
