iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🔓

Sharing My Claude Code Permission Settings (settings.json)

に公開

Hi, I'm Tomada.

For those who are wondering "how much should I loosen Claude Code's permission settings?", I'll share the settings I actually use in my personal development.

Prerequisites

These permission settings assume an environment like the following:

  • Focused on personal development
  • Git management is a prerequisite (can revert if something goes wrong)
  • Node.js development is the main focus
  • Want to develop with a priority on speed by reducing wait time for approvals

If you are working in team development or on a machine close to a production environment, I recommend more conservative settings.

Overall Settings

This is the ~/.claude/settings.json configuration I use.

{
  "permissions": {
    "defaultMode": "acceptEdits",
    "allow": [
      "Bash(mkdir *)",
      "Bash(touch *)",
      "Bash(ls *)",
      "Bash(tree *)",
      "Bash(mv *)",
      "Bash(cp *)",
      "Bash(cat *)",
      "Bash(grep *)",
      "Bash(find *)",
      "Bash(echo *)",
      "Bash(npm *)",
      "Write(*)",
      "Bash(git add *)",
      "Bash(git commit *)",
      "Bash(git push *)",
      "Bash(git pull *)",
      "Bash(git branch *)",
      "Bash(git checkout *)",
      "Bash(git status *)",
      "Bash(git log *)",
      "Bash(git diff *)",
      "Bash(git fetch *)",
      "Bash(gh pr *)",
      "WebFetch(domain:github.com)",
      "WebFetch(domain:npmjs.org)"
    ],
    "deny": [
      "Bash(sudo *)",
      "Bash(git reset *)",
      "Bash(git rebase *)",
      "Read(id_rsa)",
      "Read(id_ed25519)",
      "Read(**/*token*)",
      "Read(**/*key*)",
      "Bash(rm -rf *)",
      "Bash(rm -rf /)",
      "Bash(rm -rf ~)",
      "Bash(rm -rf ~/*)",
      "Bash(rm -rf /*)",
      "Read(.env)",
      "Read(.env.local)",
      "Read(.env.development)",
      "Read(.env.production)",
      "Read(**/.env)",
      "Read(**/.env.local)",
      "Read(**/.env.development)",
      "Read(**/.env.production)",
      "Read(**/*secret*)",
      "Write(.env)",
      "Write(.env.local)",
      "Write(.env.development)",
      "Write(.env.production)",
      "Write(**/.env)",
      "Write(**/.env.local)",
      "Write(**/.env.development)",
      "Write(**/.env.production)",
      "Write(**/*secret*)"
    ],
    "ask": [
      "Bash(rm *)",
      "Bash(chmod *)",
      "Bash(wget *)",
      "Bash(curl *)",
      "Bash(git merge *)"
    ]
  }
}

Key Points of the Settings

Here, I will explain the points I focus on with these settings.

defaultMode: acceptEdits

"defaultMode": "acceptEdits"

Automatically approves file reading and editing. This is because being asked for approval every time the basic action of reading and editing code is performed would disrupt the development flow.

File operations are basically allowed

"Bash(mkdir *)",
"Bash(touch *)",
"Bash(ls *)",
"Bash(mv *)",
"Bash(cp *)",

These are mainly references or minor operations. I don't feel the need to ask for confirmation every time, so I allow them all.

Development tools are also allowed

"Bash(npm *)",

Commands frequently used during development, such as npm install or npm run test, are allowed.

Note that I deliberately excluded npx. This is because it allows downloading and immediately executing any npm package, which carries the risk of executing unintended code.

Git operations are also allowed (but history rewriting is denied)

"Bash(git add *)",
"Bash(git commit *)",
"Bash(git_push *)",

While general articles recommend putting git push or git commit in ask, I set them to allow. This is because I leave the verification of diffs and logs to Claude Code.

On the other hand, operations that rewrite history are blocked with deny.

"Bash(git_reset *)",
"Bash(git_rebase *)",

Protecting sensitive files with deny

"Read(.env)",
"Read(**/*secret*)",
"Read(**/*token*)",
"Read(**/*key*)",

Files that may contain environment variables or API keys are blocked for both reading and writing.

The point is that .env.example and .env.sample are not included in deny. This is because these are template files and do not contain sensitive information.

Blocking rm -rf with multiple patterns

"Bash(rm -rf *)",
"Bash(rm -rf /)",
"Bash(rm -rf ~)",
"Bash(rm -rf ~/*)",
"Bash(rm -rf /*)",

Commands that forcibly delete entire directories are blocked using multiple patterns.

Operations requiring confirmation via ask

"ask": [
  "Bash(rm *)",
  "Bash(chmod *)",
  "Bash(wget *)",
  "Bash(curl *)",
  "Bash(git merge *)"
]
  • rm: While rm -rf is blocked by deny, regular deletion is allowed after confirmation.
  • chmod: Granting execution permissions could lead to unintended script execution.
  • wget / curl: I want to confirm before executing downloads from external sources.
  • git merge: Merging is confirmed because it carries the risk of incorporating unintended changes.

Cases Where This Setting Is Not Suitable

In the following cases, I recommend more conservative settings.

  • Team Development: Settings need to be unified among members.
  • High-Security Environments: Environments with strict compliance requirements, such as finance or healthcare.
  • Machines Close to Production: Environments containing connection information for production databases.
  • Beginners: For those who have not yet grasped how Claude Code operates.

For beginners, it is safer to use defaultMode: default to require confirmation for all operations and gradually loosen them once you understand what is happening.

Comparison with General Settings

The basic concepts of permissions and general setting examples are explained in detail in a separate article.

https://zenn.dev/tmasuyama1114/books/claude_code_basic/viewer/permission-optimization

While the article above recommends a "Balanced" setting, this article focuses on a "Development Efficiency Priority" type. Please use it as a reference according to your own situation.

Discussion