Passer au contenu principal
Nommer un outil et le refuser est brutal : cela tue l’outil pour chaque appel. La plupart du temps l’outil va bien et une forme d’appel est le problème — shell.exec va bien jusqu’à ce que la commande soit rm -rf, db.query va bien jusqu’à ce qu’il atteigne prod. Cette distinction est ce qu’une clause d’argument exprime : un prédicat d’argument d’outil jsonpath qui correspond sur les valeurs qu’un agent passe, de sorte que le verdict ne se déclenche que sur l’appel dangereux et laisse le reste tranquille. Cette page est un livre de recettes — une poignée de recettes args_match_json à copier-coller pour les cas qui reviennent le plus. Pour la grammaire complète des clauses, le tableau des opérateurs et la sémantique fail-closed, voir Valider les arguments et la référence du Schéma de règle.

1. Comment fonctionne une clause d’argument d’outil jsonpath

Le args_match_json d’une règle est une chaîne encodée en JSON portant un ensemble de clauses, toutes combinées par AND. La valeur décodée est un objet, {"clauses": [ … ]}, où chaque clause est un triplet { path, op, value } :
  • path — un petit sous-ensemble JSONPath sur l’objet d’arguments de l’outil : $.command, $.foo.bar, $.items[0], ou $ pour l’objet entier. Pas de wildcards, de filtres, de slices ou de descente récursive.
  • op — l’un d’un ensemble fermé : eq, contains, regex, in, cidr_match, gt, lt.
  • value — le littéral à comparer (une chaîne, un nombre, un booléen, ou — pour in — un tableau JSON).
Une clause est combinée par AND sur le tool_name_glob de la règle : la règle ne se déclenche que lorsque le nom d’outil correspond et que chaque clause tient. Omettez args_match_json entièrement (ou laissez-le un "{}" vide) et la règle correspond sur le glob seul.
Les clauses fail closed — la règle, pas la requête. Si un chemin ne se résout pas, que les arguments sont malformés, ou qu’une valeur est du mauvais type, la clause s’évalue à false et la règle simplement ne se déclenche pas — l’appel retombe sur la règle suivante ou le verdict par défaut. Une clause cassée ne refuse jamais automatiquement. Rédigez votre filet de sécurité dur comme un deny de glob simple, pas comme une clause sur laquelle vous comptez pour échouer d’une certaine façon.

2. Recette : bloquer une commande destructrice

Le cas canonique. Autoriser shell.exec en général, le refuser uniquement quand la commande paraît destructrice. Une clause regex sur $.command fait l’affaire :
{
  "label": "block destructive shell commands",
  "tool_name_glob": "*.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf|mkfs|dd if=\"}]}"
}
Les regex sont du Go RE2 — temps linéaire, pas de backreferences, pas de backtracking catastrophique — donc elles sont sûres à exécuter à chaque appel d’outil. Un $.command non-chaîne (ou manquant) ne correspond jamais, de sorte qu’un appel malformé retombe plutôt que d’être à tort bloqué.
Préférez contains à regex quand vous faites correspondre une sous-chaîne fixe — c’est plus simple à lire et ne peut pas être déclenché par un métacaractère non échappé. Recourez à regex uniquement quand vous avez vraiment besoin d’alternance ou d’ancres.

3. Recette : refuser un outil contre un environnement nommé

Laissez db.query s’exécuter, mais seulement contre des connexions sûres — refusez-le quand la cible est prod ou un replica. L’opérateur in fait correspondre la valeur résolue à n’importe quel élément d’un tableau JSON :
{
  "label": "no agent queries against prod",
  "tool_name_glob": "db.query",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.connection\",\"op\":\"in\",\"value\":[\"prod\",\"replica\"]}]}"
}
La valeur in doit être un tableau JSON — un non-tableau est rejeté quand vous enregistrez la règle. Les éléments se comparent avec une égalité scalaire, donc les nombres et les chaînes correspondent chacun à leur propre type.

4. Recette : refuser une destination en IP privée ou metadata

Quand un outil prend une IP cible comme argument, cidr_match teste si elle tombe dans un CIDR — la forme SSRF de « un agent récupérant 10.x ou l’adresse cloud metadata » :
{
  "label": "deny tool calls aimed at RFC-1918",
  "tool_name_glob": "*",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.target_ip\",\"op\":\"cidr_match\",\"value\":\"10.0.0.0/8\"}]}"
}
La valeur d’argument doit se parser comme un littéral d’IP qui se trouve dans le CIDR ; un nom d’hôte ou une chaîne non-IP ne correspond jamais.
cidr_match n’inspecte qu’une valeur qui est déjà dans les arguments de l’outil. Pour gouverner la destination qu’un outil atteint réellement au niveau réseau — listes d’autorisation et de refus host/CIDR — utilisez plutôt une règle d’egress dédiée sur la surface egress. Les deux sont complémentaires : inspection des arguments à l’aller, contrôle d’egress au retour.

5. Recette : plafonner un argument numérique

gt et lt comparent des nombres. Utilisez-les pour refuser une taille de lot absurde, une limite surdimensionnée, ou tout comptage emballé — ici, refuser une suppression de masse qui cible plus de 100 lignes :
{
  "label": "block large bulk deletes",
  "tool_name_glob": "*.bulk_delete",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.count\",\"op\":\"gt\",\"value\":100}]}"
}
Les deux côtés doivent être des nombres — une chaîne d’apparence numérique comme "500" est une incompatibilité de type et ne correspond pas, de sorte que la règle ne se déclenchera pas sur un argument typé en chaîne. Gardez l’argument numérique, ou normalisez-le avant que l’outil ne le voie.

6. Recette : combiner des clauses (AND)

Toutes les clauses d’une règle se combinent par AND, donc vous pouvez restreindre un verdict à un appel très spécifique — par exemple, refuser shell.exec uniquement quand c’est une commande destructrice et qu’elle pointe vers un hôte prod :
{
  "label": "destructive shell on a prod host",
  "tool_name_glob": "*.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf|drop table\"},{\"path\":\"$.host\",\"op\":\"in\",\"value\":[\"db-prod-1\",\"db-prod-2\"]}]}"
}
Besoin d’un OR à la place ? Il n’y a pas de OR à l’intérieur d’un seul args_match_json — rédigez deux règles (ou deux globs) à des priorités différentes. Le moteur parcourt les règles dans l’ordre de priorité et la première correspondance gagne, donc placez les règles étroites en premier. Voir Priorité des règles.

7. Choisir le verdict pour la forme correspondante

Une clause décide quels appels correspondent ; le verdict de la règle décide ce qui se passe. deny est le défaut du livre de recettes, mais la même clause peut porter un verdict plus doux :
Quand l’argument correspondant porte un secret ou de la PII plutôt qu’une instruction dangereuse, sanitize redacte les sous-chaînes correspondantes des arguments de l’outil et transmet l’appel nettoyé. Il redacte les arguments seulement — jamais le contenu qu’un outil renvoie. Voir Assainir les réponses.
Mettre en attente exactement la forme risquée pour revue au lieu de la bloquer purement et simplement : un relecteur approuve ou rejette hors-bande, et l’agent re-soumet l’appel approuvé une fois. Voir Approbations.
Définissez le verdict sur audit pour enregistrer l’appel correspondant sans bloquer pendant que vous affinez la clause. Associez au mode shadow pour mesurer un deny contre le trafic réel avant qu’il ne change quoi que ce soit.

8. Tester la clause avant de vous y fier

L’onglet Test de la console exécute une politique en dry-run contre un appel d’outil d’échantillon et renvoie le verdict, la règle correspondante et la raison — rien n’est dispatché, rien n’est persisté. Collez un objet d’arguments réaliste et confirmez que la clause se déclenche sur les appels que vous visez et seulement ceux-là, puisqu’une clause qui ne peut pas résoudre une valeur ne se déclenche silencieusement pas. Voir Tester les règles.
Les clauses sont validées strictement à l’enregistrement — les opérateurs inconnus, les mauvais chemins, une valeur in non-tableau, une regex non compilable et des CIDR invalides sont tous rejetés, de sorte qu’une clause malformée ne peut pas être persistée en premier lieu.

9. Qui peut rédiger des clauses d’arguments

Tout cela s’exécute dans la console sous votre session (/api/workspace/firewall/*) :
ActionRôle
Lire les politiques, presets, outils découvertsMember
Créer / éditer / supprimer des règlesDeveloper+
Sandbox Test (dry-run d’une politique)Developer+
Lire les événements et les agrégations d’exécutionsDeveloper+
Rédiger ou modifier une clause d’argument est une écriture Developer+. Le sandbox Test est également Developer+ — il peut prévisualiser contre une politique brouillon et sa trace de verdict expose les noms de politiques et les labels de règles, donc il se situe du côté écriture de la ligne, pas du côté lecture.

Connexe

Valider les arguments

Le cas d’usage de correspondance d’arguments en entier.

Bloquer des outils

Refuser tout un outil par son nom — aucune clause nécessaire.

Contrôle d'egress

Gouverner les destinations host / IP / CIDR sortantes.

Schéma de règle

Chaque champ qu’une règle peut porter.

Priorité des règles

La première correspondance gagne — ordonnez l’étroit avant le large.

Appels d'outils dangereux

La menace que ces recettes traitent.