メインコンテンツへスキップ
APIキー、Claudeに渡してませんか?
レッスン 7 / 12|13分で読めます

APIキー、Claudeに渡してませんか?

「ちょっと貼って動かしてもらう」が一番危ない。APIキーは会話に貼った瞬間に漏れる。安全な渡し方を1つだけ覚える。

このレッスンで終わる頃には

  • なぜAPIキーをチャットに貼ってはいけないのか、腹落ちしてる
  • 「Claudeに見せずに使わせる」型を1つ覚えている
  • 自分の過去のClaude Codeに、漏れがないかチェックできる

正直に言うと、私はずっと貼ってきた

新しいAPIサービスのキーを取得すると、そのままClaudeとの会話に貼って、コードを書いてもらって、動かす。

OpenAIで画像生成したいとき。Geminiで翻訳させたいとき。Stripeのテストをしたいとき。

これ、多くの人が無自覚にやってます。私もそうでした。

そしてある日気づきました。チャットに貼った瞬間、そのキーは"ずっと残る"ことに。


何が起きるか

APIキーを1回チャットに貼ると、こうなります。

  • ローカルの会話ログ(~/.claude/projects/)に永久保存される
  • Anthropic側のサーバーログにも記録される(規約上、品質改善のため)
  • 過去の会話を引き継いで再開すると、コンテキストとして再ロードされる

つまり、コードリポジトリに間違ってcommitしたキーと同じ重さで扱う必要があります。

「自分のローカルにしかないから大丈夫」じゃない。漏れたものとして対処すべき。


私の例:1日のヒヤリハット

ある日、Claudeに「OPENAI_API_KEYが設定されているか確認して」と頼みました。

書かれたコマンドはこれ。

echo "API key set: ${OPENAI_API_KEY:+yes}${OPENAI_API_KEY:-no}"

実行した瞬間、ターミナルに164文字のキー全文が表示されました。

${VAR:-default} は変数があれば default ではなく値そのものを返す仕様。「設定済みならyes、未設定ならno」のつもりが、「設定済みなら値全部、未設定ならno」になってた。

画面に出した瞬間、もう手遅れ。会話ログに残ってます。

そこから過去のClaude Code履歴を全部スキャンしたら、現役のGemini APIキーまで過去の会話に残っていました。「漏れてない」と思ってたものが、自分の不注意で漏れてた。


安全な型を1つだけ覚える

これからは、原則を1つに絞ります。

APIキーをClaudeに見せない。AIには「環境変数を使うコードを書いて」と指示する。

`.env` をGitから外し、値を表示せずに環境変数の存在だけ確認する実画面です。

具体的にはこうなります。

やめた書き方:

「OpenAIで画像生成して。キーは sk-proj-xxxxx です」

新しい書き方:

「OpenAIで画像生成して。OPENAI_API_KEY は ~/.zshrc に設定済み」

差分は2行だけど、意味が全然違います。

AIが書くPythonコードは os.environ['OPENAI_API_KEY'] を読むだけなので、キーの値そのものはAIの目に触れない。


ステップ1:APIキーを ~/.zshrc に書く

ターミナルで:

open -e ~/.zshrc

開いたファイルの末尾に追記:

export OPENAI_API_KEY=sk-proj-(ここに貼り付け)
export GEMINI_API_KEY=AIzaSy(ここに貼り付け)

保存(Cmd+S)→ ターミナルで反映:

source ~/.zshrc

これで全Pythonスクリプトから os.environ['OPENAI_API_KEY'] で読める状態になります。


ステップ2:Claudeにはコードだけ書かせる

「OpenAIで画像生成するスクリプトを書いて。
APIキーは OPENAI_API_KEY という環境変数に設定済み。」

これでClaudeが書くコードはこんな感じになる:

from openai import OpenAI
client = OpenAI()  # 環境変数を自動で読む
result = client.images.generate(...)

キー値はClaudeの目に入らない。会話ログにも残らない。安全。


ステップ3:環境変数の確認は値を出さないコマンドで

「ちゃんと設定されてるかな?」を確認したいとき:

# 存在確認(値は出さない)
[ -n "$OPENAI_API_KEY" ] && echo "OK" || echo "NG"

# 識別したいなら部分表示
echo "先頭8文字: ${OPENAI_API_KEY:0:8}"
echo "長さ: ${#OPENAI_API_KEY}"

echo "$OPENAI_API_KEY"printenv OPENAI_API_KEY も、もう書かない。

ターミナルで .gitignore に .env を書き、git status --short で .env が表示されていない画面
`.gitignore` に `.env` を入れると、キーを置いたファイルはGitの候補に出てきません。
ターミナルで OPENAI_API_KEY の存在確認と長さ確認だけを実行し、値全体は表示していない画面
確認するのは存在と長さだけ。値そのものは画面に出しません。

サンドボックスも「読み取り」までは守ってくれない

Claude Codeには /sandbox というOSレベルの隔離機能があります。有効にすると、書き込みは作業ディレクトリとセッションの一時領域だけに制限されます。

ただし、読み取りは別です。既定では、AWSの認証情報ファイルやSSH鍵を含め、ほぼ全域を読める設定になっています。書き込みを絞っただけで、認証情報も守られていると思い込まないでください。

APIキー1つを環境変数で扱う分には、ここまでの型で足ります。ただし、クラウドの認証情報や複数のシークレットをまとめて守りたいなら、既定のサンドボックスだけでは足りません。読み取りそのものを絞る追加設定が必要になります。


自分の過去ログを棚卸ししてみる

不安なら、過去のClaude Codeログにキーが残ってないか、自分でスキャンできます。

CLAUDE_DIR="$HOME/.claude/projects"

echo "OpenAI:    $(grep -rho 'sk-proj-[A-Za-z0-9_-]*' $CLAUDE_DIR 2>/dev/null | awk 'length($0)>=40' | sort -u | wc -l) ユニーク値"
echo "Anthropic: $(grep -rho 'sk-ant-[A-Za-z0-9_-]*' $CLAUDE_DIR 2>/dev/null | awk 'length($0)>=40' | sort -u | wc -l) ユニーク値"
echo "Google:    $(grep -rhoE 'AIza[A-Za-z0-9_-]{30,}' $CLAUDE_DIR 2>/dev/null | sort -u | wc -l) ユニーク値"
echo "GitHub:    $(grep -rhoE 'gh[ps]_[A-Za-z0-9]{30,}' $CLAUDE_DIR 2>/dev/null | sort -u | wc -l) ユニーク値"

ヒットがあれば、それは「漏れていた」キー。


ヒットしたらどうするか

該当のサービスに行ってrotate(古いキーを無効化、新しいキーを作る):

サービスURL
OpenAIhttps://platform.openai.com/api-keys
Google AI (Gemini)https://aistudio.google.com/app/apikey
Anthropichttps://console.anthropic.com/settings/keys
GitHubhttps://github.com/settings/tokens

新しいキーを ~/.zshrc に書き直して source ~/.zshrc で反映。

もう使ってないサービスなら、プロジェクトごと削除するのが一番きれい。家ごと取り壊せば鍵は意味を失います。


機密情報を扱うときも同じ構造

このパターンは、AIに個人や取引先を特定できる情報、業務の記録を扱わせるときも同じになります。

社内の基幹システムの記録をチャットに貼って「まとめて」と頼む運用は、APIキーを貼るのと等価で危険。

機密情報を含むファイルを外部AIや外部APIに読ませる処理も、チャットに貼るのと同じく「外に送る」扱いで考えます。ファイル経由なら安全、という意味ではありません。

練習では、ダミーデータか公開情報だけを使います。本番の機密データを扱う場合は、ローカル処理、社内で承認された環境、契約・監査済みの基盤など、所属先の情報管理ルールに従ってください。

開発の現場で「秘密をコードに書かない」「外に送るデータを意識する」型を整えておくと、機密データを扱う前の安全確認にもつながります。


一行でまとめる

AIに渡したものは、コードに書いたのと同じ重さで扱う。

これ1つだけ覚えていれば、たぶんもう同じ事故は起きません。

次は Hooks と Skills。「また同じこと頼んでるな」を、自動と専用コマンドで肩の荷を下ろす話。

SourceARTICLE
OpenAI: APIキーの安全な扱い方(公式)

APIキー管理のベストプラクティス。環境変数、サーバー側保管、ローテーションの考え方

Webhelp.openai.com
help.openai.com/en/articles/5112595-best-practices-for-api-key-safety

明日のアクション

3つやってみてください。

  1. ~/.zshrc を開いて、使っているAPIキーを export OPENAI_API_KEY=... の形で書き込む(Claudeに直接は貼らない)
  2. source ~/.zshrc で反映、[ -n "$OPENAI_API_KEY" ] && echo OK で確認
  3. 過去のClaude Code会話ログを grep -rho 'sk-proj-[A-Za-z0-9_-]*' ~/.claude/projects/ で棚卸し、ヒットしたら該当サービスでrotate

この3手で、過去の漏れと今後の漏れの両方が止まります。