Перейти к основному содержимому
友田 陽大
Vercel in production
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境界までを実コードで解説します。

Published
Reading time
7 min read
Author
友田 陽大
Поделиться

シークレットの取り扱いは、地味ですが事故ると一発で致命傷になる領域です。「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月時点)に基づきます。上限・仕様は更新されるため、本番採用時は公式で最新値を確認してください。

友田

友田 陽大

Разработчик продукта, отмеченного премией Министра (METI). На TypeScript + Python + AWS создаю SaaS, цифровизацию промышленности и готовый к продакшену генеративный ИИ (RAG) — от требований до инфраструктуры и эксплуатации, в одиночку.

I can take on the implementation from this article as an engagement

Vercel apps, from design to production and cost optimization

Function design assuming Fluid Compute (safe global state, waitUntil, Cron), four-layer caching (ISR/CDN/Runtime Cache/Cache Components), safe deploys (preview/Promote/Instant Rollback/Rolling Releases), entry-point defense (Firewall/WAF/BotID), storage selection (Blob/Edge Config/Marketplace), and Active-CPU-billing-aware cost optimization. With experience running Next.js products on Vercel in production, I deliver fast, cheap, and secure.

Доступен как для проектной работы, так и для технического консультирования. Начните с бесплатной 30-минутной консультации.

最短ルート:カレンダーから直接予約

相談内容が固まっている方は、フォーム送信よりその場で日程を確定する方がスムーズです。下記から空き時間をお選びください。

  • 30分のオンライン無料相談
  • Google Meet / Zoom / Microsoft Teams
  • NDA 商談前締結可・無理な営業はいたしません
無料相談の空き枠を予約する

Также стоит прочитать