Aller au contenu principal

Module 7 — Permissions, modes d'exécution, sandbox et fichiers de settings

Le module 6 a montré qu'une skill pré-approuve quelques outils pour un tour. Ce module s'occupe de la couche du dessous : les règles générales qui décident, pour toute la session, ce que Claude peut lire, écrire, exécuter et joindre. C'est la couche à poser dès l'ouverture d'un dépôt : elle protège .env, laisse tourner make test sans confirmation, isole les commandes Bash avec le sandbox, et décide qui approuve les gestes de Claude — vous, un classifieur, ou personne.

Le modèle de permissions

Une règle de permission a la forme Outil ou Outil(spécificateur). Elle vit dans une liste permissions.allow, permissions.ask ou permissions.deny d'un fichier de settings, ou dans un flag CLI (--allowedTools, --disallowedTools, --permission-mode). Les règles sont évaluées deny d'abord, puis ask, puis allow ; le premier match décide. Un deny ne porte pas d'exception, un ask général force la question même si un allow plus précis correspond.

FormeEffet
Bash ou Bash(*)Toute commande Bash. En deny, retire l'outil du contexte.
Bash(npm run *)Toute commande commençant par npm run, y compris npm run seul.
Bash(git *)Toute commande git — couvre aussi git push.
Edit(app/**)Édition sous app/ (gitignore-style, ancré à la source du settings).
Edit(/src/**)Ancré à la racine du projet en settings de projet. Un // unique ancre à la racine du système.
Read(./.env)Bloque la lecture du .env courant ; bloque aussi Edit et Write sur ce chemin (v2.1.208+/v2.1.228+).
WebFetch(domain:example.com)Fetch vers example.com. domain:*.example.com couvre les sous-domaines.
mcp__github__get_*Outils MCP dont le nom commence par get_ sur le serveur github.
Agent(Explore)Sous-agent nommé Explore.
Cd(~/code/**)Cible autorisée pour /cd. Un allow bascule /cd en mode allowlist.

Deux règles à retenir sur le Bash : le * matche n'importe quel texte y compris des espaces, et Claude Code connaît les opérateurs de shell — un Bash(safe-cmd *) en allow ne couvre pas safe-cmd && rm -rf .. Les séparateurs reconnus sont &&, ||, ;, |, |&, & et le saut de ligne. Pour > fichier, le chemin cible passe par les règles Edit et par les chemins protégés.

La commande /permissions ouvre un dialogue interactif où l'on voit chaque règle, sa portée et son fichier d'origine ; les modifications prennent effet au prochain appel d'outil dans le même tour (v2.1.234+).

Les six modes d'exécution

Le mode d'exécution décide qui approuve les appels d'outils que les règles ne tranchent pas. Six valeurs sont exposées via permissions.defaultMode ou le flag --permission-mode.

ModeCe qui tourne sans demande
default (labellisé Manual)Lectures seules. Demande sur chaque édition et chaque Bash hors liste read-only intégrée.
acceptEditsLectures, éditions dans les répertoires de travail, plus mkdir, touch, mv, cp, rm, rmdir, sed.
planLecture et exploration seulement, aucune édition. Le classifieur passe les commandes shell si auto est disponible.
autoTout, avec un classifieur (petit modèle) qui refuse les actions dangereuses. Par défaut sur Pro/Max/Team depuis la v2.1.228 (macOS/Linux/WSL).
dontAskUniquement les allow explicites et les commandes read-only ; tout le reste refusé. Idéal pour la CI.
bypassPermissionsTout, sauf quelques gardes (chemins critiques). À réserver aux containers isolés. --dangerously-skip-permissions en est l'équivalent.

Shift+Tab cycle les modes dans la CLI ; auto apparaît quand il est disponible ; bypassPermissions n'apparaît qu'après un lancement explicite. En settings managés, permissions.disableBypassPermissionsMode et permissions.disableAutoMode mis à "disable" bloquent respectivement bypass et auto. La valeur auto en defaultMode ne prend pas dans .claude/settings.json ni .local.json — il faut la placer dans ~/.claude/settings.json ou en settings managés.

Chemins protégés et critiques

Deux jeux de chemins ne sont jamais auto-approuvés sauf en bypassPermissions.

  • Chemins protégés.git, .claude (sauf .claude/worktrees), .vscode, .idea, .husky, .devcontainer, .gitconfig, .bashrc, .zshrc, .npmrc, .mcp.json, .claude.json, etc. Une écriture demande en Manual/acceptEdits, passe au classifieur en auto, est refusée en dontAsk.
  • Chemins critiques pour rm/rmdir — racine /, répertoires de premier niveau (/usr, /etc…), répertoire personnel, C:\, répertoire courant et ses parents. Ni un allow ni un hook PreToolUse ne peuvent approuver un rm -rf sur ces chemins.

Le sandbox Bash

Le sandbox est le complément OS des règles : il applique un pare-feu filesystem et réseau à chaque commande shell et à ses enfants. Sur macOS il utilise Seatbelt (rien à installer) ; sur Linux et WSL2 il s'appuie sur bubblewrap et socat (à installer). Windows natif n'est pas supporté — passer par WSL2.

/sandbox ouvre un panneau à trois onglets (Mode, Overrides, Config), plus Dependencies si un paquet manque. Le choix va dans .claude/settings.local.json. Pour activer partout, sandbox.enabled: true dans ~/.claude/settings.json.

Deux modes de sandbox, indépendants du mode de permission :

  • Auto-allow : les commandes sandboxables tournent sans demande ; les autres (hôte non allowlisté, incompatibilité) retombent dans le flux normal. Un Bash(*) en ask est ignoré pour les commandes sandboxées (sauf en plan).
  • Regular permissions : le sandbox isole, mais chaque commande passe par le flux de permission.

Par défaut, une commande sandboxée écrit dans le répertoire de travail, le tmp de session et les répertoires ajoutés (--add-dir, permissions.additionalDirectories). On élargit avec sandbox.filesystem.allowWrite ; on restreint avec denyWrite, denyRead. Le réseau est allowlisté par domaine via sandbox.network.allowedDomains, dont les entrées fusionnent entre scopes au lieu de se remplacer.

Une commande qui ne peut vraiment pas être sandboxée peut être retentée avec le paramètre dangerouslyDisableSandbox (« unsandboxed retry ») ; en Manual elle demande, en auto le classifieur juge. Pour couper cette échappatoire : sandbox.allowUnsandboxedCommands: false.

Fichiers de settings et précédence

Claude Code lit ses réglages dans cinq sources, dans un ordre strict — le premier qui définit une clé gagne.

RangSourceChemin ou originePortée
1Managedmanaged-settings.json, MDM, console claude.aiOrganisation (irremplaçable, sauf exceptions)
2CLI --settingsJSON inline ou fichierCette session
3Projet local.claude/settings.local.jsonVous, ce projet (non commité)
4Projet partagé.claude/settings.jsonToute l'équipe (à commiter)
5Utilisateur~/.claude/settings.jsonVous, tous vos projets

Les variables d'environnement ne sont pas un niveau : pour chaque comportement, la doc précise si la variable gagne (ANTHROPIC_MODEL gagne sur model) ou cède (ANTHROPIC_DEFAULT_MODEL ne prend que si aucun fichier ne définit model). Un deny dans n'importe quel scope bloque un allow d'un autre : la précédence deny > ask > allow s'applique à travers les scopes ; --allowedTools ne contredit pas un deny managé.

Clés principales de permissions : allow, ask, deny, additionalDirectories, blockReadsOutsideWorkingDirectories, defaultMode, disableBypassPermissionsMode, disableAutoMode. allowManagedPermissionRulesOnly réserve les règles aux settings managés. Autres clés utiles : apiKeyHelper (commande shell qui génère la clé API), awsAuthRefresh (rafraîchit Bedrock), env (variables injectées), skillOverrides (visibilité de skills), sandbox.*. La commande /config clé=valeur (v2.1.181+) écrit une clé sans ouvrir le menu.

Un .claude/settings.local.json commité perd son statut personnel et devient une source de projet ; ses règles restent en attente tant que la confiance d'espace de travail n'est pas accordée. Idem si .claude est un lien symbolique.

Variables d'environnement clés

  • CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 — désactive les sous-agents en arrière-plan et background: true.
  • CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 — nettoie l'environnement des sous-processus (utile en sandbox Linux).
  • CLAUDE_CODE_USE_BEDROCK=1, CLAUDE_CODE_USE_VERTEX=1 — activent Bedrock/Vertex et exposent /setup-bedrock, /setup-vertex.
  • CLAUDE_CONFIG_DIR — déplace le répertoire de configuration hors de ~/.claude.
  • DISABLE_DOCTOR_COMMAND=1 — cache /doctor.

Fil rouge : verrouiller Kiosque

Après trois modules sur Kiosque sans filet, on pose des permissions. Le fichier partagé (.claude/settings.json, commité) définit ce que toute l'équipe doit avoir ; le fichier local personnel affine.

acme-kiosque/.claude/settings.json
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "acceptEdits",
"additionalDirectories": ["../kiosque-migrations"],
"allow": [
"Bash(make test)",
"Bash(make lint)",
"Bash(make dev)",
"Bash(pytest *)",
"Bash(ruff *)",
"Bash(mypy *)",
"Bash(git status *)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(gh pr *)",
"Edit(app/**)",
"Edit(tests/**)",
"Edit(web/src/**)",
"WebFetch(domain:fastapi.tiangolo.com)",
"WebFetch(domain:docs.python.org)"
],
"ask": [
"Bash(git push *)",
"Bash(alembic upgrade *)"
],
"deny": [
"Read(./.env)",
"Read(./secrets/**)",
"Edit(./migrations/**)",
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(git push -f *)",
"Bash(git reset --hard *)"
]
},
"sandbox": {
"enabled": true,
"network": {
"allowedDomains": ["*.pypi.org", "registry.npmjs.org", "*.github.com"]
}
}
}

Karim ouvre le projet et accepte la confiance d'espace de travail. En Manual pur la journée serait pénible ; acceptEdits laisse passer les éditions dans les répertoires de travail. Les pushes forcés sont bloqués net, un git push normal demande, les migrations SQL restent bloquées à l'édition. Léa a son fichier personnel pour le front :

acme-kiosque/.claude/settings.local.json
{
"permissions": {
"allow": ["Bash(npm run *)", "Bash(pnpm *)", "WebFetch(domain:vitejs.dev)"]
}
}

Une semaine plus tard, un audit /permissions montre douze blocages sur Bash(alembic downgrade *). On complète le ask plutôt que de tout ouvrir, on commite. En cas de doute, claude doctor liste les règles rejetées et --debug explique un refus.

Un .claude/settings.local.json commité change de statut

Une fois commité (ou .claude en lien symbolique), Claude Code le traite comme source de projet et retient ses règles jusqu'à la confiance d'espace de travail — protection contre le dépôt qui s'auto-autoriserait des Bash(*).

En résumé

  • Les règles de permission ont la forme Outil(spécificateur) et sont évaluées deny > ask > allow ; un deny d'un scope bloque un allow d'un autre.
  • Les six modesdefault (Manual), acceptEdits, plan, auto, dontAsk, bypassPermissions — décident qui approuve. Shift+Tab cycle, --permission-mode fixe au lancement.
  • Chemins protégés (.git, .claude, .env, .mcp.json…) et chemins critiques (rm -rf /, ~, dossier courant) ne sont jamais auto-approuvés, sauf bypassPermissions.
  • Le sandbox Bash applique un pare-feu OS sur les commandes shell et leurs enfants : sandbox.enabled, sandbox.filesystem.allow/denyWrite, sandbox.network.allowedDomains. Deux modes : auto-allow et regular.
  • Précédence de settings : managed > CLI --settings > projet local > projet partagé > utilisateur. Un defaultMode: "auto" en .claude/settings.json ne prend pas — il doit être en utilisateur ou managed.
  • /permissions ajuste en live, /status montre les sources chargées, claude doctor liste les règles rejetées.

Module suivant : Mode plan, checkpoints, sessions et worktrees : travailler sans peur — les filets de sécurité côté conversation, code et git qui rendent l'expérimentation réversible.