メインコンテンツへスキップ
AMPL/ dev
開発系講座一覧

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

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

このレッスンで

終わる頃には、次ができるようになります

  • APIキーをチャットに貼ると会話ログとサーバーログに残る理由を説明できる
  • APIキーを~/.zshrcの環境変数に置きClaudeにはコードだけ書かせる型を実践できる
  • 環境変数の確認は値を表示せず存在確認や部分表示のコマンドで行うと判断できる

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

新しいAPIキーを取得すると、そのままChatに貼って動かす。

OpenAIで画像生成、Geminiで翻訳、Stripeのテスト。

多くの人が無自覚にやっている。私もそうだった。

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


何が起きるか

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

APIキーを1回貼ると起きること

1

ローカルの会話ログに残る

~/.claude/projects/

2

サーバーログにも記録される

Anthropic側・品質改善のため

3

再開時に再ロードされる

過去の会話を引き継ぐと

つまり、誤ってcommitしたキーと同じ重さで扱う必要がある。

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


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

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

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

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

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

${VAR:-default} は変数があれば値そのものを返す仕様。「yes/no」のつもりが「値全部/no」になってた。

画面に出た瞬間、もう手遅れ。会話ログに残る。

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


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

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

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

APIキーの渡し方

やめた書き方
「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には /sandbox というOSレベルの隔離機能があります。有効にすると、書き込みは制限されます。ただし、読み取りは別です。

/sandbox が守る範囲

書き込み
作業ディレクトリとセッションの一時領域だけに制限される。
読み取り
既定では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(古いキーを無効化、新しいキーを作る)。

OpenAI

https://platform.openai.com/api-keys

Google AI (Gemini)

https://aistudio.google.com/app/apikey

Anthropic

https://console.anthropic.com/settings/keys

GitHub

https://github.com/settings/tokens

rotate先

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

もう使わないサービスなら、プロジェクトごと削除するのが一番きれい。


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

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

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

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

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


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

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

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

セルフチェック

1. APIキーをClaudeのチャットに貼ると何が起きる?

2. ClaudeにAPIを使ったコードを書かせる安全な型は?

3. 環境変数の確認で書いてはいけないのは?

明日のアクション

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

このレッスンは役に立ちましたか?