Blog • AI / Agent

Nouveautés Claude Managed Agents 2026 : comment un AI Agent décide automatiquement si un Tool Call est autorisé ? Permission policy JSON et MCP Security

Le 10 septembre 2026, Anthropic a ajouté un nouveau type à la permission policy de Claude Managed Agents : auto. Le même jour, les événements agent.tool_use et agent.mcp_tool_use ont commencé à porter le champ evaluation, à côté de l’ancien evaluated_permission.

Que le modèle propose un Tool Call ne veut pas dire que cet appel s’exécutera. C’est l’évaluation de stratégie sur le serveur qui tranche : elle lit la JSON policy écrite dans la config de l’Agent, puis donne allow, deny ou ask d’après le nom d’outil, l’input et le contenu de la session pour cet appel.

Cet article présente :

Retenez ceci : auto n’est pas « tout ouvrir », ni une approbation humaine. Quand le serveur juge l’appel sûr, il a déjà tourné avant que vous le voyiez ; s’il le juge à haut risque, le client n’a même pas l’occasion de renverser le deny. Ci-dessous : trois stratégies → évaluation par appel → JSON d’événement → MCP → flux d’approbation.

Trois stratégies : always_allow, always_ask, auto

La permission policy ne concerne que les outils exécutés par le serveur : le jeu intégré agent_toolset_20260401, et les MCP toolset que vous branchez. Les outils personnalisés sont exécutés par votre application, hors de cette stratégie. La requête doit porter l’en-tête beta managed-agents-2026-04-01. Documentation officielle :

Claude Managed Agents Permission policies.

La stratégie décide « quand cet appel tourne », pas « si cet outil est dans le catalogue ». Pour retirer un outil de l’Agent, utilisez disable : n’attendez pas que la stratégie le cache.

Stratégie Ce que fait le serveur Ce que le client doit encore faire
always_allow Exécute tout de suite, sans attendre Lire les événements suffit, pas d’étape de confirmation
always_ask S’arrête après l’événement tool_use Envoyer, pour chaque événement bloqué, un user.tool_confirmation
auto Évalue cet appel : tourner, refuser, ou s’arrêter pour vous demander Ne traiter que les événements en ask ; un deny ne se renverse pas

Les défauts ne sont pas les mêmes des deux côtés. L’Agent toolset vaut par défaut always_allow. Le MCP toolset vaut par défaut always_ask. Aucun toolset n’ouvre auto par défaut : il faut l’écrire dans le JSON.

Une session déjà en cours garde la config toolset du moment de sa création. Après une modification de l’Agent, seules les nouvelles sessions prennent la nouvelle stratégie. Notes de version :

Claude Platform release notes (2026-09-10).

Ce que auto regarde vraiment

Avant, il n’y avait que « cet outil passe toujours » ou « cet outil demande toujours ». auto déplace le jugement du niveau outil au niveau appel.

Les docs sont précises : l’évaluation regarde l’outil, l’input de cet appel, et le contenu de la session jusqu’ici. Donc le même bash, avec deux command différents, peut donner un allow et un deny.

  1. 1
    L’appel est autorisé

    Le serveur juge cet appel sûr : l’outil s’exécute comme en always_allow. Pas de pause, pas de fenêtre humaine.

  2. 2
    L’appel est refusé

    Le serveur le classe à haut risque : l’outil ne tourne pas. L’Agent reçoit un tool result d’erreur : Permission to use {tool_name} has been denied., avec is_error: true. La session continue. Votre client ne peut pas modifier ce deny.

  3. 3
    L’appel s’arrête et vous attend

    Le serveur n’a pas de conclusion nette : la session se met en pause comme en always_ask. Vous autorisez ou refusez ensuite avec l’événement de confirmation.

L’intention se lit seulement dans les user.message que vous envoyez. Résultats d’outils, pages récupérées, retours MCP Server, messages entre threads : le serveur évalue le contenu, mais ne les traite pas comme des instructions. Certains appels sont classés à haut risque, peu importe qui les a demandés.

Si vous collez tel quel du texte d’un utilisateur final non fiable dans user.message, le serveur le traitera comme votre intention et pourra autoriser un appel. Pour ces outils d’entrée, configurez always_ask à part.

Dans quel JSON s’écrit la stratégie

La stratégie apparaît à deux endroits : le default_config.permission_policy du toolset, et une surcharge d’un outil dans configs. La config ci-dessous met l’Agent toolset et le GitHub MCP en auto, puis cloue bash tout seul en always_ask.

Config tools à la création de l’Agent (extrait de la doc officielle)
{
  "name": "Ops Agent",
  "model": "claude-opus-5",
  "mcp_servers": [
    {
      "type": "url",
      "name": "github",
      "url": "https://mcp.example.com/github"
    }
  ],
  "tools": [
    {
      "type": "agent_toolset_20260401",
      "default_config": {
        "permission_policy": { "type": "auto" }
      },
      "configs": [
        {
          "name": "bash",
          "permission_policy": { "type": "always_ask" }
        }
      ]
    },
    {
      "type": "mcp_toolset",
      "mcp_server_name": "github",
      "default_config": {
        "permission_policy": { "type": "auto" }
      }
    }
  ]
}

mcp_server_name doit correspondre à l’entrée dans mcp_servers dont le name est le même. Pour une surcharge MCP par nom d’outil, name est le nom rapporté par le Server, pas un alias que vous avez inventé.

Si vous omettez default_config, l’Agent toolset s’active en always_allow. C’est un défaut de commodité, pas un défaut de sécurité.

L’evaluation laissée par chaque appel

Quelle que soit la stratégie, agent.tool_use et agent.mcp_tool_use portent le champ de premier niveau evaluated_permission, qui vaut allow, ask ou deny. La plupart des événements portent aussi un objet evaluation, dont le type indique quelle stratégie a tranché.

Sous auto, l’objet note aussi le jugement du serveur ; si le résultat est ask ou deny, il porte reason_code. Exemple officiel : bash en auto, un appel à haut risque est refusé.

Événement agent.tool_use refusé par auto
{
  "type": "agent.tool_use",
  "id": "sevt_01pqr...",
  "name": "bash",
  "input": {
    "command": "rm -rf /workspace/reports"
  },
  "evaluated_permission": "deny",
  "evaluation": {
    "type": "auto",
    "evaluated_permission": {
      "type": "deny",
      "reason_code": "high_risk"
    }
  },
  "processed_at": "2026-03-25T14:05:12Z"
}
evaluation Résultat de premier niveau Sens
{"type":"always_allow"} allow La stratégie résolue est always_allow, l’appel a déjà tourné
{"type":"always_ask"} ask La stratégie résolue est always_ask, la session vous attend
{"type":"auto","evaluated_permission":{"type":"allow"}} allow auto a jugé cet appel sûr, il a déjà tourné
{"type":"auto","evaluated_permission":{"type":"ask","reason_code":"indeterminate"}} ask auto n’a pas de conclusion, s’arrête pour vous demander
{"type":"auto","evaluated_permission":{"type":"deny","reason_code":"high_risk"}} deny auto a classé l’appel à haut risque, déjà refusé

reason_code sert au branchement et aux journaux d’audit de votre client, ce n’est pas un texte pour les humains. Les docs listent aujourd’hui indeterminate et high_risk. Le client doit tolérer de futurs type ou reason_code supplémentaires.

Deux cas n’ont pas d’evaluation. L’Agent a visé un outil non activé dans la session : l’événement n’a que evaluated_permission: "deny". Les anciens événements, enregistrés avant l’apparition du champ, ne l’ont pas non plus : allow se lisait comme always_allow, ask comme always_ask.

C’est la même couche que « JSON est une frontière de sécurité », mais l’incision change. Là-bas, les arguments émis par le modèle doivent d’abord être validés ; ici, la plateforme écrit elle-même un résultat d’évaluation, et vous ne le renversez pas. L’article précédent :

AI Agent et frontière de sécurité JSON.

MCP Tool Call et always_ask par défaut

MCP déplace le catalogue d’outils hors de votre dépôt, vers un Server extérieur. Le Server expose les tools en JSON-RPC, chaque tool porte un inputSchema. Le Host nourrit le catalogue au modèle, puis transforme l’appel en tools/call. Spécification :

MCP Tools.

Managed Agents est conservateur par défaut : le MCP toolset vaut always_ask. Un nouvel outil ajouté à un Server déjà connecté ne s’exécutera pas en silence dans votre application. C’est la première porte MCP Security côté plateforme, plus fiable que « croire la description du Server ».

Vous pouvez encore changer. Si vous faites confiance à un GitHub MCP et voulez moins d’interruptions, passez le default_config.permission_policy de ce toolset à always_allow ou auto. Vous changez « quand exécuter », pas « faut-il encore valider le Schema ».

Couche Ce à quoi elle répond Ce à quoi elle ne répond pas
JSON Schema Si les champs, types, clés requises et enums des paramètres sont justes Si cet appel doit avoir lieu
Tool Calling Quel outil le modèle a choisi, quels arguments il a remplis Si le Host exécutera
permission policy allow / ask / deny pour cet appel Si le payload colle au schema, si la description a orienté le modèle

Empilées, les trois couches ressemblent à une porte. Ouvrir seulement auto alors que le Schema reste {"sql":{"type":"string"}} : la surface d’entrée vue par l’évaluateur est trop large pour juger, plus d’appels tombent dans indeterminate, autrement dit ask. Serrer le schema aide auto à produire une conclusion journalisable. Qui porte quelle couche :

Sécurité MCP : pourquoi Schema, Tool Calling et permissions ne se remplacent pas.

Le flux JSON d’approbation après ask

Un appel noté ask ne peut venir que de always_ask, ou d’un auto classé indeterminate. L’ordre des événements ensuite est fixe.

  1. 1
    D’abord l’événement tool_use

    La session émet agent.tool_use ou agent.mcp_tool_use, déjà porteur de evaluated_permission: "ask".

  2. 2
    Puis idle

    La session se met en pause : session.status_idle a pour stop_reason.type la valeur requires_action. Les id des événements bloqués sont dans stop_reason.event_ids. Elle attend.

  3. 3
    Vous renvoyez l’événement de confirmation

    Pour chaque id bloqué, envoyez un user.tool_confirmation : renseignez tool_use_id avec l’id de l’événement, result avec allow ou deny. En cas de refus, deny_message peut expliquer. Une requête peut porter plusieurs confirmations.

  4. 4
    La session repasse en running

    Une fois tous les blocages levés, les outils autorisés s’exécutent ; les refusés ne tournent pas, l’Agent reçoit un tool result portant votre deny_message.

Autoriser ou refuser un appel en attente
{
  "events": [
    {
      "type": "user.tool_confirmation",
      "tool_use_id": "sevt_01ask...",
      "result": "allow"
    },
    {
      "type": "user.tool_confirmation",
      "tool_use_id": "sevt_01mcp...",
      "result": "deny",
      "deny_message": "Do not push to main from this session."
    }
  ]
}

Si le evaluated_permission de l’événement n’est pas ask, un nouvel envoi de confirmation vaut 400. Cela inclut les appels déjà deny par auto : le client n’a pas de voie de recours. Pour un traitement interactif, ant beta:sessions connect montre les appels en attente dans le terminal, à autoriser ou refuser.

Monter soi-même une file d’approbation, renvoyer un deny à l’Agent, et figer une stratégie rejouable dans le Host : ce sera l’article d’implémentation. Ici, on clarifie seulement le JSON que la plateforme a déjà évalué pour vous.

auto n’est pas un point de contrôle

Les docs ont une phrase à ne pas sauter : auto n’est pas un point de contrôle humain. Quand le serveur juge l’appel sûr, il s’exécute avant que quiconque le voie ; l’effet peut être irréversible. Pour un outil qu’un humain doit voir, donnez-lui always_ask.

Les outils personnalisés ne sont pas dans cette porte. agent.custom_tool_use n’a ni evaluated_permission, ni evaluation. Votre application reçoit l’événement, décide d’exécuter ou de refuser, puis renvoie user.custom_tool_result. La plateforme n’évalue pas ce saut pour vous.

Donc « comment un AI Agent décide automatiquement si un Tool Call est autorisé » a un périmètre étroit : seulement les outils Agent et MCP exécutés par le serveur, et seulement après que vous ayez explicitement écrit la policy en auto. Le reste passe toujours, demande toujours, ou n’est tout simplement pas géré par la plateforme.

Vérifier stratégie et événements dans JSONNote

JSON de stratégie, événement tool_use, requête de confirmation : les trois se ressemblent, les champs ne sont pas la même couche. Au debug, ne balayez pas à l’œil.

  1. 1
    D’abord formater la stratégie

    Jetez la config tools de l’Agent dans le formateur JSON, confirmez que default_config et configs portent un permission_policy.type juste, non avalé par une surcharge.

  2. 2
    Puis valider la forme de l’événement

    Avec JSON Schema, écrivez un schema minimal pour evaluation : type énumère always_allow / always_ask / auto ; en auto, exigez un evaluated_permission imbriqué. Un reason_code inconnu se tolère via additionalProperties, ne le refusez pas d’emblée.

  3. 3
    Comparer deux appels

    Quand le même outil est une fois autorisé, une fois refusé, alignez avec JSON Diff les deux input et les deux evaluation. L’écart est presque toujours dans command, path, ou l’étape qui vient d’arriver dans la session — pas dans le nom de l’outil.

  4. 4
    Laisser un retour d’expérience partageable

    La stratégie et les événements masqués peuvent passer à un collègue via Partage Hash : les données ne touchent aucun serveur. N’y mettez ni clés, ni tokens de production.

FAQ

auto va-t-il laisser passer tous les Tool Call ?

Non. auto évalue à chaque appel : deux appels du même outil, avec un input et une session différents, peuvent diverger. high_risk donne un deny direct ; le client ne peut pas le renverser avec user.tool_confirmation.

Un JSON Schema valide autorise-t-il déjà l’exécution ?

Non. Le Schema ne dit que si les paramètres ont la bonne forme. La permission policy dit si cet appel peut tourner. Une commande bash bien formée peut encore sortir en deny sous auto.

Quelle stratégie suit un MCP Tool Call par défaut ?

Le MCP toolset vaut always_ask par défaut. Un nouvel outil ajouté au Server ne s’exécute pas tout seul dans votre application. Quand vous faites confiance à un Server, passez default_config.permission_policy à always_allow ou auto.

Les outils personnalisés passent-ils par la permission policy ?

Non. Les Custom tools sont exécutés par votre application. L’événement est agent.custom_tool_use, sans evaluated_permission ni evaluation. Vous décidez de tourner ou non, puis renvoyez user.custom_tool_result.

auto peut-il remplacer l’approbation humaine ?

Non. Les docs le disent : auto n’est pas un point de contrôle humain. Quand le serveur juge l’appel sûr, il s’exécute avant que quiconque le voie ; les effets de bord peuvent être irréversibles. Un outil qu’un humain doit voir se configure à part en always_ask.

Résumé

L’auto ajouté le 10 septembre a changé « cet outil peut-il servir » en « cet appel peut-il tourner ». Le jugement s’appuie sur la JSON policy écrite dans l’Agent, plus l’outil, l’input et la session de cet appel ; le résultat revient dans evaluated_permission et evaluation de l’événement.

Le modèle propose l’appel. Le moteur de stratégie autorise, refuse, ou s’arrête pour demander. MCP demande d’abord. Les outils personnalisés, c’est vous. Le client ne renverse pas un deny.

Lisez le JSON de stratégie et le JSON d’événement comme deux contrats. Un Schema valide n’est pas une autorisation. Les outils qu’un humain doit surveiller restent en always_ask ; ceux qui doivent moins interrompre, tout en laissant des champs d’audit, peuvent ouvrir auto.

← Retour au blog