An environment variable is a value the deployment reads from its process or Worker environment at runtime or at deploy time. Where a setting saved in Admin lives in the deployment’s own state and can be changed from a browser, an environment variable lives outside the application and is set by whoever runs it. This page lists every variable Chickpea reads, grouped by what it configures, and ends with the variables that only test harnesses and maintainer environments use.
The source of truth is the product repository: .env.example for the Node target, .dev.vars.example for the Cloudflare target, and the code that reads each value. Where .env.example and the code disagree, the code is authoritative and the difference is recorded under Listed but not read.
How values are resolved
- A Worker binding beats a local process value.
envValueinsrc/config/env-value.tsreads the bound platform value first, so a deliberately blank binding is never overridden by a stale local variable. - An environment value beats a value stored in Admin. Provider API keys, the Slack behaviour switches, and the GitHub App credentials all check the environment before stored settings.
- Unset is offline-safe. Every value in
.env.examplemay be left empty; the deployment then takes its local paths and makes no external calls. - The Cloudflare Deploy button prompts for every active key in
.dev.vars.example, and every prompt is required. That file is therefore entirely comments, and the shippedwrangler.jsonccarries novarsat all. Cloudflare values are added after deployment as Worker variables or withnpx wrangler secret put <NAME>. - A changed environment takes effect on restart. On Cloudflare that is the next deployment or secret write; on Node it is a service restart.
Core and authentication
| Variable | When | Default | Purpose |
|---|---|---|---|
CHICKPEA_AUTH_SECRET |
Required on Node. The deploy wrapper mints it on Cloudflare | none | Stable internal signing authority. Must decode to exactly 32 random bytes; anything else throws CHICKPEA_AUTH_SECRET must encode exactly 32 random bytes. Generated once and preserved across restarts. |
CHICKPEA_SETUP_CAPABILITY_DIGEST |
Required on Node to serve the setup link | none | SHA-256 digest of the one-time setup capability, printed by npm run setup:link -- <public url>. |
CHICKPEA_SETUP_CAPABILITY_ISSUED_AT |
Required on Node alongside the digest | none | Milliseconds since the epoch when the capability was minted. The link stops verifying 24 hours after that instant, with 5 minutes of clock-skew tolerance. |
CHICKPEA_RECOVERY_TOKEN |
Only while repairing Slack credentials | unset | Break-glass value that unlocks /admin/recovery. It mints one browser-bound 15-minute session and is not a login credential. Deleted or replaced when recovery finishes. |
NODE_ENV |
Optional, Node | unset | Labels product telemetry when CHICKPEA_TELEMETRY_ENVIRONMENT is unset. Only production, development, and test are recognised. The operations runbook sets production. |
PORT |
Optional, Node | not set by Chickpea | Listening port of the built entry point dist/server.mjs. No file in the product repository reads it; the operations runbook sets PORT=3000 and notes there is no HOST setting. |
Credential encryption
Slack credentials are stored encrypted. The key material lives in the environment on Cloudflare and in a file on Node.
| Variable | When | Default | Purpose |
|---|---|---|---|
CHICKPEA_CREDENTIAL_KEY_CURRENT_ID |
Required on Cloudflare. The deploy wrapper mints it | key_v1 on a first deploy |
Names the active key slot. Missing on Cloudflare, the deployment throws Cloudflare Slack credential encryption is not provisioned; deploy with npm run deploy to mint the versioned Worker key slots. |
CHICKPEA_CREDENTIAL_KEY_<ID> |
Required on Cloudflare, one per key id | CHICKPEA_CREDENTIAL_KEY_KEY_V1 on a first deploy |
Base64url 32-byte key material for that id. Key ids are lower-cased; the slot named by the current id must exist. |
CHICKPEA_CREDENTIAL_KEYRING_PATH |
Optional on Node. Required when state is :memory: |
<state path>.credential-keyring.json |
JSON keyring file, created on first use at mode 0600. Unsafe permissions abort startup. |
Provisioning half of the Cloudflare pair fails the deploy with Cloudflare Slack credential encryption is only partially provisioned. Losing the key material makes stored credentials unusable.
Slack
| Variable | When | Default | Purpose |
|---|---|---|---|
CHICKPEA_GATEWAY_URL |
Optional | https://chickpea-slack-gateway.pejmanjohn.workers.dev |
Origin of the shared gateway behind “Add to Slack”. Must be an HTTPS origin with no path, query, fragment, or credentials. Overridden only for a compatible private gateway. |
SLACK_TAG_PUBLIC_URL |
Optional | unset | The deployment’s public origin. Pins the Configure link in reply footers and channel onboarding, and wins over the stored slack.publicUrl. Unset, Configure is shown as a label without a link. |
SLACK_API_URL |
Optional | https://slack.com/api |
Slack Web API base URL. Points offline harnesses at a fake Slack. |
Runtime behaviour switches
Each switch below is on unless the value is an explicit false spelling. SLACK_TAG_UNASSIGNED_HINT and SLACK_TAG_WELCOME_ON_JOIN accept false, 0, off, and no, and an environment value overrides the matching Admin setting. SLACK_TAG_PROGRESSIVE_STREAMING and SLACK_TAG_SEMANTIC_ACTIVITY_STATUS accept the same four spellings and have no Admin equivalent. CHICKPEA_LIVE_CHANNEL_CONFIG accepts false, 0, and off.
| Variable | When | Default | Purpose |
|---|---|---|---|
SLACK_TAG_UNASSIGNED_HINT |
Optional | on | Private guidance sent when a message matches more than one Agent handle. |
SLACK_TAG_WELCOME_ON_JOIN |
Optional | on | Short welcome posted when @Chickpea joins a channel that already has an Agent. |
SLACK_TAG_PROGRESSIVE_STREAMING |
Optional | on | Offers model-selected answer streaming on new Slack turns. |
SLACK_TAG_SEMANTIC_ACTIVITY_STATUS |
Optional | on | Offers the under-composer activity status. |
CHICKPEA_LIVE_CHANNEL_CONFIG |
Optional | on | Resolves current Agent and channel configuration for new channel admissions. Set false to restore write-once thread snapshots during an incident. Already admitted work is unaffected. |
SLACK_TAG_LEDGER_CANARY_CHANNELS |
Optional, internal rollout | empty | Selects the channel-neutral durable Run driver for future admissions in exact channels. At most 20 comma-separated workspace/channel pairs, such as T123/C456. Empty keeps Slack execution on the established lane. |
State and retention
The three Node paths below are derived from each other when not set. Production deployments set them explicitly, outside any checkout that an upgrade replaces, and never use :memory:.
| Variable | When | Default | Purpose |
|---|---|---|---|
TAG_DB_PATH |
Optional, Node | ./tmp/flue.db |
SQLite file for the durable Flue transcript. :memory: gives an ephemeral per-process database. |
SLACK_STATE_DB_PATH |
Optional, Node | <TAG_DB_PATH>.state |
SQLite file for app-owned configuration, assignments, claims, snapshots, and settings. Resolves to :memory: when the transcript database is :memory:. |
CHICKPEA_AUTH_DB_PATH |
Optional, Node | <state path>.auth |
SQLite file for Better Auth sessions and accounts. |
TAG_RUN_BODY_RETENTION_DAYS |
Optional | 30 |
Retention recorded when a canonical Run body is written. An integer from 1 through 365; anything else throws TAG_RUN_BODY_RETENTION_DAYS must be an integer from 1 to 365. Changing it does not rewrite existing expiries, and a purge does not delete Flue transcripts. |
TAG_STATE_INSTANCE_NAME |
Optional, Cloudflare | singleton |
Name of the app-owned state Durable Object instance. Must match [A-Za-z0-9][A-Za-z0-9._-]{0,127}. A different name selects a different, empty state object. |
On Cloudflare, state lives in the TAG_STATE and SLACK_GATEWAY_SESSION Durable Objects and the AUTH_DB D1 database, declared as bindings in wrangler.jsonc rather than as variables.
Model providers
A built-in provider counts as configured when its key is present. ANTHROPIC_API_KEY, OPENAI_API_KEY, and OPENROUTER_API_KEY can each be saved in Settings → Model providers instead, and the environment value wins when both exist.
| Variable | When | Default | Purpose |
|---|---|---|---|
ANTHROPIC_API_KEY |
Optional | unset | Enables the anthropic provider. |
OPENAI_API_KEY |
Optional | unset | Enables the openai provider. |
OPENROUTER_API_KEY |
Optional | unset | Enables the openrouter provider. |
CLOUDFLARE_API_TOKEN |
Optional | unset | With the account id, enables the REST cloudflare-workers-ai provider. |
CLOUDFLARE_ACCOUNT_ID |
Optional | unset | Cloudflare account for Workers AI. Also builds the default Workers AI base URL. |
ANTHROPIC_BASE_URL |
Optional | provider default | Inference base URL override for the anthropic provider. |
OPENAI_BASE_URL |
Optional | provider default | Inference base URL override for the openai provider. |
OPENROUTER_BASE_URL |
Optional | provider default | Inference base URL override for the openrouter provider. |
CLOUDFLARE_WORKERS_AI_BASE_URL |
Optional | https://api.cloudflare.com/client/v4/accounts/<CLOUDFLARE_ACCOUNT_ID>/ai/v1 |
Explicit Workers AI inference base URL. |
ANTHROPIC_API_URL |
Optional | https://api.anthropic.com |
API root for Admin key validation and model discovery. |
OPENAI_API_URL |
Optional | https://api.openai.com/v1 |
API root for Admin key validation and model discovery. |
OPENROUTER_API_URL |
Optional | https://openrouter.ai/api/v1 |
API root for Admin key validation and model discovery. |
CLOUDFLARE_API_URL |
Optional | https://api.cloudflare.com/client/v4 |
API root for Admin model discovery. |
ANTHROPIC_CREDENTIAL_ALIAS |
Optional | Environment credential |
Non-secret accounting label for the environment key. |
OPENAI_CREDENTIAL_ALIAS |
Optional | Environment credential |
Non-secret accounting label for the environment key. |
OPENROUTER_CREDENTIAL_ALIAS |
Optional | Environment credential |
Non-secret accounting label for the environment key. |
CLOUDFLARE_WORKERS_AI_CREDENTIAL_ALIAS |
Optional | Workers AI API token |
Non-secret accounting label for the Workers AI token. |
CLOUDFLARE_AI_BINDING_ALIAS |
Optional, Cloudflare | Workers AI binding |
Non-secret accounting label for the keyless Workers AI binding. |
ANTHROPIC_CREDENTIAL_EPOCH |
Optional | 1, reported as rotation unknown |
Positive integer rotation epoch. Increment when the underlying key is rotated. |
OPENAI_CREDENTIAL_EPOCH |
Optional | 1, reported as rotation unknown |
Positive integer rotation epoch. |
OPENROUTER_CREDENTIAL_EPOCH |
Optional | 1, reported as rotation unknown |
Positive integer rotation epoch. |
CLOUDFLARE_WORKERS_AI_CREDENTIAL_EPOCH |
Optional | 1, reported as rotation unknown |
Positive integer rotation epoch for the Workers AI token. |
CHICKPEA_DEPLOYMENT_EPOCH |
Optional, Cloudflare | 1, reported as rotation unknown |
Rotation epoch for the keyless Workers AI binding deployment. |
OPENAI_PROJECT_ID |
Optional | unset | Non-secret scope label recorded with the OpenAI environment credential. |
ANTHROPIC_WORKSPACE_ID |
Optional | unset | Non-secret scope label recorded with the Anthropic environment credential. |
SLACK_TAG_MODEL |
Optional, development | unset | provider/model fallback for an Agent with no pinned model. A pinned Agent always uses its saved model. With neither, resolution throws and names the missing pin. |
LOCAL_STUB_URL |
Optional, offline harnesses | unset | Registers a local-stub provider that speaks the OpenAI completions wire protocol. |
LOCAL_STUB_API_KEY |
Optional, offline harnesses | offline-stub-key |
Non-empty key the completions client requires; the stub ignores its value. |
LOCAL_STUB_MODELS |
Optional, offline harnesses | empty | Comma-separated provider-local model ids. Each must match [A-Za-z0-9][A-Za-z0-9._:-]{0,199}. |
Managed connectors
The normal path is one project key in Settings → Connectors, stored encrypted. The variables below are the deployment-owned alternative. The key never enters Agent context or model input.
| Variable | When | Default | Purpose |
|---|---|---|---|
COMPOSIO_API_KEY |
Optional | unset | Composio project key owned by the deployment. Rotating it pauses managed execution until an Owner or Admin retries preparation in Settings → Connectors. |
CHICKPEA_COMPOSIO_CONFIGURATION_MODE |
Optional | unset | Set to deployment so Admin can prepare defaults but cannot replace or disable the deployment key. |
COMPOSIO_WEBHOOK_SECRET |
Optional | unset | Signature secret from a Composio webhook subscription. It surfaces upstream revocation between the connect-time and reconciliation identity checks. |
Google Ads and YouTube assertions
These are policy and quota assertions, not credentials. Unset, no assertion is made. .env.example ships the YouTube values as active entries matching the documented project quotas as of 2026-08-23; values above them require the corresponding audit and the approval flag.
| Variable | When | Default | Purpose |
|---|---|---|---|
COMPOSIO_GOOGLE_ADS_ACCESS_LEVEL |
Required for Google Ads | unset | basic or standard. |
COMPOSIO_GOOGLE_ADS_PERMISSIBLE_USE |
Required for Google Ads | unset | reporting or ad_management. |
COMPOSIO_YOUTUBE_GENERAL_DAILY_QUOTA_UNITS |
Optional | unset in code, 10000 in .env.example |
Daily general quota units asserted for YouTube. |
COMPOSIO_YOUTUBE_SEARCH_DAILY_CALL_LIMIT |
Optional | unset in code, 100 in .env.example |
Daily search call ceiling. |
COMPOSIO_YOUTUBE_UPLOAD_DAILY_CALL_LIMIT |
Optional | unset in code, 100 in .env.example |
Daily upload call ceiling. |
COMPOSIO_YOUTUBE_QUOTA_AUDIT_APPROVED |
Required above the default quotas | unset in code, false in .env.example |
Records that the YouTube quota and compliance audit was approved. |
Auth config ID overrides
Compatibility overrides for an installation that already owns explicit Composio auth configs. One-key setup does not need them: it creates or reuses one deterministic Composio-managed auth configuration per toolkit, named after Chickpea and that toolkit. Each override must belong to the active Composio project and be enabled, Composio-managed, and unrestricted. An invalid or temporarily unverifiable lane is ignored and its variable name is written to the operator log; the other managed connectors stay available.
| Toolkit | Read lane | Write lane |
|---|---|---|
| Gmail | COMPOSIO_GMAIL_READ_AUTH_CONFIG_ID |
COMPOSIO_GMAIL_WRITE_AUTH_CONFIG_ID |
| Google Calendar | COMPOSIO_CALENDAR_READ_AUTH_CONFIG_ID |
COMPOSIO_CALENDAR_WRITE_AUTH_CONFIG_ID |
| Google Drive | COMPOSIO_DRIVE_READ_AUTH_CONFIG_ID |
COMPOSIO_DRIVE_WRITE_AUTH_CONFIG_ID |
| Google Sheets | COMPOSIO_SHEETS_READ_AUTH_CONFIG_ID |
COMPOSIO_SHEETS_WRITE_AUTH_CONFIG_ID |
| Google Docs | COMPOSIO_DOCS_READ_AUTH_CONFIG_ID |
COMPOSIO_DOCS_WRITE_AUTH_CONFIG_ID |
| Google Slides | COMPOSIO_SLIDES_READ_AUTH_CONFIG_ID |
COMPOSIO_SLIDES_WRITE_AUTH_CONFIG_ID |
| Notion | COMPOSIO_NOTION_READ_AUTH_CONFIG_ID |
COMPOSIO_NOTION_WRITE_AUTH_CONFIG_ID |
| Google Search Console | COMPOSIO_SEARCH_CONSOLE_READ_AUTH_CONFIG_ID |
none |
| Google Analytics | COMPOSIO_ANALYTICS_READ_AUTH_CONFIG_ID |
none |
| HubSpot | COMPOSIO_HUBSPOT_READ_AUTH_CONFIG_ID |
COMPOSIO_HUBSPOT_WRITE_AUTH_CONFIG_ID |
| Gong | COMPOSIO_GONG_READ_AUTH_CONFIG_ID |
none |
| Google Ads | COMPOSIO_GOOGLE_ADS_READ_AUTH_CONFIG_ID |
COMPOSIO_GOOGLE_ADS_WRITE_AUTH_CONFIG_ID |
| YouTube | COMPOSIO_YOUTUBE_READ_AUTH_CONFIG_ID |
COMPOSIO_YOUTUBE_WRITE_AUTH_CONFIG_ID |
GitHub
Repositories use GitHub App installation tokens. Both values below can be stored through the Admin wizard instead; the environment value wins. App mode needs both, and either one alone leaves the connection in none mode. Neither variable appears in .env.example.
| Variable | When | Default | Purpose |
|---|---|---|---|
GITHUB_APP_ID |
Optional | unset, falls back to the stored value | Numeric id of the GitHub App. |
GITHUB_APP_PRIVATE_KEY |
Optional | unset, falls back to the stored value | PEM private key used to mint the App JWT. Normalised at use time, not at read time. |
Telemetry
Anonymous, content-free product telemetry is enabled by default and has a complete operator opt-out.
| Variable | When | Default | Purpose |
|---|---|---|---|
DO_NOT_TRACK |
Optional | unset | Set to 1, true, or yes for a total no-op before any state access or network call. Matching is case-insensitive. |
CHICKPEA_DISABLE_TELEMETRY |
Optional | unset | Same values and effect, scoped to Chickpea product telemetry. |
CHICKPEA_TELEMETRY_ENVIRONMENT |
Optional | production on Cloudflare, development on Node |
Labels events as production, development, or test. It never disables them, and an unrecognised value falls back to development. |
Usage recording
Usage recording is additive and fail-open. Each layer is on unless its value is something other than 1 or true, so 0 disables it.
| Variable | When | Default | Purpose |
|---|---|---|---|
USAGE_RUNTIME_RECORDING |
Optional | on | Records usage operations at runtime. |
USAGE_ESTIMATES |
Optional | on | Computes cost estimates from the price catalog. |
USAGE_ADMIN_UI |
Optional | on | Shows the Usage section in Admin. |
CHICKPEA_INSTALLATION_ID |
Optional | chickpea |
Non-secret accounting label shared by every workspace this deployment serves. Must match [A-Za-z0-9][A-Za-z0-9:._/@-]{0,255}; an invalid value falls back to the default. |
Deploy and build
These are read by the deploy and build scripts, not by the running deployment.
| Variable | When | Default | Purpose |
|---|---|---|---|
CHICKPEA_DEPLOY_PROFILE |
Optional, Cloudflare | core |
core or sandbox. The sandbox profile adds the coding sandbox binding and container. Set as a build variable in Settings → Builds → Variables, or use npm run deploy:sandbox. Any other value fails the build. |
CHICKPEA_DEPLOY_INSPECTION_TIMEOUT_MS |
Optional, Cloudflare | 30000 |
Timeout for inspecting the active Worker before deploying. Values above the default are clamped to it. |
CHICKPEA_DEPLOY_READINESS_TIMEOUT_MS |
Optional, Cloudflare | 360000 |
Timeout for the post-deploy readiness wait. Capped at 600000. |
Listed but not read
These names appear in .env.example, .dev.vars.example, or the README, and nothing in the running deployment reads them. Setting one has no effect.
| Variable | Where it appears | What is true instead |
|---|---|---|
SLACK_BOT_TOKEN |
.env.example, README Configuration table |
The one encrypted workspace installation is the only runtime source of the bot token. |
SLACK_SIGNING_SECRET |
.env.example, README Configuration table |
The signing secret is resolved from the same encrypted installation, never from the environment. |
SLACK_BOT_USER_ID |
.env.example |
The bot user id comes from the active stored credential revision. |
TAG_ADMIN_TOKEN |
.dev.vars.example comment |
Slack OIDC is the only human sign-in. No passwords. The name survives only in the secret-redaction pattern. |
TAG_OPENAI_SUBSCRIPTION_ENABLED |
.env.example |
No code reads the gate, and the Cloudflare smoke test asserts the built artifact exposes no OpenAI Subscription preview gate. |
SLACK_TAG_MEMORY_ENABLED |
a verification script only | Memory is always on. There is no memory feature flag or opt-out secret. |
Test and harness variables
The names below are read only by scripts under scripts/, by verification harnesses, or by the maintainer-operated live test environments named amber and cobalt. They are listed for completeness and are not part of operating a deployment.
- Offline and smoke harnesses:
CF_SMOKE_BASE_URL,SMOKE_SKIP_BUILD,SMOKE_SLOW_TURN_DELAY_MS,SMOKE_WRANGLER_PORT,AI_SMOKE_REPLY,NET_GUARD_ALLOW,NET_GUARD_LOG,KEEP_EXPORT_SCRATCH,MODEL_CATALOG_RECONCILE_DATE,AGENT_AUTHORING_EVAL_MODEL,DEPLOY_TEST_READINESS_BASE_URL,DEPLOY_TEST_READINESS_STATUSES. - Live Slack testing:
SLACK_APP_TOKENandPORTfor the development Socket Mode bridge,SLACK_APP_MANIFEST_PATHandSLACK_IDENTITY_ACCEPT_UNKNOWN_ICONfor the identity check,CHICKPEA_GATEWAY_BASE_URLandCHICKPEA_GATEWAY_EXPECT_UNCONFIGUREDfor the shared gateway check. - Management MCP canary:
MANAGEMENT_MCP_BASE_URL,MANAGEMENT_MCP_BEARER_TOKEN,MANAGEMENT_MCP_PROTOCOL_VERSION,MANAGEMENT_MCP_ALLOW_MUTATION,MANAGEMENT_MCP_CANARY_APPLY_PATH. - Managed connector live checks:
COMPOSIO_CONNECTOR,COMPOSIO_CAPABILITY,COMPOSIO_ACCESS_LANE,COMPOSIO_ALLOW_WRITE_CANARY,COMPOSIO_USER_ID,COMPOSIO_CONNECTED_ACCOUNT_ID. - Provider live checks:
CHICKPEA_PERSONAL_TOKEN,OPENAI_SUBSCRIPTION_TEST_MODEL,CAPTURE_DB,CAPTURE_API_KEY,CAPTURE_ADMIN_KEY. - Maintainer live environments:
CHICKPEA_DEPLOY_TARGET,CHICKPEA_DEPLOY_AUTH_DB_ID,CHICKPEA_DEPLOY_SCHEMA_GENERATION,CHICKPEA_AUTH_DB_SCHEMA_GENERATION,CHICKPEA_DURABLE_OBJECT_SCHEMA_GENERATION,CHICKPEA_DEPLOY_STATE_MODE,CHICKPEA_ENVIRONMENT_ROOT,CHICKPEA_ENV_TARGET,CHICKPEA_ENV_SOURCE_REVISION,CHICKPEA_ENV_SOURCE_DIRTY, and the Workers Builds valuesWORKERS_CI,WORKERS_CI_BUILD_UUID,WRANGLER_CI_OVERRIDE_NAME.
