Today Platform Web — Dev Docs
Automation

Cloud credentials

What every entry in `.env.cloud.example` is for, how the cloud-dev session consumes it, and what is intentionally not there.

The cloud-dev session (Claude Code on the web) has no direct access to local secrets. Credentials are delivered through the environment variables panel at Settings → Environment in claude.ai/code. The canonical list is .env.cloud.example; your actual .env.cloud is gitignored.

How each credential is actually used

Most entries are not process.env.X that the app reads at runtime. The env channel is just the only way the cloud agent accepts secrets — what each value really does varies by type:

TypeExamplesBehavior
Tools auto-consumeVERCEL_TOKEN, AWS_*, SLACK_*Read by CLIs / MCP servers without agent action
Raw materials for the agentGH_TOKEN, E2E_*, VERCEL_AUTOMATION_BYPASS_SECRETDelivered as env; agent invokes them via specific commands per recipe
Pulled from VercelOIDC_*, API URLs, per-app bypass headerWritten into apps/<app>/.env.development.local by pnpm cloud:bootstrap. Not in .env.cloud

The variable name often reflects a historical CI use case, not the real scope. The use-cloud-credentials skill makes the real scope explicit per credential. Read it before assuming a name means what it sounds like.

The credential list

The actual contents of .env.cloud.example change over time as new services are wired up. The current set, grouped by purpose:

Vercel CLI bootstrap

VariableReal scope
VERCEL_TOKENPersonal access token scoped to the today-platform team. Used by vercel pull to fetch OIDC creds + API URLs + per-app bypass headers into per-app .env.development.local.
VERCEL_ORG_IDPre-filled constant — the today-platform team's Vercel org ID
VERCEL_PROJECT_ID_WEBPre-filled — apps/web Vercel project
VERCEL_PROJECT_ID_ADMINPre-filled — apps/admin Vercel project
VERCEL_PROJECT_ID_DOCSPre-filled — design-system/docs Vercel project
VERCEL_PROJECT_ID_DEV_DOCSPre-filled — apps/dev-docs Vercel project (this site)

pnpm cloud:bootstrap reads these to call vercel pull for each app.

AWS CLI

VariableReal scope
AWS_ACCESS_KEY_IDRead-only IAM user, CloudWatch Logs only
AWS_SECRET_ACCESS_KEYPaired with the access key
AWS_DEFAULT_REGIONus-west-2 — pre-filled

Consumed by pnpm cloud:logs to tail backend CloudWatch logs (defaults to /today/api/dev).

GitHub (cross-repo)

VariableReal scope
GH_TOKENFine-grained PAT with contents:read on todayai-labs/*. General-purpose GH cred for any cross-repo operation.

Use it to clone sibling repos (todayai-labs/today-cloud), to read PRs / issues in sibling repos, to query GitHub API beyond what the agent's built-in tools cover.

E2E testing

VariableReal scope
E2E_USER_EMAILTest user email — the dev-environment seed has this user with a known password / OTP path
E2E_ADMIN_EMAILAdmin test user — same shape
E2E_SHARED_SECRETGates /internal/e2e/last-otp — the cloud endpoint that returns the latest OTP for an email without going through Resend
VERCEL_AUTOMATION_BYPASS_SECRETVercel deployment protection bypass header (x-vercel-protection-bypass) — works for any client, not just CI
PLAYWRIGHT_BASE_URLDefaults to the dev environment if unset; override to test against a specific preview deployment

Playwright smoke / full configs read these; ad-hoc curl / fetch can use the bypass secret directly via the x-vercel-protection-bypass header.

Slack (MCP)

VariableReal scope
SLACK_BOT_TOKENBot token for the Slack MCP server. Wired via .claude/settings.json; agents call the MCP tools, the server reads this.
SLACK_TEAM_IDTeam ID for scoping queries

When the agent reads Slack ("check the deploy channel for errors"), the MCP server handles auth; the agent never touches the token directly.

Onboarding (Vite app)

VariableReal scope
DEV_API_TOKENToken used by apps/onboarding (Vite) to talk to dev APIs without a real session. Lives in .env.cloud because onboarding has no Vercel project, so vercel pull can't fetch it.

What's intentionally NOT in .env.cloud

The .env.cloud.example header comment lists what to leave out:

  • WEB_NEXT_PUBLIC_OIDC_* / ADMIN_* equivalents — these are fetched by pnpm cloud:bootstrap (via vercel pull) into apps/<app>/.env.development.local. Listing them in .env.cloud would create a stale second source of truth.
  • Local-only credentials — anything that wouldn't apply to the cloud session (whistle CA fingerprints, machine-specific keychains).

The pattern: vercel pull is the source of truth for per-app dev credentials; .env.cloud is for everything else.

Setting up a fresh cloud session

When you first connect a new cloud session to this repo:

# In the cloud-dev shell, after the agent clones the repo:
pnpm install                       # workspace deps
pnpm cloud:bootstrap               # vercel pull for web + admin (writes per-app .env.development.local)
# verify by running typecheck:
pnpm typecheck                     # should be green

If pnpm cloud:bootstrap errors out, check VERCEL_TOKEN in the env panel — it's the most common rotation casualty.

Defensive practices

From the use-cloud-credentials skill:

  • Never echo / print / log a credential value. To confirm presence without leaking, redact: ${VAR:0:4}…
  • Never include a credential in commit messages, PR descriptions, comments, or error reports. If a tool emits the credential in an error, paraphrase before reporting back.
  • Treat names as historical, not authoritative. Re-read the skill before assuming a credential's scope is what its name suggests.

The maintain-cloud-dev skill runs a monthly audit; rotated credentials that the audit catches surface as one-line action items.

On this page