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 :
- À quelle couche s’arrête chacune des trois permission policy
auto: ce que l’évaluation par appel regarde, et le JSON laissé par les trois résultats- Pourquoi le MCP toolset vaut par défaut
always_ask, et comment le superposer à auto - Après arrêt de la session sur
requires_action, comment écrireuser.tool_confirmation. - Comment séparer stratégie, événements et demandes d’approbation dans JSONNote
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
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
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., avecis_error: true. La session continue. Votre client ne peut pas modifier ce deny. -
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.
{
"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é.
{
"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 :
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
D’abord l’événement tool_use
La session émet
agent.tool_useouagent.mcp_tool_use, déjà porteur deevaluated_permission: "ask". -
2
Puis idle
La session se met en pause :
session.status_idlea pourstop_reason.typela valeurrequires_action. Les id des événements bloqués sont dansstop_reason.event_ids. Elle attend. -
3
Vous renvoyez l’événement de confirmation
Pour chaque id bloqué, envoyez un
user.tool_confirmation: renseigneztool_use_idavec l’id de l’événement,resultavecallowoudeny. En cas de refus,deny_messagepeut expliquer. Une requête peut porter plusieurs confirmations. -
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.
{
"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
D’abord formater la stratégie
Jetez la config
toolsde l’Agent dans le formateur JSON, confirmez quedefault_configetconfigsportent unpermission_policy.typejuste, non avalé par une surcharge. -
2
Puis valider la forme de l’événement
Avec JSON Schema, écrivez un schema minimal pour
evaluation:typeénumèrealways_allow/always_ask/auto; en auto, exigez unevaluated_permissionimbriqué. Unreason_codeinconnu se tolère viaadditionalProperties, ne le refusez pas d’emblée. -
3
Comparer deux appels
Quand le même outil est une fois autorisé, une fois refusé, alignez avec JSON Diff les deux
inputet les deuxevaluation. 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
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.
Décortiquer la stratégie et les événements tool_use