Secrets
The CMS depends on three categories of secret material: Worker
secrets (set per environment via wrangler secret put), GitHub
Actions secrets (set in the repo’s Environments and Settings), and
per-space integration secrets (set in the dashboard UI and stored
encrypted in D1).
Worker secrets — runtime
Set with wrangler secret put NAME [--env staging] and confirm with
wrangler secret list [--env staging]. They never appear in
wrangler.jsonc and aren’t visible in the dashboard once set.
| Name | Required | Format | Used by |
|---|---|---|---|
AUTH_JWT_SECRET | Always | 32+ random characters | Signs / verifies session JWTs. |
TOKEN_ENCRYPTION_KEY | Always | 64-character hex string (32 raw bytes) | AES-256-GCM cipher for API tokens, integration secrets, preview-URL probe secrets. |
OIDC_ISSUER | When AUTH_PROVIDER=oidc | URL | OIDC issuer (Okta, Auth0, Azure AD, …) — used to fetch JWKS for token validation. |
OIDC_AUDIENCE | When AUTH_PROVIDER=oidc | Opaque string | Expected aud claim on incoming bearer tokens. |
Set each per environment. Example for prod + staging:
cd apps/cmsnpx wrangler secret put AUTH_JWT_SECRET # prodnpx wrangler secret put AUTH_JWT_SECRET --env staging # staging
openssl rand -hex 32 | npx wrangler secret put TOKEN_ENCRYPTION_KEYopenssl rand -hex 32 | npx wrangler secret put TOKEN_ENCRYPTION_KEY --env stagingGitHub Actions secrets
Stored at repo Settings → Secrets and variables → Actions. The
workflows in .github/workflows/ consume these.
Repository-wide (visible to all jobs)
| Name | Used by | Notes |
|---|---|---|
VERDACCIO_AUTH_TOKEN | ci.yml, deploy-prod.yml, publish-*.yml | Auth for npm.alokai.cloud (enterprise package registry). |
Environment-scoped: staging
Used by the deploy-staging job in ci.yml. No required reviewers —
staging deploys are auto-approved.
| Name | Notes |
|---|---|
CLOUDFLARE_API_TOKEN | Workers + D1 + R2 + KV deploy permissions. Scope to staging resources only if you can. |
CLOUDFLARE_ACCOUNT_ID | Alokai Inc. account id (also pinned in wrangler.jsonc#account_id — the env var overrides it). |
Environment-scoped: production
Used by deploy-prod.yml. Configure required reviewers here so the
workflow pauses before touching prod.
| Name | Notes |
|---|---|
CLOUDFLARE_API_TOKEN | Workers + D1 + R2 + KV + Pages deploy permissions for production. |
CLOUDFLARE_ACCOUNT_ID | Same value as staging (single account today, separate workers per env). |
Environment-scoped: preview
Used by the deploy-docs-preview job in ci.yml (PR docs previews).
Configure deployment branch policy = All branches so PR feature
branches can access these secrets — the default “Selected branches:
main” policy blocks PR runs.
| Name | Notes |
|---|---|
CLOUDFLARE_API_TOKEN | Cloudflare Pages: Edit (and Account Settings: Read). Workers permissions are not required. |
CLOUDFLARE_ACCOUNT_ID | Same value as staging/production. |
GITHUB_TOKEN is provided automatically by GitHub Actions and is used by
deploy-prod.yml for the version-bump commit, tag push, and Release
creation.
Per-space integration secrets (UI-managed, D1-stored)
These don’t live in Worker secrets at all — operators set them in the CMS dashboard:
- MCP Integrations — Settings → MCP Integrations. Stitch / agent URL and bearer secret per space.
- Preview URL probe secrets — Settings → Preview URLs. Optional
HMAC-style secret the storefront exposes at
/api/cms-probe.
Both are encrypted with TOKEN_ENCRYPTION_KEY before being written to
D1, so rotating that key is what invalidates them — see the caution box
above.
Local-dev secrets
apps/cms/.dev.vars is gitignored and read by wrangler dev. Copy from
apps/cms/.dev.vars.example:
cp apps/cms/.dev.vars.example apps/cms/.dev.varsopenssl rand -hex 32 # paste into TOKEN_ENCRYPTION_KEY=The default AUTH_JWT_SECRET in the example is fine for local-only dev.
Never copy a real production value into .dev.vars.
Inventory and audit
When adding a new secret:
- Add it to this page’s table with a clear description.
- Add a placeholder line to
apps/cms/.dev.vars.exampleif it’s needed in local dev. - If it’s read in a workflow, add it to the appropriate GitHub Environment (not the repo-wide secrets, unless every workflow truly needs it).
- If the workflow’s
env:block was updated, double-check that the same secret name is referenced in${{ secrets.NAME }}.
When removing one:
- Remove all
wrangler secret putreferences from runbooks. wrangler secret delete NAME [--env staging]on every environment.- Remove the entry from this page and from
.dev.vars.example.