導入
「APIキーをそのままコードに書いてしまった」「うっかりGitHubにpushしてしまった」――この瞬間にプロジェクトの命運は尽きます。実際、漏れたAPIキーが数時間以内に悪用され、十万円単位の請求が来る事故は珍しくありません。だからこそ、環境変数の正しい管理は、非エンジニアであっても絶対に身に付けるべきスキルです。本記事では、ClaudeCodeを活用しながら、.envファイルの基本、.gitignoreとの連携、Cloudflare WorkersのSecretsを使った本番運用、CI/CDへのシークレット連携までを8,000字以上で丁寧に解説します。読み終える頃には「漏らさない開発」の基礎が身についているはずです。
結論
結論からお伝えすると、APIキー・パスワード・トークンは絶対にソースコードに書かず、必ず環境変数として外部に分離してください。ローカル開発では.envファイル、本番のCloudflare Workersではwrangler secretコマンドで登録するSecretsを使うのが社内標準です。ClaudeCodeに依頼するときも、「秘密情報は環境変数経由で読むコードにして」と明示するだけで、安全なパターンに沿った実装をしてくれます。重要なポイントは三つあります。第一に、.envは必ず.gitignoreに追加してリポジトリに含めないこと。第二に、.env.exampleを作って、必要な変数の「名前だけ」をチームで共有すること。第三に、本番ではClouflare Secretsなど安全な仕組みに登録し、ソースコードや設定ファイルに値そのものを書かないこと。これさえ守れば、漏洩事故のほとんどは防げます。逆に、JSバンドルに焼き込まれるNEXT_PUBLIC_系プレフィックスやVITE_系プレフィックスにはAPIキーを入れないこと、これも絶対NGとして覚えておいてください。
環境変数とは何か
環境変数(environment variable)は、OSやプロセスが読み書きできるキーと値のペアです。アプリケーションのコードから「外部に分離された設定値」として参照でき、コードの書き換えなしに本番・開発・テストで値を切り替えられるのが最大のメリットです。
たとえばデータベースの接続文字列。開発時はローカルのPostgreSQLにつなぎ、本番ではCloudflare D1につなぎたい。これをコードに直書きすると、デプロイのたびに書き換えが必要になり、ミスの温床になります。環境変数に逃がしておけば、コードは一切変えずに環境ごとに値を差し替えられます。
環境変数の典型的な用途は以下のとおりです。
- データベース接続情報(
DATABASE_URL) - 外部APIキー(
ANTHROPIC_API_KEY、STRIPE_SECRET_KEY) - アプリの実行モード(
NODE_ENV=production) - 機能フラグ(
FEATURE_NEW_UI=true) - ホストやポート番号(
PORT=3000)
.envファイルの基本
Node.js系のプロジェクトでは、.envという名前のファイルに環境変数を書き、dotenvや各フレームワーク(Next.jsなど)の機能で自動的に読み込みます。
ClaudeCodeに以下のように依頼します。
このNext.jsプロジェクトに.envファイルを導入してください。DATABASE_URL、ANTHROPIC_API_KEY、SESSION_SECRETの三つを管理し、.env.exampleも作成してください。.gitignoreにも.envを追加してください。
ClaudeCodeが生成するファイル例です。
.env(このファイルは絶対にGitに含めない)
DATABASE_URL=postgres://postgres:postgres@localhost:5432/myapp
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxx
SESSION_SECRET=super-long-random-string-please-rotate
.env.example(Gitに含めてOK)
DATABASE_URL=
ANTHROPIC_API_KEY=
SESSION_SECRET=
.gitignoreに追加される行
.env
.env.local
.env.*.local
Next.jsの場合、.envはサーバーサイドのみで読まれ、.env.localはNext.js特有の上書き用ファイルです。クライアントサイドに公開して問題ない値だけNEXT_PUBLIC_プレフィックスをつけます。
絶対NGパターン集
ここからは、絶対にやってはいけないパターンを具体的に紹介します。これは社内ルールでも厳しく禁止されている内容です。
NG1:APIキーをソースコードに直書き
// 絶対にやってはいけない
const client = new Anthropic({
apiKey: 'sk-ant-api03-xxxxxxxxxxx', // ❌
});
正しくは、
// 環境変数経由で読み込む
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
NG2:.envをGitにコミット
.gitignoreに登録し忘れた状態でコミットすると、たとえ後から削除してもGit履歴に残り、リポジトリのアクセス権を持つ人なら誰でも閲覧できます。履歴ごと削除しないと意味がないので注意してください。
NG3:クライアントサイドに焼き込まれる変数にシークレットを置く
Next.jsのNEXT_PUBLIC_、ViteのVITE_、Create React AppのREACT_APP_は、すべてブラウザに配信されるJSバンドルに埋め込まれます。ここにAPIキーやパスワードハッシュを入れたら、F12開発者ツールで誰でも読めます。絶対に置かないでください。
NG4:パスワードやPINのハッシュ値をJSコードに埋め込む
「ハッシュにしておけば安全」は誤解です。ハッシュ値が見えれば、辞書攻撃やレインボーテーブルで元の文字列を推測される可能性があります。認証は必ずサーバー側、もしくはCloudflare Accessに任せましょう。
NG5:本番のシークレットを開発環境で使い回す
本番のAPIキーを開発端末にコピーすると、紛失やマルウェア感染で漏れます。開発・ステージング・本番でキーを完全に分けるのが基本です。
Cloudflare Workersでの環境変数管理
社内標準のホスティング先であるCloudflare Workersでは、環境変数の扱いが少し独特です。wrangler.jsonc(旧wrangler.toml)に書ける「平文の変数」と、コマンドラインで登録する「Secrets」の二種類があります。
wrangler.jsoncの例:
{
"name": "my-app",
"main": "src/index.ts",
"compatibility_date": "2026-05-01",
"preview_urls": false,
"vars": {
"API_BASE_URL": "https://api.example.com",
"FEATURE_FLAG_NEW_UI": "true"
},
"d1_databases": [
{
"binding": "DB",
"database_name": "my-app-db",
"database_id": "xxxx"
}
]
}
varsに書けるのは「公開されても問題ない値」だけです。preview_urls: falseは社内ルールの必須項目で、Access認証バイパスを防ぐためにも必ず設定してください。
シークレット(APIキーなど)は、コマンドで個別に登録します。
wrangler secret put ANTHROPIC_API_KEY
# プロンプトが表示されるので、値を貼り付けてEnter
ClaudeCodeに以下のように依頼すれば、必要なシークレットを洗い出して登録手順をまとめてくれます。
このプロジェクトをCloudflare Workersにデプロイするにあたって、必要なシークレットを洗い出してください。それぞれのwrangler secret putコマンドを表にまとめてください。
コード側からはenv.ANTHROPIC_API_KEYのように、HonoやWorkersランタイムから渡されるenvオブジェクト経由でアクセスします。
import Anthropic from '@anthropic-ai/sdk';
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const client = new Anthropic({
apiKey: env.ANTHROPIC_API_KEY,
});
// ... 処理 ...
return new Response('OK');
},
};
interface Env {
ANTHROPIC_API_KEY: string;
DB: D1Database;
}
.gitignoreとセキュリティスキャン
.gitignoreに.envを追加するのは大前提ですが、それでも事故は起きます。GitHubには「Secret scanning」という機能があり、AWS・Stripe・Anthropicなど主要サービスのAPIキーがpushされると自動検知してくれます。Privateリポジトリ(社内ルールで必須)でも有効にしておきましょう。
ClaudeCodeに以下のように依頼すれば、誤コミットの確認もできます。
git logを遡って、過去のコミットに.envファイルやAPIキーらしき文字列が含まれていないかチェックしてください。見つかったら、削除と履歴クリーンアップの手順を提案してください。
万が一漏らしてしまった場合は、すぐに以下を実行します。
- 漏れた鍵を該当サービス側で即座に無効化(ローテーション)
- 新しい鍵を発行して環境変数に再設定
- Git履歴のクリーンアップ(
git filter-repoやBFG Repo-Cleanerを使用) - 履歴を強制push(チームに事前告知必須)
鍵のローテーションが最優先です。履歴を消しても、すでにダウンロードしている第三者がいる可能性を前提に行動してください。
CI/CDでのシークレット管理
GitHub Actionsでテストやデプロイを自動化する場合も、シークレットは適切に扱う必要があります。GitHubの「Settings → Secrets and variables → Actions」から登録すれば、ワークフロー内で${{ secrets.ANTHROPIC_API_KEY }}として参照できます。
ClaudeCodeに依頼するときは以下のように。
GitHub Actionsで、mainブランチへのpush時にCloudflare Workersへデプロイするワークフローを作成してください。CLOUDFLARE_API_TOKENとCLOUDFLARE_ACCOUNT_IDはGitHub Secretsから読み込み、wrangler.jsonc内のシークレットも自動で同期するようにしてください。
生成例:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
ワークフローのログにシークレットが出力されないよう、echo $SECRETのような無意味な出力は絶対に書かないでください。
ローカル開発でのベストプラクティス
.env.localを使い分ける:Next.jsなら.env.development.local、.env.test.localのように環境ごとに分割direnvを活用:ディレクトリに入ると自動で環境変数が読み込まれる便利ツール- チームで
.env.exampleを更新:新しい変数を追加したら必ずexampleにも反映 - 値はパスワードマネージャーに保管:1PasswordやBitwardenにチーム共有スペースを作る
- シークレットは年に最低一度ローテーション:定期的な交換で被害を最小化
ClaudeCodeに「.env.exampleを実際の.envと差分チェックして、足りない項目を出力して」と依頼すれば、追加し忘れを防げます。
型安全な環境変数の扱い(TypeScript)
TypeScriptで開発している場合、process.envはstring | undefinedなので、毎回チェックが面倒です。zodなどのスキーマライブラリで型安全に扱うのが現代的なやり方です。
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
ANTHROPIC_API_KEY: z.string().startsWith('sk-ant-'),
NODE_ENV: z.enum(['development', 'production', 'test']),
PORT: z.coerce.number().default(3000),
});
export const env = envSchema.parse(process.env);
これにより、必須の変数が設定されていなければ起動時にエラーになり、本番投入後の「変数忘れ」を未然に防げます。
実践チュートリアル:実プロンプト例集
プロンプト例1:環境変数の初期セットアップ
このNode.jsプロジェクトに.env、.env.example、.gitignore、env.tsを作成してください。env.tsではzodで型安全に環境変数を読み込み、必須項目が欠けていたら起動時にエラーで止めてください。
プロンプト例2:Cloudflare Workersへの移行
process.envで読んでいる環境変数を、Cloudflare Workersのenvバインディング経由に書き換えてください。Honoを使っています。
プロンプト例3:シークレット監査
ソースコード全体を走査して、APIキー、パスワード、トークンらしき文字列がハードコードされていないかチェックしてください。検出したら該当行を一覧化し、環境変数化の修正案を提示してください。
プロンプト例4:CI/CDシークレット連携
GitHub Actionsで使うシークレットの一覧を、Cloudflare WorkersのSecretsから自動で取得してsyncするスクリプトを書いてください。
プロンプト例5:環境別の設定切り替え
開発、ステージング、本番の三環境で異なるAPIエンドポイントを使い分けたいです。Next.jsのenv設定ファイルを分けて作成してください。
プロンプト例6:誤コミット復旧手順
.envファイルを誤ってコミットしてしまいました。git filter-repoを使った履歴クリーンアップ手順と、APIキーローテーションのチェックリストを作成してください。
FAQ
Q1. .envファイルの場所はどこが良い? プロジェクトのルート直下が原則です。サブディレクトリに置くと読み込み設定が複雑になります。
Q2. NEXT_PUBLIC_で公開してもいいのはどんな値? GoogleアナリティクスのIDなど、HTMLソースに書いても問題ない公開情報のみです。APIキーや内部URLは絶対に入れないでください。
Q3. .envに改行や特殊文字を入れたいです。
ダブルクオートで囲み、改行は\nでエスケープします。複数行の値はBASE64エンコードしてから入れるのが安全です。
Q4. Cloudflare WorkersのSecretsは何個まで登録できる? 2026年現在、Workersあたり最大128個まで登録可能です。実用上は十分な数です。
Q5. preview_urlsをtrueのままにしてはいけない理由は?
プレビューURLはCloudflare Accessの認証をバイパスする可能性があるためです。社内ルールで"preview_urls": falseが必須となっています。
Q6. ローカルでwrangler devを動かすときの環境変数は?
.dev.varsというファイル名でルートに置けば、wrangler devが自動で読み込んでくれます。これも必ず.gitignoreに追加してください。
Q7. 環境変数を変更したらアプリの再起動が必要?
ローカル開発では基本的にプロセス再起動が必要です。Cloudflare Workersではwrangler secret putの後、次回のリクエストから新しい値が反映されます。
まとめ
環境変数の管理は、地味でありながらプロジェクトの命を守る重要な作業です。本記事のポイントを振り返ります。APIキーやパスワードは絶対にソースコードに書かない。.envは.gitignoreに必ず追加する。本番ではCloudflare Secretsなど安全な仕組みに登録する。NEXT_PUBLIC_系のクライアント公開変数にはシークレットを入れない。CI/CDではGitHub Secretsを活用する。これらをClaudeCodeにサポートしてもらいながら習慣化すれば、漏洩事故のリスクは大幅に下がります。社内ルールに従い、preview_urls: falseの徹底、リポジトリのPrivate化、Cloudflare Accessによる認証ガードと組み合わせて、安全な開発体制を整えていきましょう。