- 技術 💻
.envの使い方と注意点|APIキーを安全に管理する方法
.env(ドットエンブ)は、APIキーやデータベースのパスワードなど、コードに直接書きたくない設定値を別のファイルにまとめ、「環境変数」としてプログラムに読み込ませるための仕組みです。.env ファイルはGitで管理しない(.gitignoreに入れる)のが大原則で、代わりに値を空にした .env.example を共有します。
ただし、.envに書けば安全というわけではありません。特に、Next.jsやViteなどフロントエンドで使った値は、ブラウザに公開されます。この記事では、.envの書き方と言語・フレームワーク別の読み込み方に加えて、秘密情報が漏れる典型的なパターン、本番環境での管理方法、AIのコーディングツールを使うときの注意点までを解説します。
.envと環境変数の関係
環境変数は、OSやプログラムの実行環境が持っている「名前と値」の組です。プログラムは実行時に環境変数を読み取れるため、同じコードのまま、開発環境と本番環境で違う値を使うことができます。
export OPENAI_API_KEY=sk-xxxx # 環境変数を設定(Mac・Linux)
node app.js # プログラムから読み取れる
毎回コマンドで設定するのは手間なので、値をファイルに書いておき、起動時にまとめて環境変数として読み込むのが .env です。
# .env
OPENAI_API_KEY=sk-xxxx
DATABASE_URL=postgres://user:password@localhost:5432/app
PORT=3000
| 方法 | 問題点 |
|---|---|
| コードに直接書く | Gitに記録され、共有・公開した瞬間に漏れる。環境ごとに値を変えられない |
| .env に書く | .gitignoreに入れればGitには残らない。環境ごとに別の .env を用意できる |
.envの書き方
# コメントは # で書く
API_KEY=abc123
APP_NAME="My App" # スペースを含む値は引用符で囲む
GREETING='こんにちは'
EMPTY_VALUE=
=の前後にスペースを入れない(ライブラリによってはスペースも値として扱われる)- 変数名は、大文字とアンダースコアで書くのが慣習
- 値はすべて文字列として読み込まれる。数値や真偽値は、プログラム側で変換する(
"false"は文字列なので、そのままでは真として扱われることがある) - 複数行の値や、値の中の
#の扱いは、読み込むライブラリによって違うので、各ライブラリのドキュメントで確認する
言語・フレームワーク別の読み込み方
Node.js
node --env-file=.env app.js # Node.js 20.6以降は標準機能で読み込める
// ライブラリ(dotenv)を使う場合
import "dotenv/config";
console.log(process.env.OPENAI_API_KEY);
Python
# pip install python-dotenv
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.environ["OPENAI_API_KEY"] # 未設定ならエラーで気づける
os.environ.get("KEY") は未設定のとき None を返すため、必須の値は os.environ["KEY"] で取得して、設定漏れにすぐ気づけるようにするのがおすすめです。
Next.js・Vite(自動で読み込まれる)
Next.jsとViteは、プロジェクト直下の .env 系のファイルを自動で読み込みます。
| ファイル | 用途 | Gitに含めるか |
|---|---|---|
| .env | すべての環境の共通の既定値 | 秘密を含まないなら可 |
| .env.local | 自分のパソコンだけの値(秘密情報) | 含めない |
| .env.development | 開発時の値 | 秘密を含まないなら可 |
| .env.production | 本番ビルド時の値 | 秘密を含まないなら可 |
秘密情報は .env.local に書くのが基本です。Next.jsやViteのプロジェクトのひな形では、多くの場合 .local の付いたファイルがはじめから .gitignore に入っていますが、念のため確認しておきましょう。
Docker Compose
services:
app:
env_file:
- .env # この値がコンテナ内の環境変数になる
environment:
- NODE_ENV=production
Docker Composeには、2つの似た仕組みがあります。env_file はコンテナ内に渡す環境変数、プロジェクト直下の .env はdocker-compose.yml の中の ${変数} を置き換えるための値です。どちらの意味で使っているかを区別しておくと、「値が反映されない」ときに迷いません。
Spring Boot(Java)
Spring Bootは、.env を標準では読み込みません。application.properties に ${環境変数名} と書き、環境変数から値を受け取るのが一般的です。
spring.datasource.password=${DB_PASSWORD}
最も重要:フロントエンドで使った値は公開される
AIで個人開発を始めた人が、最もつまずきやすいポイントです。
# .env.local
NEXT_PUBLIC_OPENAI_API_KEY=sk-xxxx # × ブラウザに公開される
VITE_OPENAI_API_KEY=sk-xxxx # × ブラウザに公開される
OPENAI_API_KEY=sk-xxxx # ○ サーバー側だけで使える
Next.jsの NEXT_PUBLIC_、Viteの VITE_ で始まる変数は、ビルド時にJavaScriptのコードに埋め込まれ、ブラウザに配信されます。サイトを訪れた誰でも、開発者ツールでファイルの中身を見れば、キーを読み取れます。
| 接頭辞 | どこで使えるか | 書いてよい値 |
|---|---|---|
| なし | サーバー側(APIルート、サーバーコンポーネント、バックエンド) | APIキー、DBのパスワードなどの秘密 |
NEXT_PUBLIC_・VITE_ |
ブラウザ(公開される) | 公開してよい値だけ(サイトのURL、公開用のキーなど) |
外部APIの秘密キーを使う処理は、必ずサーバー側(APIルートなど)で行い、ブラウザからは自分のサーバーを経由して呼び出します。「ブラウザで直接APIを呼ぶとCORSエラーになる」ときに、キーを NEXT_PUBLIC_ に移して解決しようとするのは、典型的な漏えいのパターンです。
※Firebaseの設定値や、地図サービスの「公開用キー(リファラー制限付き)」のように、ブラウザで使う前提のキーもあります。サービスのドキュメントで、公開してよいキーかどうかを確認します。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「.envの使い方と注意点|APIキーを安全に管理する方法」
.gitignoreと.env.example
.gitignoreに追加する
# .gitignore
.env
.env.*
!.env.example
プロジェクトを作ったら、最初のコミットより前に .gitignoreに追加します。一度コミットしてしまったファイルは、後から.gitignoreに書いてもGitの管理から外れません。
git rm --cached .env # Gitの管理から外す(ファイル自体は残る)
git commit -m "chore: .envを管理対象から除外"
ただし、過去のコミットには値が残っています。一度でもpushした場合は、次の「漏れたときの対処」を行ってください。
.env.exampleで必要な項目を共有する
# .env.example(Gitで共有する)
OPENAI_API_KEY=
DATABASE_URL=postgres://user:password@localhost:5432/app
PORT=3000
どんな環境変数が必要かを、値を空にしたり、ダミーの値にしたりして共有します。新しいメンバーは、これをコピーして自分の値を入れるだけで始められます。
cp .env.example .env
本番環境では.envファイルを使わない
本番のサーバーやクラウドでは、.envファイルを置くのではなく、各サービスの環境変数・シークレットの管理機能を使うのが一般的です。
| 環境 | 設定場所 |
|---|---|
| Vercel・Netlify | プロジェクトの設定画面の環境変数 |
| AWS | Secrets Manager、Systems Manager パラメータストア |
| Google Cloud | Secret Manager |
| Azure | Key Vault |
| GitHub Actions | リポジトリの Secrets |
| Docker(本番) | オーケストレーターのシークレット機能 |
これらは、アクセスできる人の制限、変更履歴、キーのローテーション(定期的な交換)の仕組みを持っています。
環境変数と.envの優先順位
多くのライブラリ(Node.jsのdotenv、Pythonのpython-dotenvなど)は、既定ではすでに設定されている環境変数を.envの値で上書きしません。本番で環境変数を設定していれば、誤って.envが置かれていても本番の値が優先されます。逆に「.envを書き換えたのに反映されない」ときは、同じ名前の環境変数がシェルに残っていないか確認します。
起動時に、必要な環境変数をチェックする
環境変数の設定漏れは、そのAPIを呼んだときに初めてエラーになるため、原因がわかりにくくなりがちです。起動時にまとめて検証しておくと、すぐに気づけます。
// Node.js:zodで検証する例
import { z } from "zod";
const env = z.object({
OPENAI_API_KEY: z.string().min(1),
DATABASE_URL: z.string().url(),
PORT: z.coerce.number().default(3000),
}).parse(process.env); // 足りなければ起動時にエラー
Pythonでは、pydantic-settings を使うと、型の変換と検証をまとめて行えます。
秘密情報が漏れる、よくあるパターン
| パターン | 対策 |
|---|---|
| .envをGitにコミットした | プロジェクト作成時に.gitignoreへ追加。コミット前に git status で確認 |
NEXT_PUBLIC_・VITE_ に秘密キーを入れた |
秘密キーはサーバー側だけで使う |
| ログやエラーメッセージに環境変数を出力した | console.log(process.env) のような出力をしない。ログに出す値を限定する |
| スクリーンショットや画面共有に写った | .envを開いたまま共有しない |
| チャットやAIへの質問にキーを貼った | 質問するときは値を伏せる |
| Dockerイメージに.envを含めた | .dockerignore に .env を追加する |
GitHubのシークレットスキャンとプッシュ保護を有効にしておくと、既知の形式のキーを含むpushを止めてくれます。
AIのコーディングツールに.envを読ませない
AIのコーディングエージェントは、プロジェクトのファイルを読んで作業します。.envの中身がAIへの入力に含まれないよう、各ツールの除外設定を使います。
// Claude Code:.claude/settings.json
{
"permissions": {
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
Cursorなど他のツールにも、特定のファイルを読み込ませない設定(.cursorignoreなど)があります。AIが書いたコードに、キーが直接書き込まれていないかも、コミット前に確認しましょう。
漏れてしまったときの対処
キーがGitHubなどに公開された場合、ファイルを消すより先に、キーを無効化します。公開リポジトリは、数分以内に自動収集される可能性があります。
- 発行元のサービスで、キーを無効化(削除)する
- 新しいキーを発行し、.envや本番環境の設定を更新する
- 利用履歴を確認し、不正利用がないか調べる
- 必要に応じて、Gitの履歴からも削除する
Gitの履歴から消しても、すでにコピーされたキーは使えてしまいます。無効化が最優先です。
よくある質問
Q. .envファイルは暗号化されていますか? A. されていません。ただのテキストファイルです。パソコン自体のセキュリティ(ディスクの暗号化、画面ロック)で守られている前提で使います。
Q. .envをチームで共有したいときはどうすればいいですか? A. チャットやメールで送るのは避け、パスワード管理ツールの共有機能や、クラウドのシークレット管理サービスを使います。
Q. .envを書き換えたのに、値が変わりません。
A. 多くの場合、プログラムの起動時に一度だけ読み込まれるため、再起動が必要です。Next.jsの NEXT_PUBLIC_ の値はビルド時に埋め込まれるため、再ビルドが必要です。同じ名前の環境変数がシェルに設定されていると、そちらが優先されることもあります。
Q. .envとconfigファイル(config.jsonなど)はどう使い分けますか? A. 秘密情報と、環境ごとに変わる値は環境変数(.env)へ、秘密でなく全環境で共通の設定はconfigファイルへ、という分け方が一般的です。
まとめ
- .envは、秘密情報や環境ごとの値を、コードから分けて環境変数として読み込む仕組み
- .gitignoreに最初から追加し、必要な項目は .env.example で共有する
NEXT_PUBLIC_・VITE_の値はブラウザに公開される。秘密キーはサーバー側だけで使う- 本番では.envファイルではなく、クラウドのシークレット管理機能を使う
- 起動時に必要な環境変数を検証し、設定漏れにすぐ気づけるようにする
- AIツールには.envを読ませない設定を。漏れたらまずキーを無効化する
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「.envの使い方と注意点|APIキーを安全に管理する方法」
株式会社RJCでは、AI駆動開発の現場でも、秘密情報の扱いのような基本を大切にしています。こうした知識を仲間と共有しながら、一緒に成長を楽しんでいます。
株式会社RJC ― SI事業・SES事業・AI駆動開発。未経験からエンジニアに育てるのが得意な会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。