メインコンテンツへスキップ
友田 陽大
Vercel 本番運用
Vercel
セキュリティ
Next.js
TypeScript
型安全
CI/CD
アーキテクチャ設計

Vercel 環境変数・シークレット管理ガイド:3環境・NEXT_PUBLIC_の罠・OIDC鍵レス・型安全な境界

Vercel公式に忠実な環境変数・シークレット管理ガイド。production/preview/developmentの3環境とブランチ別上書き、NEXT_PUBLIC_によるブラウザ露出の罠、64KB上限とEdge 5KB制限、vercel env pullでのローカル同期、システム環境変数、OIDC鍵レスによる外部クラウド接続、Zodでの型安全なenv境界までを実コードで解説します。

公開日
読了時間
7分
著者
友田 陽大
シェア

シークレットの取り扱いは、地味ですが事故ると一発で致命傷になる領域です。「API キーが GitHub に漏れた」「NEXT_PUBLIC_ を付けたら本番のキーがブラウザに出ていた」——どれも数分で起きて、長く尾を引きます。

この記事は Vercel 環境変数の公式仕様に忠実に、3環境の使い分け・NEXT_PUBLIC_ の罠・OIDC 鍵レス・型安全な env 境界をまとめます。全体像は Vercel 本番運用ガイド、入口セキュリティは Firewall・WAF・BotID を参照してください。


3つの環境を使い分ける

Vercel の環境変数は環境ごとに値を変えられます。値は保存時に暗号化され、プロジェクトにアクセスできるメンバーに見えます。

環境いつ適用されるか用途
Production本番ブランチ(通常 main)へのプッシュ / vercel --prod本番のキー・接続文字列
Preview本番以外のブランチへのプッシュ / vercelステージングDB等。ブランチ別に上書き可
Developmentvercel dev / ローカルローカル開発用
# 環境ごとに値を登録
vercel env add DATABASE_URL production    # 本番DB
vercel env add DATABASE_URL preview       # ステージングDB
vercel env add DATABASE_URL development   # ローカルDB

# 特定ブランチだけ上書きしたいとき(preview)
# → ダッシュボードでブランチ指定。同名変数はブランチ別が優先される

重要な落とし穴環境変数の変更は、新しいデプロイにのみ適用されます。既存の本番デプロイは値が変わりません。「変えたのに反映されない」の大半はこれ——再デプロイしてください。

Preview のブランチ別上書き

Preview 変数は「全非本番ブランチ」か「特定ブランチ」に適用できます。ブランチ指定の変数は同名の一般 Preview 変数を上書きするので、全部を複製せず差分だけ定義すれば済みます。


NEXT_PUBLIC_ の罠(最重要)

最も多い、そして最も危険な事故が NEXT_PUBLIC_ 接頭辞です。

  • NEXT_PUBLIC_ を付けた変数は、ビルド時にバンドルへ埋め込まれ、ブラウザに露出します。
  • だから、API キー・DB 接続文字列・秘密鍵・サービスロールキーには絶対に付けない
  • 付けてよいのは「クライアントで読む必要がある公開値」だけ(公開可能な計測 ID、公開 API のベースURL など)。
// ❌ 絶対NG:秘密に NEXT_PUBLIC_ → ブラウザに丸見え
// NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_xxx

// ✅ サーバーでだけ読む(無印)
const stripeSecret = process.env.STRIPE_SECRET_KEY; // サーバー専用

// ✅ クライアントで読む公開値だけ NEXT_PUBLIC_
const ga = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID; // 公開してよい

Supabase の anon keyservice_role key の取り違え、NEXT_PUBLIC_ への秘密混入は、実際の脆弱性診断で頻出します(env リーク防止anon/service_role の露出)。「クライアントで読む必要が本当にあるか」を一段疑うのが防御です。


サイズ上限とランタイム差

  • 合計 64KB / デプロイ(全変数の合計。単一変数も 64KB 以下)。JWT・証明書のような大きな値も扱えます。
  • 対応ランタイム(64KB):Node.js / Python / Ruby / Go / PHP コミュニティランタイム。
  • Edge ランタイムは 1変数 5KB まで。Edge ミドルウェアで大きな値を読むなら注意。

ローカル開発:vercel env pull

ローカルでは .env.local(または vercel env pull が生成する .env)に開発用変数を置きます。

# Development 環境の変数をローカルへ同期
vercel env pull .env.local

# vercel dev なら自動で Development 変数をメモリに読み込む(pull不要)
vercel dev

.env*コミットしない.gitignore に必ず入れる)。Vercel CLI 経由のデプロイは .env 系を自動で無視しますが、Git 経由は .gitignore が頼りです。

@vercel/speed-insights / @vercel/analytics の罠:これらは**package.json の依存**に入れます。グローバルに入れて参照すると、特にモノレポでビルドエラーになります(可観測性)。


システム環境変数

Vercel は実行時に有用なシステム変数を注入します。

変数内容
VERCEL_ENVproduction / preview / development
VERCEL_URLこのデプロイの生成URL
VERCEL_GIT_COMMIT_SHAデプロイ元のコミット
VERCEL_REGION実行リージョン
// 環境で分岐(例:プレビューだけ noindex、本番だけ外部送信)
const isProd = process.env.VERCEL_ENV === "production";
if (!isProd) headers.set("X-Robots-Tag", "noindex");

OIDC 鍵レス:外部クラウドへ長命キーを置かない

AWS S3・SES、GCP、データベースなど外部リソースへアクセスするとき、長命のアクセスキーを環境変数に置くのは2026年では非推奨です。OIDC(OpenID Connect)連携で一時クレデンシャルを得ます。

  • Vercel の OIDC トークンを外部クラウドの IAM ロールが信頼し、鍵を保管せずに一時的な権限を得る。
  • 漏洩リスクが構造的に下がり、ローテーション運用も消える。
  • CI/CD(GitHub Actions → Vercel/AWS)も同じく OIDC 鍵レスに(OIDC 鍵レス CI/CD)。

どうしても長命キーが必要な場合は、最小権限に絞り、Production にのみ置き、定期ローテーションします。


Fluid Compute での秘密の扱い

Fluid Compute は1インスタンスで複数リクエストを並行処理します。

// ✅ 起動時に一度だけ読む(リクエスト非依存)
const apiKey = process.env.EXTERNAL_API_KEY!;

// ❌ リクエスト固有のトークンをモジュールスコープにキャッシュしない
// let userToken; // 別リクエストに漏れる

リクエストごとのトークン・ユーザー秘密は関数スコープのローカルに閉じます。


型安全な env 境界(Zod)

環境変数は「外部入力」です。起動時に Zod で検証して、未設定や形式不正をビルド/起動で落とします。これで「本番で env 未設定の 500」を未然に防げます。

// lib/env.ts — env を型安全な単一の真実源に
import { z } from "zod";

const schema = z.object({
  DATABASE_URL: z.string().url(),
  STRIPE_SECRET_KEY: z.string().startsWith("sk_"),
  NEXT_PUBLIC_GA_MEASUREMENT_ID: z.string().optional(),
});

// 起動時に検証(失敗したら即座に落ちる=本番で気づくより安全)
export const env = schema.parse(process.env);

process.env.X を直に散らさず、env.X 経由にすることで、型・必須・形式が一箇所で保証されます(型安全の徹底)。


本番チェックリスト(env・シークレット)

  • 3環境(production/preview/development)に値を整理
  • NEXT_PUBLIC_ に機密を付けていない(ブラウザ露出)
  • 変更後は再デプロイ(既存デプロイには反映されない)
  • .env* をコミットしていない
  • Edge で読む変数は 5KB 以内、合計 64KB 以内
  • 外部クラウドは OIDC 鍵レス、長命キーは最小権限+ローテーション
  • Fluid のグローバルにリクエスト固有の秘密を残さない
  • env を Zod で起動時検証(型安全な境界)

まとめ

シークレット管理は「派手さはないが、外すと一発」の領域です。

  1. 3環境を使い分け、変更は再デプロイで反映
  2. NEXT_PUBLIC_ に秘密を付けない(最重要)
  3. ローカルは vercel env pull.env はコミットしない
  4. 外部クラウドは OIDC 鍵レスで長命キーを消す
  5. env は Zod で型安全な境界にする

シークレット管理の監査・OIDC 鍵レス化・型安全な env 境界の導入を、案件として承ります。

本記事は Vercel 環境変数 公式ドキュメント(2026年6月時点)に基づきます。上限・仕様は更新されるため、本番採用時は公式で最新値を確認してください。

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事の実装を、案件として承ります

Vercel のアプリを、設計から本番運用・コスト最適化まで承ります

Fluid Compute を前提とした関数設計(グローバル状態の安全化・waitUntil・Cron)、4層キャッシュ(ISR/CDN/Runtime Cache/Cache Components)の設計、プレビュー/Promote/Instant Rollback/Rolling Releases の安全なデプロイ、Firewall/WAF/BotID の入口防御、Blob/Edge Config/Marketplace のストレージ選定、Active CPU 課金前提のコスト最適化まで。Next.js 製プロダクトを Vercel で本番運用してきた知見で、速く・安く・安全に伴走します。

プロジェクト単位(請負)・技術顧問のどちらにも対応可能です。まずは30分の無料技術相談から。

あわせて読みたい