AIに鍵を握らせる前に。初心者がまず守る“事故らせない”5つの安全対策
Claude Codeに作業を任せる前の超入門。APIキー漏洩・危険コマンドの暴走・本番削除を防ぐ最小設定を、僕の失敗談つきでやさしく解説します。
「このプロジェクト、ざっと整理しといて」
軽い気持ちでそう打ち込んで、コーヒーを淹れに行きました。戻ってきたら、ターミナルが rm -rf を実行する一歩手前で止まっていた。承認ボタンに、僕の指が無意識に伸びかけていたんです。
あのとき「はい」を押していたら、.env も設定ファイルも、まとめて消えていました。
Claude Codeは賢い。けれど賢さと安全は、まったくの別物です。むしろ賢くて手が速いぶん、間違った方向にも全力で走る。包丁がよく切れるほど、扱いを覚える前にケガをするのと同じですね。
この記事は、初心者が最初に押さえるべき安全対策だけに絞ります。難しい話は後回し。まず守る5つを、僕のやらかしと一緒にやさしく書きます。
そもそも、何がそんなに危ないの?
普通のテキストエディタは、文字を表示するだけです。でもClaude Codeは違う。あなたのパソコンの中で、こんなことが「できてしまう」道具です。
- ファイルを読む、書く、消す
- ターミナルのコマンドを実行する(
rmもできる) - ネットにアクセスして、外のサービスに投稿する
しかもこれ全部、あなたが「はい」と承認すれば動きます。問題は、承認ボタンを何十回も押すうちに中身を見なくなること。「はいはい、OK」のリズムに乗った瞬間、危ない操作がするっと通り抜けます。
だから安全対策って、気をつけることじゃないんです。気をつけなくても事故らない仕組みを、先に作っておくこと。順番に見ていきましょう。
こんな場面でヒヤッとする(3つ)
初心者がやりがちな「危ない場面」を3つだけ。どれも特別なことはしていません。
場面1:エラーを直してほしくて、ログを全部貼る
「このエラー直して」と頼むとき、ターミナルに出た文字を全部コピペしますよね。でもそのログの中に、DATABASE_URL=postgresql://user:本物のパスワード@... みたいな行が紛れていることがある。AIに渡したつもりが、会話の履歴にもログにも、生のパスワードが残ります。
場面2:「全部おまかせ」モードで放置する
承認が面倒で、確認なしで何でも実行できるモードにして、席を立つ。AIが良かれと思って git push --force を叩き、チームの誰かの作業が吹き飛ぶ。悪気はゼロ。でも結果は最悪です。
場面3:似た名前のDBを取り違える
myapp_dev と myapp_prod。一文字違いです。「DBの古いデータ消しといて」とだけ頼んで、AIがどっちに繋がっているか確認しなかったら——消えるのは本番のお客さんのデータかもしれません。
3つに共通するのは、人間が「うっかり」した瞬間にAIが全力で実行すること。なら、うっかりしても大丈夫にしておけばいい。それが対策です。
僕がやらかした失敗3つ
偉そうに書いていますが、僕も最初は事故だらけでした。正直に3つ白状します。
ひとつ目。Qiitaへの自動投稿を作っていたとき、トークンをプロンプトに直接貼りました。 「QIITA_TOKEN=xxxx を使って投稿して」と。動いたので満足していたんですが、後で気づいた。その文字列、会話ログにも、裏で動く小さなAI(サブエージェント)の履歴にも残るんです。慌ててトークンを作り直しました。今思うと冷や汗ものです。
ふたつ目。調査のために「.env の中身を確認して」と頼みました。 AIは素直に全部読み上げてくれました。APIキーもDBのパスワードも、ぜんぶ画面とログに。読ませた瞬間、それはもう「漏れた」のと同じです。.env は人間の僕ですら、普段は開きません。
みっつ目。趣味プロジェクトのゆるい設定を、仕事のリポジトリにコピーしました。 結果、仕事側であるべき「本番への書き込み禁止」が、趣味用のゆるさで上書きされていた。事故る前に気づきましたが、設定の使い回しは本当に危ないです。
どれも、知識がなかったというより、仕組みで止めていなかったのが原因でした。ここからが本題です。
守るのはこの5つ。順番にやればいい
対策1:APIキーは「コードの外」に置く
いちばん大事です。APIキーやトークンは、絶対にコードやプロンプトに直接書かない。.env という専用ファイルに隔離して、それをGitの管理から外す。これだけで漏洩の大半は防げます。
まず、やってはいけない例から。
// NG: ソースコードに直書き(コミットしたら即アウト)
const client = new Anthropic({ apiKey: "本物のAPIキーを直接貼る" });
// NG: プロンプトに混ぜる
// 「QIITA_TOKEN=本物のトークン を使って投稿して」← 僕がやらかしたやつ
正しくは、.env というファイルに鍵をまとめます。
# .env (このファイルはGitに上げない。自分のパソコンにだけ置く)
ANTHROPIC_API_KEY=ここに本物の値
QIITA_TOKEN=ここに本物の値
DATABASE_URL=postgresql://...
そして、その .env を「Gitが絶対に拾わない」ように宣言します。これが命綱。
# .gitignore に必ず書く(鍵をうっかりコミットしない保険)
.env
.env.*
!.env.example # サンプルだけは共有してOK
*.pem
*.key
*-service-account.json # クラウドのサービスアカウント鍵も忘れずに
チームに「どんな鍵が必要か」だけ伝えたいときは、値を空にしたサンプルを置きます。
# .env.example (これはGitに上げてOK。中身は空っぽ)
ANTHROPIC_API_KEY=
QIITA_TOKEN=
DATABASE_URL=
コードからは、ファイルの値を直接書かずに「環境変数」として読み込みます。鍵の現物はコードのどこにも現れません。
// OK: 環境変数から読む。値はコードに一切書かない
import { config } from "dotenv";
config();
const token = process.env.QIITA_TOKEN;
if (!token) {
// 鍵が無ければ、値ではなく「設定し忘れてるよ」とだけ伝える
throw new Error("QIITA_TOKEN が未設定です。.env を確認してください。");
}
ポイントはひとつ。鍵の現物が触れるのは .env の中だけ。コードもプロンプトもログも、鍵の「名前」しか知らない状態にする。これが基本のキです。
対策2:危険なコマンドを“自動承認”させない
次に、rm -rf(一括削除)や git push --force(チームの作業を上書き)みたいな取り返しのつかないコマンド。これらは「実行前に必ず人間に聞く」か「そもそも実行不可」に設定しておきます。
Claude Codeには、コマンドごとに「OK/要確認/禁止」を決められる仕組みがあります。.claude/settings.json にこう書きます。
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "default",
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(rm -rf*)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(curl * | bash)"
],
"ask": [
"Write(**)",
"Edit(**)",
"Bash(git commit*)",
"Bash(git push*)"
]
}
}
読み方はシンプルです。3つの箱に振り分けるだけ。
| 箱 | 意味 | 入れるもの |
|---|---|---|
allow | 確認なしで実行OK | 読むだけの安全な操作 |
ask | 毎回ちゃんと聞く | 書き込み・コミット・プッシュ |
deny | 一切やらせない | 削除・force push・本番DB |
迷ったら、こう覚えてください。読むだけは allow、書くなら ask、消すなら deny。 最初はガチガチに絞っておいて、「あ、これは安全だな」と分かった操作だけ、後から ask や allow に格上げする。逆向き(最初ゆるく、後で締める)は事故ってからになるので、絶対に締める方向から始めます。
対策3:読み書きの“範囲”を絞る
対策2の deny をよく見てください。先頭にこんな行があります。
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
これは「.env と secrets フォルダは読むことすら禁止」という設定です。僕がやらかした「.env を読ませる」事故は、この一行があれば起きませんでした。「確認して」と頼んでも門前払いになるからです。
範囲を絞るとは、見せていい場所と見せちゃいけない場所を、最初に線引きしておくこと。鍵の入ったフォルダ、本番の設定、お客さんのデータ。これらを「そもそも触れない」ようにしておけば、うっかり依頼しても安全です。
加えて、絶対に編集してほしくないファイルは、プロジェクトのルール(CLAUDE.md)にも日本語で書いておくと安心です。
## 編集禁止ファイル(CLAUDE.md に書く)
以下は絶対に編集しない。必要なら必ず僕(人間)に確認すること。
- .env (鍵・パスワードを含む)
- wrangler.toml (本番の公開設定)
- .github/workflows/*.yml (自動デプロイの設定)
設定ファイルで機械的にブロックし、ルール文でAIにも意図を伝える。二段構えにしておくと、抜け漏れが減ります。
対策4:秘密情報をログに出さない
これは設定というより、ちょっとした書き方のクセです。エラーメッセージを書くとき、鍵の「値」を一緒に出力しないこと。
// NG: エラーログにAPIキーがそのまま出てしまう
throw new Error(`認証失敗: token=${process.env.TOKEN}`);
// OK: 値は出さず、どこを見ればいいかだけ伝える
throw new Error("認証失敗: TOKEN 環境変数を確認してください");
たった1行の違いですが、上はログを誰かに見せた瞬間に鍵が漏れます。
そしてもうひとつ。AIにログを渡すとき、生のまま貼らない。鍵やパスワードの行は、値を伏せ字に置き換えてから渡します。
# こう書き換えてから渡す。AIは「DB接続情報がある」構造だけ分かればいい
DATABASE_URL=***マスク済み***
QIITA_TOKEN=***マスク済み***
「渡していいもの」と「ダメなもの」を、ざっくり表に。これを CLAUDE.md に貼っておくと、頼むたびに判断基準を思い出せます。
| 渡してOK | 渡したらダメ |
|---|---|
| エラーの種類、再現手順、ファイル名 | APIキー、パスワード、セッションのcookie |
.env.example、設定項目の「名前」 | 本番DBのURL、お客さんのデータ |
| 伏せ字に置き換えたログ | 実トークン、サービスアカウントの.jsonファイル |
対策5:本番のものは“別扱い”にする
最後。練習用(開発)と本番を、はっきり分けます。myapp_dev と myapp_prod の取り違えを防ぐには、本番への書き込みにひと手間かけさせるのが効きます。
// scripts/db-query.mjs
const env = process.env.NODE_ENV ?? "development";
// 本番に書き込もうとしたら、専用フラグが無いかぎり止める
if (env === "production" && process.argv.includes("--write")) {
console.error("本番への書き込みには --force-production フラグが必要です。");
process.exit(1);
}
「うっかり本番」を、フラグというひと手間で物理的にブロックする。この面倒くささが命綱です。本番のデータは、消したら戻りません。
始めるなら、ここから(手順)
5つ全部を今日やる必要はありません。順番にやれば30分で終わります。
- プロジェクトに
.envを作り、鍵を全部そこへ移す .gitignoreに.envを追加する(対策1).claude/settings.jsonを作り、denyにrm -rfと.envの読み取りを入れる(対策2・3)- 書き込み・コミット系を
askに入れる(対策2) CLAUDE.mdに「渡していい/ダメ」の表と編集禁止ファイルを貼る(対策4)
最初の3ステップだけでも、冒頭の rm -rf 事故と .env 漏洩は止まります。完璧を目指さず、まず一個。それで十分前進です。
権限設定をもっと細かく詰めたくなったら Claude Code の権限設定ガイド を、実際にあった事故の生々しい話が知りたければ Claude Code のセキュリティ失敗事例 を読んでみてください。設定の正確な仕様は、いつも公式ドキュメントが一番です。
実際に試した結果
冒頭の rm -rf ヒヤリ以来、僕は「AIを信用するかどうか」で悩むのをやめました。代わりに見るのは、どの門番で止まったかです。
deny に .env の読み取りを足したら、「環境変数を確認して」と頼んでもAIが素直に引き下がるようになりました。あの気まずい「全部読み上げ」が、二度と起きません。
正直、設定を書いた日は「やりすぎかな」と思いました。でも逆でした。ガードがあるからこそ、安心して手を抜ける。承認ボタンを軽い気持ちで押せるのは、危ない操作が先に deny で止まると分かっているからです。賢いAIを使いこなそうと頑張るより、転んでもケガしない床を先に敷く。これが一番ラクで速い、というのが今の僕の結論です。
まとめ
初心者がまず守るのは、この5つだけで十分です。
| 守ること | やり方 |
|---|---|
| APIキーを漏らさない | .env に隔離 + .gitignore |
| 危険コマンドを暴走させない | deny に rm -rf / force push |
| 読み書きの範囲を絞る | .env・secretsを deny、本番ファイルは編集禁止 |
| 秘密情報をログに出さない | 値を出さない・伏せ字で渡す |
| 本番を別扱いにする | フラグで本番書き込みをブロック |
セキュリティと聞くと身構えますが、やることは「事故が起きない仕組みを先に作る」だけ。一度入れれば、あとは放っておいても守ってくれます。今日30分。それで未来の大事故をひとつ消せます。
もし「うちのチームでどこまで縛ればいい?」と迷ったら、教材やサポートも用意しています。まずは 教材一覧 をのぞいてみてください。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
Claude Code権限セーフティラダー: 初心者がallowを広げる順番
Claude Codeの権限をread-onlyからbuild、限定編集、deploy確認まで段階的に広げる安全な運用手順。
Claude Code Small PR Proof Pack: 小さなPRをレビュー可能にする証拠セット
Claude Codeの小さなPRに、差分・検証・公開URL・CTA・rollbackを添える実務チェックリスト。
Claude Codeのコミット前レビューゲート: 差分、テスト、CTAをまとめて止める型
Claude Codeでcommit前に差分をレビューする実践手順。build、公開URL、CTA、Gumroadリンク、未翻訳本文を検知します。