⚠️

Claudeでdenyなどの設定を手軽に行うために!

に公開4

本記事のサマリ

Claude Code Editorを使っているなら、セキュリティ設定は必須です。環境変数や秘密鍵を無防備に晒していませんか?この記事では、Fishシェル関数を使って .claude/settings.local.jsonの初期設定を一発で行う方法を紹介します。毎回コピペする手間から解放されて、セキュリティも担保できる実用的なtipsです!

ちゃんとClaudeにdeny設定してますか?

Claude Code Editorを使い始めたとき、何も設定せずにそのまま使っていませんか?便利なツールだからこそ、セキュリティ設定を怠ると思わぬリスクを抱えることになります。

具体的には、以下のようなセキュリティリスクが考えられます:

  • 環境変数の漏洩: .envファイルに記載されたAPIキーやデータベースの認証情報が読み取られる
  • 秘密鍵の露出: SSH秘密鍵(id_rsaid_ed25519)がアクセス可能な状態になる
  • トークン情報の流出: 各種サービスのアクセストークンやシークレットキーが参照される
  • 予期しないコマンド実行: curlwgetによる外部への通信、データベースへの接続コマンドが実行される
  • 破壊的操作: rm -rfなどの削除コマンドが確認なしに実行される可能性

Claude自体は信頼できるツールですが、AI側が「必要だと判断した操作」を実行できる権限を持っている以上、明示的に制限をかけておくことは重要です。特に、環境変数や秘密鍵は開発者自身も普段意識していないファイルに含まれていることがあり、AIが文脈から「このファイルを読めば解決できる」と判断してアクセスしてしまうケースもあります。

私が使っているdeny/ask設定

私自身は以下のような設定を .claude/settings.local.jsonに記述しています:
(他にあった方が良いものが抜けていれば、コメントで教えてください🙇‍♂️)

{
  "permissions": {
    "allow": [
      "Bash(cat:*)",
      "Bash(tree:*)",
      "WebSearch"
    ],
    "deny": [
      "Read(**.env)",
      "Bash(sudo:*)",
      "Read(id_rsa)",
      "Read(id_ed25519)",
      "Read(**/*token*)",
      "Read(**/*key*)",
      "Write(.env*)",
      "Write(**/secrets/**)",
      "Bash(curl:*)",
      "Bash(wget:*)",
      "Bash(nc:*)",
      "Bash(npm uninstall:*)",
      "Bash(npm remove:*)",
      "Bash(psql:*)",
      "Bash(mysql:*)",
      "Bash(mongod:*)",
      "Bash(echo test)"
    ],
    "ask": [
      "Bash(rm:*)",
      "Bash(rm -rf:*)",
      "Bash(git push:*)",
      "Bash(git commit:*)",
      "Bash(git reset:*)",
      "Bash(git rebase:*)"
    ]
  }
}

設定のポイント

deny設定の考え方

最低限守るべきは、.envファイルと秘密鍵の読み取り禁止です。これらは多くのプロジェクトで機密情報を含むファイルの代表格です。**/*token***/*key*といったパターンマッチで、ファイル名に tokenkeyを含むファイル全般をブロックしています。

また、外部通信系のコマンド(curlwgetnc)も制限対象です。意図しない外部へのデータ送信を防ぐためです。データベース系のコマンド(psqlmysqlmongod)も、誤って本番DBに接続してしまうリスクを考えると、deny対象にしておく方が安全です。

ちなみに Bash(echo test)は一見不要に見えますが、これは設定が正しく反映されているかを確認するためのテスト用エントリです。Claudeに「echo testを実行して」と指示したときに拒否されれば、設定がちゃんと動いていることが分かります。

ask設定の考え方

rm系やGitの重要な操作は、実行前に確認が入るように askに設定しています。これにより、意図しない削除やコミットを防ぎつつ、必要なときには承認して実行できる柔軟性を保てます。

問題:毎回コピペするのは面倒

さて、この設定ファイルを用意したとして、新しいプロジェクトを作るたびに別のプロジェクトからコピペしてくるのは正直面倒です。しかも、コピー元のファイルがどこにあったか忘れたり、古いバージョンをコピーしてしまったりといったミスも起こりがちです。

理想は「プロジェクトルートで一発コマンドを叩けば、セキュリティ設定が整った状態になる」こと。そこで、Fishシェルの関数として設定の初期化スクリプトを作りました。(原始的!?💥)

Fishシェル関数で自動化する

以下が、実際に使っている claude_init関数です:

function claude_init --description "Initialize Claude settings.local.json in current directory"
    set target_dir ".claude"
    set target_file "$target_dir/settings.local.json"
    set template_file ~/.config/fish/conf.d/template.settings.local.json

    # Check if settings.local.json already exists
    if test -f $target_file
        echo "Error: settings.local.json already exists at $target_file" >&2
        return 1
    end

    # Check if template file exists
    if not test -f $template_file
        echo "Error: Template file not found at $template_file" >&2
        return 1
    end

    # Create .claude directory if it doesn't exist
    if not test -d $target_dir
        mkdir -p $target_dir
        if test $status -ne 0
            echo "Error: Failed to create .claude directory" >&2
            return 1
        end
    end

    # Copy template to target location
    cp $template_file $target_file
    if test $status -ne 0
        echo "Error: Failed to copy template file" >&2
        return 1
    end

    echo "✓ Successfully created $target_file"
end

この関数は以下の処理を行います:

  1. すでに .claude/settings.local.jsonが存在する場合はエラーを出して終了(誤って上書きを防ぐ)
  2. テンプレートファイルの存在確認
  3. .claudeディレクトリがなければ作成
  4. テンプレートをコピー

エラーハンドリングもしっかり入れているので、失敗した場合はどこで問題が起きたのかが分かりやすくなっています。

セットアップ方法

以下の2つのファイルを ~/.config/fish/conf.d/に配置します:

1. claude_init.fish

上記の関数定義をそのまま保存します。Fishは conf.dディレクトリ内の .fishファイルを自動で読み込むので、関数定義がそのまま有効になります。つまり、新しいシェルを開いた瞬間から claude_initコマンドが使えるようになります。

2. template.settings.local.json

先ほど紹介したdeny/ask設定のJSONファイルをそのまま保存します。これがテンプレートとして使われます。

セットアップ後は、任意のプロジェクトディレクトリで claude_initを実行するだけです:

cd /path/to/your/project
claude_init

すると、.claude/settings.local.jsonが自動で生成されます。簡単ですね。

実際に使ってみて

この仕組みを導入してから、新しいプロジェクトでのClaudeの初期設定が本当に楽になりました。プロジェクトを作ったらとりあえず claude_initを叩く、というルーチンが確立されて、「設定し忘れて危ない操作をしてしまった」というミスもなくなりました。

また、テンプレートファイルを一箇所で管理できるので、設定を見直したいときもそこを編集すれば次回以降のプロジェクトに反映されます。設定のバージョン管理がしやすくなったのも地味に嬉しいポイントです。

まとめ

Claude Code Editorは強力なツールだからこそ、適切な権限管理が重要です。deny/ask設定を整えることで、セキュリティリスクを大幅に減らせます。

そして、その設定を毎回手作業でコピペするのではなく、シェル関数として自動化することで、手間を減らしつつ設定忘れも防げます。今回紹介したFish関数はシンプルで力技ですが、忘れるよりは良いでしょう!笑

📣 改めて設定内容については人によって最適解が異なると思うので、「こんな設定も追加しておくといいよ」といったフィードバックがあれば、ぜひコメントで教えてください。

株式会社StellarCreate | Tech blog📚

Discussion

MizMiz

もし認識や前提に誤りがあったらすみません。

さて、この設定ファイルを用意したとして、新しいプロジェクトを作るたびに別のプロジェクトからコピペしてくるのは正直面倒です。

おそらくプロジェクト共通で利用したい権限設定を行うというユースケースだと思いますので、 ~/.claude/settings.json に権限設定を記載するのはいかがでしょうか?
その方が権限設定の更新が発生した際も漏れなく行うことができると思います。

https://docs.claude.com/en/docs/claude-code/settings

佐々木将一佐々木将一

Mizさん、コメントにて教えていただきありがとうございます!
(記事に追記させていただきました!)
前提として実務利用を考えており、他メンバーとClaudeの設定を共有するとなった際に下記2つの選択肢があるかと思います。

【選択肢】

  1. global設定を入社/参画時にお願いする
  2. project単位で管理することでシステム的に反映する

私の意見としては2の方が、システム的に確実に反映されるので安心だな...と考えております。
前提条件の記載がなく、申し訳ございません!
Mizさんのご意見もお伺いできますとありがたいです!🙇‍♂️

MizMiz

ご丁寧な返信ありがとうございます🙇
前提条件も踏まえて考えると、確かに2の選択肢が妥当だと思います。

しかし、以下のエラーハンドリングに少し問題があると感じました。

すでに .claude/settings.local.jsonが存在する場合はエラーを出して終了(誤って上書きを防ぐ)

実運用を考えると、恐らく「この権限のdenyが必要だった」、「この権限denyに追加したけどやっぱり過剰すぎたからaskに落とそう」という権限の更新が考えられます。そこも踏まえて考えると、以下の2つの改善の余地があるのかなと思いました。

1つ目に、権限設定処理(本記事でいうclaude_init関数)をgit管理し、CI/CDパイプラインに組み込む。
具体的に言うと、権限設定処理を更新したら、自動的に対象プロジェクトのリポジトリに対して、権限設定処理の更新コミットを行うようなシステムです。これにより、常に全プロジェクトが最新の権限設定を維持することができます。

2つ目に、権限設定の管理を.claude/settings.local.jsonではなく、managed-settings.jsonに変更する。
プロジェクト単位に他の設定を行うこともあるでしょうから、エラーハンドリングを入れた理由としても記載されているとおり、設定を上書きされてしまうと困ります。
ClaudeCodeの設定には、managed-settings.jsonというエンタープライズ管理ポリシー用の設定ファイルが存在するようです。(これについては私も知りませんでした)
ここに記載される設定は以下の特徴を持つようです。

  • IT/DevOps によってデプロイされる想定 (= 今回のような組織としての共通設定を管理する用)
  • 最も優先順位の高い設定でかつ、.claude/settings.local.json等で設定がオーバーライドされない (= 直接このファイルを編集しない限り、誤ってDeny -> Allowに設定が置き換わることがない)

https://code.claude.com/docs/ja/settings#設定の優先順位

そのため、このmanaged-settings.jsonを組織共通の設定ファイルとして運用し、権限設定処理では本ファイルを更新(または新規作成)するようにすれば、今回の要件は満たせるのかなと思います。

コメントにて長々とすみません、以上です🙇

佐々木将一佐々木将一

しっかりとした内容を共有いただきありがとうございます!!
拙い記事にも関わらず、補完いただき本当にありがたいです!!🙇‍♂️

確かにユースケースは初期化だけではなさそうですね。
それ以降のメンテも考えると、claude_initだけでは物足りなそうです。(特に今後、プロジェクトの初期化や反映を他メンバーがやることも考えると)

CI/CDでやりたい気持ちはありますが、結局それぞれのリポジトリで、settings.local.jsonの代わりにclaude_initスクリプトや設定ファイル専用のgit actionsファイルなど、結局別途(リポジトリで)管理するファイルが出てきそうですね。
これでは当初の、サクッとdeny反映済みのプロジェクトを用意する、という目的には反してしまいそうです。(reusable actionなども使えそうではありますが...そこまでするのもなと)

managed-settings.jsonの方が目的としてはかなりマッチしていそうと感じました!
Claude Code を使うPC に対して、システムレベルで managed-settings.json を導入することで、
ローカルでの settings.local.json やプロジェクトごとの設定ファイルよりも優先的に、権限設定を強制できるのですね。勉強になりました!🙇‍♂️

【以降は曖昧な情報源ですのでご注意ください】
ただ、調べた感じですとわからなかったのですが...このmanaged-settings.jsonによって組織でルールを管理する...というのが、下記のいずれかによって手間は変わってきそうですね🤔

  1. 組織で管理しているclaudeアカウントに自動適用
  2. 各PCにgit pullのように自動反映が可能

どうやらPCの特定箇所にファイルとして保持されるようですので、1ではなさそうなのかなと推察しております。
また試せ次第記事にしてみますね!ありがとうございます!