{"id":27053,"plugin_id":"plugin_connector_690a90ec05c881918afb6a55dc9bbaa1","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-06T18:03:10.781Z","digest":"60fde6eb478c0a856498a2db5e973bcd2bdd10a390509106a44a02ba8912eb65","against":24838,"payload":{"description":"Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, Secret or Config variable types, OIDC tokens, or managing environment-specific configuration.","included_files":[{"relative_path":"agents/openai.yaml","size_in_bytes":105}],"name":"env-vars","skill_md_contents":"---\nname: env-vars\ndescription: Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, Secret or Config variable types, OIDC tokens, or managing environment-specific configuration.\nmetadata:\n  priority: 7\n  docs:\n    - \"https://vercel.com/docs/environment-variables\"\n    - \"https://vercel.com/docs/environment-variables/sensitive-environment-variables\"\n  sitemap: \"https://vercel.com/sitemap.xml\"\n  pathPatterns:\n    - '.env'\n    - '.env.*'\n    - '.env.local'\n    - '.env.production'\n    - '.env.development'\n    - '.env.test'\n    - '.env.production.local'\n    - '.env.development.local'\n    - '.env.test.local'\n    - '.env.example'\n  bashPatterns:\n    - '\\bvercel\\s+env\\s+pull\\b'\n    - '\\bvercel\\s+env\\s+add\\b'\n    - '\\bvercel\\s+env\\s+rm\\b'\n    - '\\bvercel\\s+env\\s+ls\\b'\n    - '\\bvercel\\s+env\\s+update\\b'\n    - '\\bvercel\\s+env\\s+run\\b'\nchainTo:\n  -\n    pattern: '\\b(OPENAI_API_KEY|ANTHROPIC_API_KEY|GOOGLE_API_KEY)\\b'\n    targetSkill: ai-gateway\n    message: 'Direct provider API key detected — loading AI Gateway guidance for OIDC auth (no manual keys needed on Vercel).'\nretrieval:\n  aliases:\n    - environment variables\n    - env file\n    - secrets\n    - config vars\n    - secret env var\n    - sensitive env var\n  intents:\n    - set env var\n    - manage secrets\n    - pull env vars\n    - configure environment\n  entities:\n    - .env\n    - vercel env\n    - OIDC\n    - environment variable\n\n---\n\n# Vercel Environment Variables\n\nYou are an expert in Vercel environment variable management — `.env` file conventions, the `vercel env` CLI, OIDC token lifecycle, and environment-specific configuration.\n\n## .env File Hierarchy\n\nVercel and Next.js load environment variables in a specific order. Later files override earlier ones:\n\n| File | Purpose | Git-tracked? |\n|------|---------|-------------|\n| `.env` | Default values for all environments | Yes |\n| `.env.local` | Local overrides and secrets | **No** (gitignored) |\n| `.env.development` | Development-specific defaults | Yes |\n| `.env.development.local` | Local dev overrides | **No** |\n| `.env.production` | Production-specific defaults | Yes |\n| `.env.production.local` | Local prod overrides | **No** |\n| `.env.test` | Test-specific defaults | Yes |\n| `.env.test.local` | Local test overrides | **No** |\n\n### Load Order (Next.js)\n\n1. `.env` (lowest priority)\n2. `.env.[environment]` (development, production, or test)\n3. `.env.local` (skipped in test environment)\n4. `.env.[environment].local` (highest priority, skipped in test)\n\n### Critical Rules\n\n- **Never commit secrets** to `.env`, `.env.development`, or `.env.production` — use `.local` variants or Vercel environment variables\n- `.env.local` is always gitignored by Next.js — this is where `vercel env pull` writes secrets\n- Variables prefixed with `NEXT_PUBLIC_` are exposed to the browser bundle — never put secrets in `NEXT_PUBLIC_` vars\n- All other variables are server-only (API routes, Server Components, middleware)\n\n## vercel env CLI\n\n### Pull Environment Variables\n\n```bash\n# Pull all env vars for the current environment into .env.local\nvercel env pull .env.local\n\n# Pull for a specific environment\nvercel env pull .env.local --environment=production\nvercel env pull .env.local --environment=preview\nvercel env pull .env.local --environment=development\n\n# Overwrite existing file without prompting\nvercel env pull .env.local --yes\n\n# Pull to a custom file\nvercel env pull .env.production.local --environment=production\n```\n\n### Add Environment Variables\n\nEvery variable has a type:\n\n| Type | After saving | Use for |\n|------|--------------|---------|\n| **Secret** | Hidden in the dashboard and `vercel env ls`; can be replaced, never read back. Production and Preview Secrets are not returned by `vercel env pull`. | Passwords, API keys, tokens, database URLs |\n| **Config** | Readable by members with access | Non-sensitive values you need to read later |\n\nDeployments receive both types at build time and runtime. Secret and Config replaced the Sensitive toggle; existing Sensitive variables are Secrets.\n\n```bash\n# Interactive — prompts for value, environments, and type\nvercel env add MY_SECRET\n\n# Non-interactive: read the value from a file so it never lands in shell\n# history or process arguments (echo \"value\" | ... and --value do both)\nvercel env add MY_SECRET production < ./secret.txt\n\n# Add to production and preview in one command\nvercel env add MY_SECRET production,preview < ./secret.txt\n\n# Set the type explicitly\nvercel env add MY_SECRET production --type secret < ./secret.txt\nvercel env add SITE_REGION production --type config < ./region.txt\n\n# Add development in its own command; development-only adds default to Config\nvercel env add MY_SECRET development < ./dev-secret.txt\n\n# Update an existing value\nvercel env update MY_SECRET production < ./secret.txt\n```\n\n- **Defaults**: a non-interactive add to production, preview, or a custom environment is stored as Secret.\n- **Public prefixes are always Config**: variables such as `NEXT_PUBLIC_*` or `VITE_*` are exposed to browsers, so the CLI refuses `--type secret` for them. Keep a private value under a name without the prefix.\n- **Flags**: `--type config|secret` needs Vercel CLI 59.6 or later. Older CLIs use `--visibility`, now a deprecated alias of `--type`. `--sensitive` (Secret) and `--no-sensitive` (Config) still work in every version.\n- **Team policy**: **Separate Production Secret Values** requires a Production Secret to differ from the Preview, Development, and custom environment values of the same key. Under it, create separate Production and non-Production values instead of adding one value to all targets. It replaces the deprecated **Enforce Sensitive Environment Variables** policy.\n\n### List Environment Variables\n\n```bash\n# List all environment variables\nvercel env ls\n\n# Filter by environment\nvercel env ls production\n```\n\n### Remove Environment Variables\n\n```bash\n# Remove from specific environment\nvercel env rm MY_SECRET production\n\n# Remove from all environments\nvercel env rm MY_SECRET\n```\n\n## Bootstrap Flow (Fresh Clone / New Machine)\n\nUse this sequence when setting up a project from scratch:\n\n```bash\n# 1) Link first so pulls target the correct Vercel project\nvercel link --yes --project <name-or-id> --scope <team>\n\n# 2) Pull env vars into .env.local\nvercel env pull .env.local --yes\n\n# 3) Verify required keys from .env.example exist in .env.local\nwhile IFS='=' read -r key _; do\n  [[ -z \"$key\" || \"$key\" == \\#* ]] && continue\n  grep -q \"^${key}=\" .env.local || echo \"Missing in .env.local: $key\"\ndone < .env.example\n```\n\n### Temporary Path: Run With Vercel Envs Without Writing a File\n\nIf you need Vercel environment variables immediately but do not want to write `.env.local` yet:\n\n```bash\nvercel env run -- npm run dev\n```\n\nThis is useful for quick validation during bootstrap, but still pull `.env.local` for a normal local workflow.\n\n### Re-pull After Secret or Provisioning Changes\n\nAfter creating/updating secrets (`vercel env add`, dashboard changes) or provisioning integrations that add env vars (for example Neon/Upstash), re-run:\n\n```bash\nvercel env pull .env.local --yes\n```\n\n## OIDC Token Lifecycle\n\nVercel uses **OIDC (OpenID Connect)** tokens for secure, keyless authentication between your app and Vercel services (AI Gateway, storage, etc.).\n\n### How It Works\n\n1. **On Vercel deployments**: `VERCEL_OIDC_TOKEN` is automatically injected as a short-lived JWT and auto-refreshed — zero configuration needed\n2. **Local development**: `vercel env pull .env.local` provisions a `VERCEL_OIDC_TOKEN` valid for ~12 hours\n3. **Token expiry**: When the local OIDC token expires, re-run `vercel env pull .env.local --yes` to get a fresh one. Consider re-pulling at the start of each dev session to avoid mid-session auth failures\n\n### Common OIDC Patterns\n\n```ts\n// The @vercel/oidc package reads VERCEL_OIDC_TOKEN automatically\nimport { getVercelOidcToken } from '@vercel/oidc'\n\n// AI Gateway uses OIDC by default — no manual token handling needed\nimport { gateway } from 'ai'\nconst result = await generateText({\n  model: gateway('openai/gpt-5.2'),\n  prompt: 'Hello',\n})\n```\n\n### Troubleshooting OIDC\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `VERCEL_OIDC_TOKEN` missing locally | Haven't pulled env vars | `vercel env pull .env.local` |\n| Auth errors after ~12h locally | Token expired | `vercel env pull .env.local --yes` |\n| Works on Vercel, fails locally | Token not in `.env.local` | `vercel env pull .env.local` |\n| `AI_GATEWAY_API_KEY` vs OIDC | Both set, key takes priority | Remove `AI_GATEWAY_API_KEY` to use OIDC |\n\n## Environment-Specific Configuration\n\n### Vercel Dashboard vs .env Files\n\n| Use Case | Where to Set |\n|----------|-------------|\n| Secrets (API keys, tokens) | Vercel Dashboard (`https://vercel.com/{team}/{project}/settings/environment-variables`) or `vercel env add`, as type Secret |\n| Public config (site URL, feature flags) | `.env` or `.env.[environment]` files |\n| Local-only overrides | `.env.local` |\n| CI/CD secrets | Vercel Dashboard (`https://vercel.com/{team}/{project}/settings/environment-variables`) with environment scoping |\n\n### Environment Scoping on Vercel\n\nVariables set in the Vercel Dashboard at `https://vercel.com/{team}/{project}/settings/environment-variables` can be scoped to:\n\n- **Production** — production domain deployments\n- **Preview** — branch/PR deployments\n- **Development** — `vercel dev` and `vercel env pull`\n\nA variable can be assigned to one, two, or all three environments.\n\n### Git Branch Overrides\n\nPreview environment variables can be scoped to specific Git branches:\n\n```bash\n# Add a variable only for the \"staging\" branch\nvercel env add DATABASE_URL preview --git-branch=staging < ./staging-database-url.txt\n```\n\n## Gotchas\n\n### `vercel env pull` Overwrites Custom Variables\n\n`vercel env pull .env.local` **replaces the entire file** — any manually added variables (custom secrets, local overrides, debug flags) are lost. Always back up or re-add custom vars after pulling:\n\n```bash\n# Save custom vars before pulling\ngrep -v '^#' .env.local | grep -v '^VERCEL_\\|^POSTGRES_\\|^NEXT_PUBLIC_' > .env.custom.bak\nvercel env pull .env.local --yes\ncat .env.custom.bak >> .env.local  # Re-append custom vars\n```\n\nOr maintain custom vars in a separate `.env.development.local` file (loaded after `.env.local` by Next.js).\n\n### Pulled Files Omit Production and Preview Secrets\n\n`vercel env pull --environment=production` (or `preview`) does not write Secret values, so a pulled file cannot reproduce production credentials. Keep separate Development values for local work instead of trying to copy production Secrets onto a machine.\n\n### Scripts Don't Auto-Load `.env.local`\n\nOnly Next.js auto-loads `.env.local`. Standalone scripts (`drizzle-kit`, `tsx`, custom Node scripts) need explicit loading:\n\n```bash\n# Use dotenv-cli\nnpm install -D dotenv-cli\nnpx dotenv -e .env.local -- npx drizzle-kit push\nnpx dotenv -e .env.local -- npx tsx scripts/seed.ts\n\n# Or source manually\nsource <(grep -v '^#' .env.local | sed 's/^/export /') && node scripts/migrate.js\n```\n\n## Best Practices\n\n1. **Use `vercel env pull` as part of your setup workflow** — document it in your README\n2. **Never hardcode secrets** — always use environment variables\n3. **Scope narrowly** — don't give preview deployments production database access\n4. **Rotate OIDC tokens regularly in local dev** — re-pull when you see auth errors\n5. **Use `.env.example`** — commit a template with empty values so teammates know which vars are needed\n6. **Prefix client-side vars with `NEXT_PUBLIC_`** — and never put secrets in them\n7. **Keep custom vars in `.env.development.local`** — protects them from `vercel env pull` overwrites\n\n## Official Documentation\n\n- [Environment Variables](https://vercel.com/docs/environment-variables)\n- [Vercel CLI: env](https://vercel.com/docs/cli/env)\n- [Secret and Config types](https://vercel.com/changelog/environment-variables-now-use-config-and-secret-types)\n- [Next.js Environment Variables](https://nextjs.org/docs/app/guides/environment-variables)\n"},"changes":[{"path":"/description","type":"changed","before":"Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, OIDC tokens, or managing environment-specific configuration.","after":"Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, Secret or Config variable types, OIDC tokens, or managing environment-specific configuration."},{"path":"/skill_md_contents","type":"changed","before":"---\nname: env-vars\ndescription: Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, OIDC tokens, or managing environment-specific configuration.\nmetadata:\n  priority: 7\n  docs:\n    - \"https://vercel.com/docs/environment-variables\"\n  sitemap: \"https://vercel.com/sitemap/docs.xml\"\n  pathPatterns:\n    - '.env'\n    - '.env.*'\n    - '.env.local'\n    - '.env.production'\n    - '.env.development'\n    - '.env.test'\n    - '.env.production.local'\n    - '.env.development.local'\n    - '.env.test.local'\n    - '.env.example'\n  bashPatterns:\n    - '\\bvercel\\s+env\\s+pull\\b'\n    - '\\bvercel\\s+env\\s+add\\b'\n    - '\\bvercel\\s+env\\s+rm\\b'\n    - '\\bvercel\\s+env\\s+ls\\b'\n---\n\n# Vercel Environment Variables\n\nYou are an expert in Vercel environment variable management — `.env` file conventions, the `vercel env` CLI, OIDC token lifecycle, and environment-specific configuration.\n\n## .env File Hierarchy\n\nVercel and Next.js load environment variables in a specific order. Later files override earlier ones:\n\n| File | Purpose | Git-tracked? |\n|------|---------|-------------|\n| `.env` | Default values for all environments | Yes |\n| `.env.local` | Local overrides and secrets | **No** (gitignored) |\n| `.env.development` | Development-specific defaults | Yes |\n| `.env.development.local` | Local dev overrides | **No** |\n| `.env.production` | Production-specific defaults | Yes |\n| `.env.production.local` | Local prod overrides | **No** |\n| `.env.test` | Test-specific defaults | Yes |\n| `.env.test.local` | Local test overrides | **No** |\n\n### Load Order (Next.js)\n\n1. `.env` (lowest priority)\n2. `.env.[environment]` (development, production, or test)\n3. `.env.local` (skipped in test environment)\n4. `.env.[environment].local` (highest priority, skipped in test)\n\n### Critical Rules\n\n- **Never commit secrets** to `.env`, `.env.development`, or `.env.production` — use `.local` variants or Vercel environment variables\n- `.env.local` is always gitignored by Next.js — this is where `vercel env pull` writes secrets\n- Variables prefixed with `NEXT_PUBLIC_` are exposed to the browser bundle — never put secrets in `NEXT_PUBLIC_` vars\n- All other variables are server-only (API routes, Server Components, middleware)\n\n## vercel env CLI\n\n### Pull Environment Variables\n\n```bash\n# Pull all env vars for the current environment into .env.local\nvercel env pull .env.local\n\n# Pull for a specific environment\nvercel env pull .env.local --environment=production\nvercel env pull .env.local --environment=preview\nvercel env pull .env.local --environment=development\n\n# Overwrite existing file without prompting\nvercel env pull .env.local --yes\n\n# Pull to a custom file\nvercel env pull .env.production.local --environment=production\n```\n\n### Add Environment Variables\n\n```bash\n# Interactive — prompts for value and environments\nvercel env add MY_SECRET\n\n# Non-interactive\necho \"secret-value\" | vercel env add MY_SECRET production\n\n# Add to multiple environments\necho \"secret-value\" | vercel env add MY_SECRET production preview development\n\n# Add a sensitive variable (encrypted, not shown in logs)\nvercel env add MY_SECRET --sensitive\n```\n\n### List Environment Variables\n\n```bash\n# List all environment variables\nvercel env ls\n\n# Filter by environment\nvercel env ls production\n```\n\n### Remove Environment Variables\n\n```bash\n# Remove from specific environment\nvercel env rm MY_SECRET production\n\n# Remove from all environments\nvercel env rm MY_SECRET\n```\n\n## Bootstrap Flow (Fresh Clone / New Machine)\n\nUse this sequence when setting up a project from scratch:\n\n```bash\n# 1) Link first so pulls target the correct Vercel project\nvercel link --yes --project <name-or-id> --scope <team>\n\n# 2) Pull env vars into .env.local\nvercel env pull .env.local --yes\n\n# 3) Verify required keys from .env.example exist in .env.local\nwhile IFS='=' read -r key _; do\n  [[ -z \"$key\" || \"$key\" == \\#* ]] && continue\n  grep -q \"^${key}=\" .env.local || echo \"Missing in .env.local: $key\"\ndone < .env.example\n```\n\n### Temporary Path: Run With Vercel Envs Without Writing a File\n\nIf you need Vercel environment variables immediately but do not want to write `.env.local` yet:\n\n```bash\nvercel env run -- npm run dev\n```\n\nThis is useful for quick validation during bootstrap, but still pull `.env.local` for a normal local workflow.\n\n### Re-pull After Secret or Provisioning Changes\n\nAfter creating/updating secrets (`vercel env add`, dashboard changes) or provisioning integrations that add env vars (for example Neon/Upstash), re-run:\n\n```bash\nvercel env pull .env.local --yes\n```\n\n## OIDC Token Lifecycle\n\nVercel uses **OIDC (OpenID Connect)** tokens for secure, keyless authentication between your app and Vercel services (AI Gateway, storage, etc.).\n\n### How It Works\n\n1. **On Vercel deployments**: `VERCEL_OIDC_TOKEN` is automatically injected as a short-lived JWT and auto-refreshed — zero configuration needed\n2. **Local development**: `vercel env pull .env.local` provisions a `VERCEL_OIDC_TOKEN` valid for ~12 hours\n3. **Token expiry**: When the local OIDC token expires, re-run `vercel env pull .env.local --yes` to get a fresh one. Consider re-pulling at the start of each dev session to avoid mid-session auth failures\n\n### Common OIDC Patterns\n\n```ts\n// The @vercel/oidc package reads VERCEL_OIDC_TOKEN automatically\nimport { getVercelOidcToken } from '@vercel/oidc'\n\n// AI Gateway uses OIDC by default — no manual token handling needed\nimport { gateway } from 'ai'\nconst result = await generateText({\n  model: gateway('openai/gpt-5.2'),\n  prompt: 'Hello',\n})\n```\n\n### Troubleshooting OIDC\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `VERCEL_OIDC_TOKEN` missing locally | Haven't pulled env vars | `vercel env pull .env.local` |\n| Auth errors after ~12h locally | Token expired | `vercel env pull .env.local --yes` |\n| Works on Vercel, fails locally | Token not in `.env.local` | `vercel env pull .env.local` |\n| `AI_GATEWAY_API_KEY` vs OIDC | Both set, key takes priority | Remove `AI_GATEWAY_API_KEY` to use OIDC |\n\n## Environment-Specific Configuration\n\n### Vercel Dashboard vs .env Files\n\n| Use Case | Where to Set |\n|----------|-------------|\n| Secrets (API keys, tokens) | Vercel Dashboard (`https://vercel.com/{team}/{project}/settings/environment-variables`) or `vercel env add` |\n| Public config (site URL, feature flags) | `.env` or `.env.[environment]` files |\n| Local-only overrides | `.env.local` |\n| CI/CD secrets | Vercel Dashboard (`https://vercel.com/{team}/{project}/settings/environment-variables`) with environment scoping |\n\n### Environment Scoping on Vercel\n\nVariables set in the Vercel Dashboard at `https://vercel.com/{team}/{project}/settings/environment-variables` can be scoped to:\n\n- **Production** — only `vercel.app` production deployments\n- **Preview** — branch/PR deployments\n- **Development** — `vercel dev` and `vercel env pull`\n\nA variable can be assigned to one, two, or all three environments.\n\n### Git Branch Overrides\n\nPreview environment variables can be scoped to specific Git branches:\n\n```bash\n# Add a variable only for the \"staging\" branch\necho \"staging-value\" | vercel env add DATABASE_URL preview --git-branch=staging\n```\n\n## Gotchas\n\n### `vercel env pull` Overwrites Custom Variables\n\n`vercel env pull .env.local` **replaces the entire file** — any manually added variables (custom secrets, local overrides, debug flags) are lost. Always back up or re-add custom vars after pulling:\n\n```bash\n# Save custom vars before pulling\ngrep -v '^#' .env.local | grep -v '^VERCEL_\\|^POSTGRES_\\|^NEXT_PUBLIC_' > .env.custom.bak\nvercel env pull .env.local --yes\ncat .env.custom.bak >> .env.local  # Re-append custom vars\n```\n\nOr maintain custom vars in a separate `.env.development.local` file (loaded after `.env.local` by Next.js).\n\n### Scripts Don't Auto-Load `.env.local`\n\nOnly Next.js auto-loads `.env.local`. Standalone scripts (`drizzle-kit`, `tsx`, custom Node scripts) need explicit loading:\n\n```bash\n# Use dotenv-cli\nnpm install -D dotenv-cli\nnpx dotenv -e .env.local -- npx drizzle-kit push\nnpx dotenv -e .env.local -- npx tsx scripts/seed.ts\n\n# Or source manually\nsource <(grep -v '^#' .env.local | sed 's/^/export /') && node scripts/migrate.js\n```\n\n## Best Practices\n\n1. **Use `vercel env pull` as part of your setup workflow** — document it in your README\n2. **Never hardcode secrets** — always use environment variables\n3. **Scope narrowly** — don't give preview deployments production database access\n4. **Rotate OIDC tokens regularly in local dev** — re-pull when you see auth errors\n5. **Use `.env.example`** — commit a template with empty values so teammates know which vars are needed\n6. **Prefix client-side vars with `NEXT_PUBLIC_`** — and never put secrets in them\n7. **Keep custom vars in `.env.development.local`** — protects them from `vercel env pull` overwrites\n\n## Official Documentation\n\n- [Environment Variables](https://vercel.com/docs/environment-variables)\n- [Vercel CLI: env](https://vercel.com/docs/cli/env)\n- [Next.js Environment Variables](https://nextjs.org/docs/app/building-your-application/configuring/environment-variables)\n","after":"---\nname: env-vars\ndescription: Vercel environment variable expert guidance. Use when working with .env files, vercel env commands, Secret or Config variable types, OIDC tokens, or managing environment-specific configuration.\nmetadata:\n  priority: 7\n  docs:\n    - \"https://vercel.com/docs/environment-variables\"\n    - \"https://vercel.com/docs/environment-variables/sensitive-environment-variables\"\n  sitemap: \"https://vercel.com/sitemap.xml\"\n  pathPatterns:\n    - '.env'\n    - '.env.*'\n    - '.env.local'\n    - '.env.production'\n    - '.env.development'\n    - '.env.test'\n    - '.env.production.local'\n    - '.env.development.local'\n    - '.env.test.local'\n    - '.env.example'\n  bashPatterns:\n    - '\\bvercel\\s+env\\s+pull\\b'\n    - '\\bvercel\\s+env\\s+add\\b'\n    - '\\bvercel\\s+env\\s+rm\\b'\n    - '\\bvercel\\s+env\\s+ls\\b'\n    - '\\bvercel\\s+env\\s+update\\b'\n    - '\\bvercel\\s+env\\s+run\\b'\nchainTo:\n  -\n    pattern: '\\b(OPENAI_API_KEY|ANTHROPIC_API_KEY|GOOGLE_API_KEY)\\b'\n    targetSkill: ai-gateway\n    message: 'Direct provider API key detected — loading AI Gateway guidance for OIDC auth (no manual keys needed on Vercel).'\nretrieval:\n  aliases:\n    - environment variables\n    - env file\n    - secrets\n    - config vars\n    - secret env var\n    - sensitive env var\n  intents:\n    - set env var\n    - manage secrets\n    - pull env vars\n    - configure environment\n  entities:\n    - .env\n    - vercel env\n    - OIDC\n    - environment variable\n\n---\n\n# Vercel Environment Variables\n\nYou are an expert in Vercel environment variable management — `.env` file conventions, the `vercel env` CLI, OIDC token lifecycle, and environment-specific configuration.\n\n## .env File Hierarchy\n\nVercel and Next.js load environment variables in a specific order. Later files override earlier ones:\n\n| File | Purpose | Git-tracked? |\n|------|---------|-------------|\n| `.env` | Default values for all environments | Yes |\n| `.env.local` | Local overrides and secrets | **No** (gitignored) |\n| `.env.development` | Development-specific defaults | Yes |\n| `.env.development.local` | Local dev overrides | **No** |\n| `.env.production` | Production-specific defaults | Yes |\n| `.env.production.local` | Local prod overrides | **No** |\n| `.env.test` | Test-specific defaults | Yes |\n| `.env.test.local` | Local test overrides | **No** |\n\n### Load Order (Next.js)\n\n1. `.env` (lowest priority)\n2. `.env.[environment]` (development, production, or test)\n3. `.env.local` (skipped in test environment)\n4. `.env.[environment].local` (highest priority, skipped in test)\n\n### Critical Rules\n\n- **Never commit secrets** to `.env`, `.env.development`, or `.env.production` — use `.local` variants or Vercel environment variables\n- `.env.local` is always gitignored by Next.js — this is where `vercel env pull` writes secrets\n- Variables prefixed with `NEXT_PUBLIC_` are exposed to the browser bundle — never put secrets in `NEXT_PUBLIC_` vars\n- All other variables are server-only (API routes, Server Components, middleware)\n\n## vercel env CLI\n\n### Pull Environment Variables\n\n```bash\n# Pull all env vars for the current environment into .env.local\nvercel env pull .env.local\n\n# Pull for a specific environment\nvercel env pull .env.local --environment=production\nvercel env pull .env.local --environment=preview\nvercel env pull .env.local --environment=development\n\n# Overwrite existing file without prompting\nvercel env pull .env.local --yes\n\n# Pull to a custom file\nvercel env pull .env.production.local --environment=production\n```\n\n### Add Environment Variables\n\nEvery variable has a type:\n\n| Type | After saving | Use for |\n|------|--------------|---------|\n| **Secret** | Hidden in the dashboard and `vercel env ls`; can be replaced, never read back. Production and Preview Secrets are not returned by `vercel env pull`. | Passwords, API keys, tokens, database URLs |\n| **Config** | Readable by members with access | Non-sensitive values you need to read later |\n\nDeployments receive both types at build time and runtime. Secret and Config replaced the Sensitive toggle; existing Sensitive variables are Secrets.\n\n```bash\n# Interactive — prompts for value, environments, and type\nvercel env add MY_SECRET\n\n# Non-interactive: read the value from a file so it never lands in shell\n# history or process arguments (echo \"value\" | ... and --value do both)\nvercel env add MY_SECRET production < ./secret.txt\n\n# Add to production and preview in one command\nvercel env add MY_SECRET production,preview < ./secret.txt\n\n# Set the type explicitly\nvercel env add MY_SECRET production --type secret < ./secret.txt\nvercel env add SITE_REGION production --type config < ./region.txt\n\n# Add development in its own command; development-only adds default to Config\nvercel env add MY_SECRET development < ./dev-secret.txt\n\n# Update an existing value\nvercel env update MY_SECRET production < ./secret.txt\n```\n\n- **Defaults**: a non-interactive add to production, preview, or a custom environment is stored as Secret.\n- **Public prefixes are always Config**: variables such as `NEXT_PUBLIC_*` or `VITE_*` are exposed to browsers, so the CLI refuses `--type secret` for them. Keep a private value under a name without the prefix.\n- **Flags**: `--type config|secret` needs Vercel CLI 59.6 or later. Older CLIs use `--visibility`, now a deprecated alias of `--type`. `--sensitive` (Secret) and `--no-sensitive` (Config) still work in every version.\n- **Team policy**: **Separate Production Secret Values** requires a Production Secret to differ from the Preview, Development, and custom environment values of the same key. Under it, create separate Production and non-Production values instead of adding one value to all targets. It replaces the deprecated **Enforce Sensitive Environment Variables** policy.\n\n### List Environment Variables\n\n```bash\n# List all environment variables\nvercel env ls\n\n# Filter by environment\nvercel env ls production\n```\n\n### Remove Environment Variables\n\n```bash\n# Remove from specific environment\nvercel env rm MY_SECRET production\n\n# Remove from all environments\nvercel env rm MY_SECRET\n```\n\n## Bootstrap Flow (Fresh Clone / New Machine)\n\nUse this sequence when setting up a project from scratch:\n\n```bash\n# 1) Link first so pulls target the correct Vercel project\nvercel link --yes --project <name-or-id> --scope <team>\n\n# 2) Pull env vars into .env.local\nvercel env pull .env.local --yes\n\n# 3) Verify required keys from .env.example exist in .env.local\nwhile IFS='=' read -r key _; do\n  [[ -z \"$key\" || \"$key\" == \\#* ]] && continue\n  grep -q \"^${key}=\" .env.local || echo \"Missing in .env.local: $key\"\ndone < .env.example\n```\n\n### Temporary Path: Run With Vercel Envs Without Writing a File\n\nIf you need Vercel environment variables immediately but do not want to write `.env.local` yet:\n\n```bash\nvercel env run -- npm run dev\n```\n\nThis is useful for quick validation during bootstrap, but still pull `.env.local` for a normal local workflow.\n\n### Re-pull After Secret or Provisioning Changes\n\nAfter creating/updating secrets (`vercel env add`, dashboard changes) or provisioning integrations that add env vars (for example Neon/Upstash), re-run:\n\n```bash\nvercel env pull .env.local --yes\n```\n\n## OIDC Token Lifecycle\n\nVercel uses **OIDC (OpenID Connect)** tokens for secure, keyless authentication between your app and Vercel services (AI Gateway, storage, etc.).\n\n### How It Works\n\n1. **On Vercel deployments**: `VERCEL_OIDC_TOKEN` is automatically injected as a short-lived JWT and auto-refreshed — zero configuration needed\n2. **Local development**: `vercel env pull .env.local` provisions a `VERCEL_OIDC_TOKEN` valid for ~12 hours\n3. **Token expiry**: When the local OIDC token expires, re-run `vercel env pull .env.local --yes` to get a fresh one. Consider re-pulling at the start of each dev session to avoid mid-session auth failures\n\n### Common OIDC Patterns\n\n```ts\n// The @vercel/oidc package reads VERCEL_OIDC_TOKEN automatically\nimport { getVercelOidcToken } from '@vercel/oidc'\n\n// AI Gateway uses OIDC by default — no manual token handling needed\nimport { gateway } from 'ai'\nconst result = await generateText({\n  model: gateway('openai/gpt-5.2'),\n  prompt: 'Hello',\n})\n```\n\n### Troubleshooting OIDC\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `VERCEL_OIDC_TOKEN` missing locally | Haven't pulled env vars | `vercel env pull .env.local` |\n| Auth errors after ~12h locally | Token expired | `vercel env pull .env.local --yes` |\n| Works on Vercel, fails locally | Token not in `.env.local` | `vercel env pull .env.local` |\n| `AI_GATEWAY_API_KEY` vs OIDC | Both set, key takes priority | Remove `AI_GATEWAY_API_KEY` to use OIDC |\n\n## Environment-Specific Configuration\n\n### Vercel Dashboard vs .env Files\n\n| Use Case | Where to Set |\n|----------|-------------|\n| Secrets (API keys, tokens) | Vercel Dashboard (`https://vercel.com/{team}/{project}/settings/environment-variables`) or `vercel env add`, as type Secret |\n| Public config (site URL, feature flags) | `.env` or `.env.[environment]` files |\n| Local-only overrides | `.env.local` |\n| CI/CD secrets | Vercel Dashboard (`https://vercel.com/{team}/{project}/settings/environment-variables`) with environment scoping |\n\n### Environment Scoping on Vercel\n\nVariables set in the Vercel Dashboard at `https://vercel.com/{team}/{project}/settings/environment-variables` can be scoped to:\n\n- **Production** — production domain deployments\n- **Preview** — branch/PR deployments\n- **Development** — `vercel dev` and `vercel env pull`\n\nA variable can be assigned to one, two, or all three environments.\n\n### Git Branch Overrides\n\nPreview environment variables can be scoped to specific Git branches:\n\n```bash\n# Add a variable only for the \"staging\" branch\nvercel env add DATABASE_URL preview --git-branch=staging < ./staging-database-url.txt\n```\n\n## Gotchas\n\n### `vercel env pull` Overwrites Custom Variables\n\n`vercel env pull .env.local` **replaces the entire file** — any manually added variables (custom secrets, local overrides, debug flags) are lost. Always back up or re-add custom vars after pulling:\n\n```bash\n# Save custom vars before pulling\ngrep -v '^#' .env.local | grep -v '^VERCEL_\\|^POSTGRES_\\|^NEXT_PUBLIC_' > .env.custom.bak\nvercel env pull .env.local --yes\ncat .env.custom.bak >> .env.local  # Re-append custom vars\n```\n\nOr maintain custom vars in a separate `.env.development.local` file (loaded after `.env.local` by Next.js).\n\n### Pulled Files Omit Production and Preview Secrets\n\n`vercel env pull --environment=production` (or `preview`) does not write Secret values, so a pulled file cannot reproduce production credentials. Keep separate Development values for local work instead of trying to copy production Secrets onto a machine.\n\n### Scripts Don't Auto-Load `.env.local`\n\nOnly Next.js auto-loads `.env.local`. Standalone scripts (`drizzle-kit`, `tsx`, custom Node scripts) need explicit loading:\n\n```bash\n# Use dotenv-cli\nnpm install -D dotenv-cli\nnpx dotenv -e .env.local -- npx drizzle-kit push\nnpx dotenv -e .env.local -- npx tsx scripts/seed.ts\n\n# Or source manually\nsource <(grep -v '^#' .env.local | sed 's/^/export /') && node scripts/migrate.js\n```\n\n## Best Practices\n\n1. **Use `vercel env pull` as part of your setup workflow** — document it in your README\n2. **Never hardcode secrets** — always use environment variables\n3. **Scope narrowly** — don't give preview deployments production database access\n4. **Rotate OIDC tokens regularly in local dev** — re-pull when you see auth errors\n5. **Use `.env.example`** — commit a template with empty values so teammates know which vars are needed\n6. **Prefix client-side vars with `NEXT_PUBLIC_`** — and never put secrets in them\n7. **Keep custom vars in `.env.development.local`** — protects them from `vercel env pull` overwrites\n\n## Official Documentation\n\n- [Environment Variables](https://vercel.com/docs/environment-variables)\n- [Vercel CLI: env](https://vercel.com/docs/cli/env)\n- [Secret and Config types](https://vercel.com/changelog/environment-variables-now-use-config-and-secret-types)\n- [Next.js Environment Variables](https://nextjs.org/docs/app/guides/environment-variables)\n"}],"summary":"Fields changed: 2. /description, /skill_md_contents.","summary_kind":"deterministic","summary_metadata":{}}