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

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には「環境変数を使うコードを書いて」と指示する。

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

やめた書き方:

「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 も、もう書かない


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

不安なら、過去の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に患者IDや診療情報を扱わせるときも同じになります。

カルテのテキストをチャットに貼って「まとめて」と頼む運用は、APIキーを貼るのと等価で危険

正しいのは、「カルテファイルから読み込んで処理する関数を書いて」と頼むこと。AIが書くコードがファイルを読みに行くだけで、AIの目に直接データが触れない設計にする。

開発の現場で型を整えておくと、医療データを扱うときに同じ型がそのまま使えます。


一行でまとめる

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

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

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

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

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

Webhelp.openai.com

明日のアクション

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手で、過去の漏れと今後の漏れの両方が止まります。