Tips & Tricks

Guide complet des permissions Claude Code | settings.json, Hooks et Allowlist expliqués

Guide complet des permissions Claude Code. Maîtrisez allow/deny/ask, l'automatisation avec les Hooks, settings.json par environnement et les schémas pratiques, avec du code fonctionnel.

Claude Code dispose de capacités extrêmement puissantes d’opérations sur les fichiers et d’exécution de commandes. Les permissions permettent de contrôler cette puissance en toute sécurité. Dépassez l’état « ça marche à peu près » et concevez un Claude Code qui fonctionne exactement comme prévu.

Cet article explique en détail, avec du code fonctionnel, tous les paramètres de .claude/settings.json, les schémas d’implémentation des Hooks et la conception des permissions selon les environnements.

Vue d’ensemble des permissions

Les permissions Claude Code sont contrôlées à 3 niveaux.

NiveauCléComportement
AutoriserallowS’exécute automatiquement sans boîte de dialogue de confirmation
DemanderaskNécessite l’approbation de l’utilisateur à chaque fois
RefuserdenyNe peut pas s’exécuter du tout (rejeté avec une erreur)

Les paramètres sont écrits dans .claude/settings.json. Placé à la racine du projet, il peut être partagé en équipe via git ; placé dans ~/.claude.json, il devient une configuration globale.

Priorité (de la plus haute à la plus basse) :
Projet .claude/settings.json
    > Global ~/.claude.json
        > Par défaut (tout est ask)

Structure de base de settings.json

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm run *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force*)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)"
    ]
  },
  "hooks": {
    "PreToolUse": [],
    "PostToolUse": []
  }
}

Noms d’outils et syntaxe des motifs

Les permissions sont écrites au format « NomOutil(motif d’argument) ».

Liste des principaux outils

Nom de l’outilDescription
ReadLecture de fichiers
WriteCréation de nouveaux fichiers
EditModification partielle de fichiers existants
BashExécution de commandes shell
GlobRecherche par motif de fichiers
GrepRecherche de contenu
WebFetchRécupération d’URL
AgentLancement d’un sous-agent

Syntaxe des motifs

"Read(**)"          // Autoriser la lecture de tous les fichiers
"Read(src/**)"      // Autoriser uniquement sous src/
"Read(*.md)"        // Autoriser uniquement les fichiers .md
"Bash(npm run *)"   // Autoriser uniquement les commandes commençant par npm run
"Bash(git *)"       // Autoriser toutes les commandes git
"Bash(rm -rf *)"    // Refuser rm -rf

** correspond à tous les chemins y compris les répertoires ; * correspond à un seul segment.

Schémas pratiques

Schéma 1 : Développement solo (relativement permissif)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm *)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git add*)",
      "Bash(node *)",
      "Bash(echo *)",
      "Bash(cat *)",
      "Bash(ls *)"
    ],
    "deny": [
      "Bash(rm -rf /)",
      "Bash(rm -rf ~*)",
      "Bash(git push --force *main*)",
      "Bash(git push --force *master*)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(rm *)"
    ]
  }
}

Schéma 2 : Développement en équipe (axé sur la sécurité)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm run lint)",
      "Bash(npm run test)",
      "Bash(npm run typecheck)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git branch*)"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Bash(git push -f*)",
      "Bash(git reset --hard*)",
      "Bash(git rebase *main*)",
      "Bash(git rebase *master*)",
      "Bash(DROP *)",
      "Bash(TRUNCATE *)",
      "Bash(curl * | bash)",
      "Bash(wget * | sh)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(git add*)",
      "Bash(npm install*)",
      "Bash(*deploy*)"
    ]
  }
}

Schéma 3 : Environnement de production (lecture seule)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git show*)",
      "Bash(cat *)",
      "Bash(ls *)",
      "Bash(ps *)",
      "Bash(df *)",
      "Bash(top *)"
    ],
    "deny": [
      "Write(**)",
      "Edit(**)",
      "Bash(git push*)",
      "Bash(git commit*)",
      "Bash(git reset*)",
      "Bash(rm *)",
      "Bash(mv *)",
      "Bash(*deploy*)",
      "Bash(*restart*)",
      "Bash(*kill *)"
    ],
    "ask": []
  }
}

En production, ceci est spécifié avec CLAUDE_SETTINGS=.claude/settings.production.json claude.

Schéma 4 : Génération de contenu uniquement (le schéma utilisé sur ce site)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Write(site/src/content/**)",
      "Write(content/**)",
      "Edit(site/src/content/**)",
      "Edit(content/**)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(node scripts/*)",
      "Bash(QIITA_TOKEN=* node scripts/qiita-publish.mjs)"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Edit(.env*)",
      "Read(.env*)"
    ],
    "ask": [
      "Bash(git add*)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(bash scripts/deploy.sh*)"
    ]
  }
}

La clé est de restreindre les écritures à un répertoire spécifique, comme avec Write(site/src/content/**).

Hooks : Exécuter des processus avant et après les permissions

Les Hooks sont un mécanisme qui exécute automatiquement des commandes avant et après l’exécution des outils. Ils peuvent être utilisés pour des vérifications de sécurité et du formatage automatique.

PreToolUse : Hook avant l’exécution

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git add*)",
        "hooks": [{
          "type": "command",
          "command": "git diff --cached --name-only | grep -E '^\\.env' && echo '🚨 Ajout de .env détecté !' && exit 1 || exit 0"
        }]
      },
      {
        "matcher": "Bash(git commit*)",
        "hooks": [{
          "type": "command",
          "command": "node scripts/secret-scan.mjs"
        }]
      },
      {
        "matcher": "Bash(rm*)",
        "hooks": [{
          "type": "command",
          "command": "echo '⚠️ Commande de suppression détectée. Exécution dans 5 secondes. Ctrl+C pour annuler.' && sleep 5"
        }]
      }
    ]
  }
}

Si une commande hook retourne le code de sortie 1, l’exécution de l’outil est bloquée. C’est le point le plus important.

PostToolUse : Hook après l’exécution

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{
          "type": "command",
          "command": "npx tsc --noEmit 2>&1 | head -20 || true"
        }]
      },
      {
        "matcher": "Bash(git commit*)",
        "hooks": [{
          "type": "command",
          "command": "git log --oneline -3"
        }]
      }
    ]
  }
}

PostToolUse est utilisé pour les vérifications post-exécution et les effets secondaires — par exemple, exécuter automatiquement des vérifications de types après des modifications de fichiers ou afficher les 3 dernières entrées du journal après un commit.

Collection de recettes de Hooks pratiques

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(npm install*)",
        "hooks": [{
          "type": "command",
          "command": "echo '📦 Ajout de paquet. Veuillez vérifier package.json.'"
        }]
      },
      {
        "matcher": "Bash(*deploy*)",
        "hooks": [{
          "type": "command",
          "command": "read -p '🚀 Sur le point de déployer. Continuer ? [y/N] ' ans && [ \"$ans\" = 'y' ] || exit 1"
        }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write(*.ts)|Edit(*.ts)",
        "hooks": [{
          "type": "command",
          "command": "npx eslint --fix $CLAUDE_TOOL_INPUT_FILE_PATH 2>/dev/null || true"
        }]
      }
    ]
  }
}

Modes de permission : Niveau de permission au démarrage

Vous pouvez également spécifier le mode lors du lancement de la commande claude.

# Mode normal (suit settings.json)
claude

# Approuver automatiquement toutes les opérations (dangereux ! uniquement pour les environnements de confiance)
claude --dangerously-skip-permissions

# Ignorer uniquement des opérations spécifiques
claude --allowedTools "Read,Grep,Glob"

# Mode non interactif (utilisé en CI/CD)
claude -p "Exécuter les tests et rapporter les résultats" --dangerously-skip-permissions

--dangerously-skip-permissions ne doit être utilisé que pour l’automatisation CI/CD ou des scripts d’automatisation parfaitement maîtrisés, et évité dans l’utilisation interactive quotidienne.

Priorité et écrasement des fichiers de configuration

Lorsque plusieurs fichiers de configuration existent :

~/.claude.json              ← Global (partagé entre tous les projets)
    +
.claude/settings.json       ← Projet (géré avec git)
    +
.claude/settings.local.json ← Écrasements personnels (gitignore recommandé)
    =
La configuration fusionnée est appliquée

Écrivez les paramètres additionnels personnels dans .claude/settings.local.json et ajoutez-le à gitignore. Pour éviter que les listes deny de l’équipe soient écrasées par des paramètres personnels, la conception sécurisée consiste à écrire les règles deny uniquement dans settings.json.

# Ajouter à .gitignore
.claude/settings.local.json

Les 5 pièges les plus courants

1. Se tromper dans les motifs génériques

// ❌ Ceci ne correspond qu'à la commande unique "git"
"Bash(git)"

// ✅ Correspond aussi à git suivi d'arguments
"Bash(git *)"
"Bash(git*)"  // Fonctionne aussi sans espace, mais * explicite est plus sûr

2. Oublier que deny a la priorité sur ask

// Avec cette configuration, Bash(rm -rf /tmp/test) est intercepté par deny et bloqué
// Il n'atteint jamais ask
{
  "deny": ["Bash(rm -rf*)"],
  "ask": ["Bash(rm*)"]  // ← rm -rf est traité par deny
}

3. Ne pas faire attention aux codes de sortie des hooks

# Si la commande du hook PreToolUse retourne toujours exit 0,
# les échecs de scan ne bloqueront pas l'exécution

# ❌ Passe même en cas d'erreur
"command": "node scan.mjs"

# ✅ Contrôler explicitement le code de sortie
"command": "node scan.mjs || exit 1"

4. Ajouter accidentellement settings.json à .gitignore

Certaines équipes ajoutent accidentellement settings.json—qu’elles veulent partager—à .gitignore. L’approche correcte est la configuration du projet sous git, seulement settings.local.json dans gitignore.

5. Oublier de changer manuellement la configuration de production

# ❌ Travailler en production avec la configuration quotidienne

# ✅ Changer explicitement la configuration avant les travaux en production
CLAUDE_SETTINGS=.claude/settings.production.json claude

Enregistrer un alias le rend plus difficile à oublier :

# ~/.bashrc or ~/.zshrc
alias claude-prod='CLAUDE_SETTINGS=.claude/settings.production.json claude'

Débogage de la configuration

Quand on ne comprend pas « pourquoi cette commande est-elle bloquée » :

# Vérifier la configuration actuelle
claude --print-settings 2>/dev/null || cat .claude/settings.json

# Vérifier quelle règle correspond (mode verbose)
claude --verbose -p "Exécuter git push"

Résumé : Bonnes pratiques pour la conception des permissions

1. Commencer par deny
   → Lister les commandes à ne jamais exécuter
   → rm -rf, git push --force, DROP TABLE sont indispensables

2. Ensuite configurer ask
   → Opérations d'écriture et de déploiement nécessitant confirmation

3. Allow pour tout le reste
   → Opérations de lecture et CI : tout en allow pour l'efficacité

4. Automatiser la sécurité avec les Hooks
   → Scan pré-commit, vérification de types automatique après modifications

5. Préparer des fichiers de configuration spécifiques aux environnements
   → settings.json (développement), settings.production.json (production)

Avec des permissions correctement configurées, vous cesserez de cliquer mécaniquement sur les boutons d’approbation et pourrez vous concentrer uniquement sur les opérations qui nécessitent vraiment une vérification. Consacrer 30 minutes à cette conception initiale sécurisera des centaines d’heures de travail futur.

Articles connexes

Références

#claude-code #permissions #security #hooks #settings #configuration

Passez votre flux Claude Code au niveau supérieur

50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.

Gratuit

PDF gratuit : aide-mémoire Claude Code en 5 minutes

Laissez simplement votre e-mail et nous vous enverrons immédiatement l'aide-mémoire A4 en PDF.

Nous traitons vos données avec soin et n'envoyons jamais de spam.

Masa

À propos de l'auteur

Masa

Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.