# Environment variables Hankweave reads configuration from several layers, and the process environment is one of them. This page is the lookup surface for every environment variable the 0.10.0 release reads: which component consumes each name, what values it accepts, and where the common mistakes are. It assumes you already know what a hank and a codon are; if not, [Hanks](/concepts/hanks) and [Codons](/concepts/codons) cover those first. ## How to read this page The fastest way to find a variable is to start from the component that reads it. Hankweave's environment consumers fall into a few groups: codon harnesses (the processes that run individual tasks), server runtime configuration, provider health checks, telemetry, and execution support. Each section below covers one group, and every listed variable has a real consumer in the release artifact. Markers such as `since 0.8.0` identify additions or changes recorded in the release history. Before setting a variable, check three things: its exact spelling, its consumer, and its value rules. Spelling matters more than usual here because Hankweave uses prefixes to route variables to different consumers, and a mistyped name is often a hard startup error rather than an ignored setting. For how environment values combine with the other configuration layers, see [Hanks](/concepts/hanks); for the file-based keys, see [Hankweave JSON](/reference/hankweave-json). The names and behavior here follow the 0.10.0 environment-read inventory, provider registry, release history, and captures. ## The three HANKWEAVE\_ prefixes The `HANKWEAVE_` prefix is not one namespace but three, and the prefix you choose decides which component sees the variable: | Prefix | Reaches | Never reaches | | ---------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `HANKWEAVE_` except `RUNTIME_` and `SENTINEL_` | Codon agent processes, with the prefix stripped | The `RUNTIME_`-mapped config object or sentinel-scoped provider lookup; telemetry, trace, cache, and replay names can still be read directly by server consumers | | `HANKWEAVE_RUNTIME_*` | Server runtime configuration | Codon agent processes | | `HANKWEAVE_SENTINEL_` | Sentinel-scoped provider lookup (provider health checks) | Codon agent processes | The table's consumers need two pieces of vocabulary. A codon is one task in the ordered `hank` program; loops in the `hank` array are expanded into a flattened execution plan. A sentinel observes the run's event stream and triggers configured work, and its provider lookup can use a sentinel-scoped credential before the standard provider variable; [Sentinels](/concepts/sentinels) owns the observer and trigger model. Note the boundary in the first column: `HANKWEAVE_RUNTIME_SENTINEL_*` is a different namespace from `HANKWEAVE_SENTINEL_*`. The former selects nested runtime settings, not sentinel credentials. Separately from all three prefixes, the `env` object in `hank.json` is per-codon configuration rather than the system environment; [Hank JSON](/reference/hank-json) documents that field. The ordinary `HANKWEAVE_` route is forwarded by both the Claude Agent SDK and embedded Pi harnesses after the prefix is stripped. The exact value `unset` removes the stripped name from agent child environments and from the server's `process.env` before provider initialization, and Hankweave prints a stripping line when it does this. A codon's `env` object is the final overlay: it wins over a pass-through value and over `unset` for that codon. `requirements.env` accepts either the direct name or its `HANKWEAVE_`-prefixed spelling. It checks the direct spelling first, while sentinel provider lookup checks its sentinel spelling before the standard provider variable. A missing requirement stops startup and `--validate` with `Missing required environment variables: `. That ordering produces an edge case worth knowing. `HANKWEAVE_X=unset` removes direct `X`, but it does not remove the non-empty prefixed spelling from the requirements check, so the requirement passes. The later provider self-test can still fail authentication; in the captured Anthropic case, the diagnostic is `No authentication found (set ANTHROPIC_API_KEY)`. `--validate` reports collected system-prefixed variables with their prefixes stripped and each codon's `env` under an **Environment variables** section; see the [Command-line reference](/reference/cli) for the option's invocation. Hankweave has no `.env`-file loader of its own: values listed here come from the real process environment, such as a shell, CI system, or container. `.env` loading is not a Hankweave feature. The codon `env` overlay described above looks like this in a hank file. These values apply to that codon only; nothing here touches the system environment: ```json { "hank": [ { "id": "database-migration", "name": "Database Migration", "model": "sonnet", "promptFile": "./prompts/migrate.md", "env": { "DATABASE_URL": "postgres://localhost:5432/mydb", "MIGRATION_DRY_RUN": "true" } } ] } ``` The release captures below show this machinery in action: the validation echo with masked values, prefix stripping, provider and requirement failures, and runtime-configuration failures. One capture needs context: the misspelled-runtime case reports the mapped field as a `hank` root field (`prot`), but the trigger is the invalid `HANKWEAVE_RUNTIME_PROT` spelling; it is not a hand-edited `hankweave.json` key. ```text ╭────────────────────────────────────────────────────────────────────╮ │ Hankweave v0.10.0 │ │ darwin arm64 • node v23.8.0 │ ╰────────────────────────────────────────────────────────────────────╯ Calculating data signature for validation... > Validating configuration: /fixtures/scenarios/env-vars/hank.json Data source: /fixtures/scenarios/env-vars/data Execution path: ~/.hankweave-executions/validation- ✓ Configuration is valid! ╭──────────────────────────────────────────────────────────────────────────────╮ │ Environment variables v1.0.0 │ │ 1 codon • 0 loops │ ╰──────────────────────────────────────────────────────────────────────────────╯ └─ [1] write-line (Write one line) model: haiku │ mode: fresh │ prompts: 1 (2 lines) checkpointedGlobs: 1 ╭─ GOOD TO RUN! ─────────────────────────────────────────────────────╮ │ 1 codons • 1 prompts • 0 system prompts • 0 rigs • 1 checkpoints │ ╰────────────────────────────────────────────────────────────────────╯ Run it: hankweave hank.json Environment Variables: From System (HANKWEAVE_ prefixed): - CAPTURE_VERSION: 0.10.0 - FIXTURE_SECRET: ••••••ABCD (24 chars) - FIXTURE_SHORT: abc From Codon Configurations: Codon "Write one line" (write-line): - FIXTURE_MODE: docs - FIXTURE_TOKEN: ••••••cdef (20 chars) exit=0 ``` ```text ╭────────────────────────────────────────────────────────────────────╮ │ Hankweave v0.10.0 │ │ darwin arm64 • node v23.8.0 │ ╰────────────────────────────────────────────────────────────────────╯ Created new execution directory: ~/.hankweave-executions/ New execution: Source → data Exec → ~/.hankweave-executions/ SDKs → Claude node_modules ✓ > Stripped ANTHROPIC_API_KEY from process environment (HANKWEAVE_ANTHROPIC_API_KEY=unset) [] [ERROR] Self-test completed: FAILED [] [ERROR] Self-test FAILED: Some checks failed [] [ERROR] - authentication: ✗ No authentication found (set ANTHROPIC_API_KEY) [ERROR] Server startup failed! Error message: Self-test failed for 1 model(s): - Claude Haiku 4.5 (latest) (anthropic/claude-haiku-4-5): Some checks failed • authentication: No authentication found (set ANTHROPIC_API_KEY) Stack trace: Error: Self-test failed for 1 model(s): - Claude Haiku 4.5 (latest) (anthropic/claude-haiku-4-5): Some checks failed • authentication: No authentication found (set ANTHROPIC_API_KEY) at eU (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:260:5401) at async Egt (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:842:647) at async file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:843:754 exit=1 ``` ```text ╭────────────────────────────────────────────────────────────────────╮ │ Hankweave v0.10.0 │ │ darwin arm64 • node v23.8.0 │ ╰────────────────────────────────────────────────────────────────────╯ Calculating data signature for validation... > Validating configuration: /fixtures/scenarios/env-vars/hank-gemini.json Data source: /fixtures/scenarios/env-vars/data-gemini Execution path: ~/.hankweave-executions/validation- [] [ERROR] Self-test completed: FAILED [] [ERROR] Self-test FAILED: Some checks failed [] [ERROR] - authentication: ✗ Missing API key for provider 'google'. Set GEMINI_API_KEY. Validation failed: Self-test failed for 1 model(s): • - Gemini 2.5 Flash (google/gemini-2.5-flash): Some checks failed • • authentication: Missing API key for provider 'google'. Set GEMINI_API_KEY. exit=1 ``` ```text ╭────────────────────────────────────────────────────────────────────╮ │ Hankweave v0.10.0 │ │ darwin arm64 • node v23.8.0 │ ╰────────────────────────────────────────────────────────────────────╯ Calculating data signature for validation... > Validating configuration: /fixtures/scenarios/env-vars/hank.json Data source: /fixtures/scenarios/env-vars/data Execution path: ~/.hankweave-executions/validation- Validation failed: Missing required environment variables: ANTHROPIC_API_KEY • These are declared in the hank's requirements.env field. exit=1 ``` ```text ╭────────────────────────────────────────────────────────────────────╮ │ Hankweave v0.10.0 │ │ darwin arm64 • node v23.8.0 │ ╰────────────────────────────────────────────────────────────────────╯ Error: Invalid environment variable configuration: - Unrecognized field(s) at hank root: prot. Valid root fields are: $schema, meta, overrides, requirements, globalSystemPromptFile, globalSystemPromptText, hank. Stack: Error: Invalid environment variable configuration: - Unrecognized field(s) at hank root: prot. Valid root fields are: $schema, meta, overrides, requirements, globalSystemPromptFile, globalSystemPromptText, hank. at qmt (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:248:994) at tU (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:249:535) at Egt (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:834:117) at async file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:843:754 exit=1 ``` ```text ╭────────────────────────────────────────────────────────────────────╮ │ Hankweave v0.10.0 │ │ darwin arm64 • node v23.8.0 │ ╰────────────────────────────────────────────────────────────────────╯ Error: Invalid number value for port: "abc" Stack: Error: Invalid number value for port: "abc" at a (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:248:610) at qmt (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:248:923) at tU (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:249:535) at Egt (file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:834:117) at async file:///build/runtime/0.10.0/node_modules/hankweave/dist/index.js:843:754 exit=1 ``` **See also:** [Hank JSON](/reference/hank-json) for `requirements.env` and codon `env`; [Authentication and models](/operate/authentication-and-models) for credential use. ## Runtime configuration variables The `HANKWEAVE_RUNTIME_*` prefix from the table above maps selected names into the server's runtime configuration. The loader strips the prefix, converts `SNAKE_CASE` to camelCase, and supports nested `SENTINEL_` settings. Booleans accept `true` or `1`; numeric values are parsed and reject `NaN`. | Environment spelling | Mapped key | Shape or parse rule | Status / since | | --------------------------------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | | `HANKWEAVE_RUNTIME_PORT` | `port` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_AUTOSTART` | `autostart` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_SHOW_COSTS` | `showCosts` | Presence test; any non-empty value enables | Environment-only; since 0.5.7 | | `HANKWEAVE_RUNTIME_WITHOUT_PROXY` | `withoutProxy` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_MODEL` | `model` | Scalar schema key | Global override | | `HANKWEAVE_RUNTIME_ANTHROPIC_BASE_URL` | `anthropicBaseUrl` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_OUTPUT_DIRECTORY` | `outputDirectory` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_EXECUTION_BASE_DIR` | `executionBaseDir` | Scalar schema key; direct read | Effective root control; since 0.8.0 | | `HANKWEAVE_RUNTIME_LOG_PARSING_INTERVAL` | `logParsingInterval` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_DATA_HASH_TIME_LIMIT` | `dataHashTimeLimit` | Scalar schema key | Maps, not consumed by hashing call sites | | `HANKWEAVE_RUNTIME_IDLE_TIMEOUT` | `idleTimeout` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_SHIM_IDLE_TIMEOUT` | `shimIdleTimeout` | Schema key; the env parser leaves the value a string, so strict numeric validation rejects any non-empty value | Not effective as an env spelling | | `HANKWEAVE_RUNTIME_IGNORE_RIG_FAILURES` | `ignoreRigFailures` | Scalar schema key | Effective | | `HANKWEAVE_RUNTIME_SENTINEL_ENABLE_PERSISTENCE` | `sentinel.enablePersistence` | Nested schema key | Effective | | `HANKWEAVE_RUNTIME_SENTINEL_HEALTH_CHECK_GRACE_PERIOD_MS` | `sentinel.healthCheckGracePeriodMs` | Nested schema key | Effective | | `HANKWEAVE_RUNTIME_SENTINEL_WAIT_FOR_ALL_HEALTH_CHECKS` | `sentinel.waitForAllHealthChecks` | Nested schema key | Effective | The table lists the 12 working flat runtime spellings and the 3 working nested spellings. It also shows `HANKWEAVE_RUNTIME_SHIM_IDLE_TIMEOUT` because the schema declares `shimIdleTimeout`, even though its non-empty environment value is not parsed as a number and fails strict validation. The mapped object is checked against a strict runtime schema, so an unknown spelling such as `HANKWEAVE_RUNTIME_TELEMETRY_ENABLED` is a startup error beginning with `Invalid environment variable configuration:`, and a non-number value produces an invalid-number error. No environment spelling configures budget settings: `HANKWEAVE_RUNTIME_BUDGET_*` maps to unknown keys. The strictness applies only to the environment layer. An invalid or unknown key in `hankweave.json` makes `loadRuntimeConfig` throw, but `resolveSettings` catches that error and silently discards the entire file layer–including valid settings and budget ceilings–and continues with defaults, hank overrides, environment, and CLI. The raw `telemetry` object is read separately and still applies. > **Pitfall:** A mistyped `HANKWEAVE_RUNTIME_*` name is a startup error, while an invalid or unknown `hankweave.json` key silently discards the whole file layer, except for the direct `telemetry` read. Three entries in the table behave differently from their mapping alone. `HANKWEAVE_RUNTIME_DATA_HASH_TIME_LIMIT` maps to and validates the merged `dataHashTimeLimit` field, but the normal hashing call sites do not consume it: execution setup defaults to `DEFAULT_CONFIG.dataHashTimeLimit`, and `--validate` passes that same default. No alternative environment override is documented. `HANKWEAVE_RUNTIME_MODEL` is the environment-layer (layer-4) global model override and prints `> Using global model override: (applies to all codons)` at startup. Model-selection precedence belongs to [Hanks](/concepts/hanks), not this page. `HANKWEAVE_RUNTIME_SHOW_COSTS` is a presence test in the terminal UI at 0.10.0: any non-empty value–including `false` or `0`–enables cost lines; unset or empty hides them. The environment loader still maps the name with its `true`/`1` rule into merged `showCosts`, but that merged value is not consumed. `HANKWEAVE_RUNTIME_EXECUTION_BASE_DIR` is instead read at call time by `getManagedExecutionsRoot()` and overrides `~/.hankweave-executions`. The similarly named `executionBaseDir` JSON key is not the operative root control. This managed root is distinct from `-e, --execution`, which selects a particular execution directory; see [Command-line reference](/reference/cli#-e---execution-path). `HANKWEAVE_RUNTIME_TELEMETRY_*` is not a telemetry namespace: its flat mapping fails strict runtime validation because no matching runtime key exists. Telemetry reads the non-`RUNTIME_` `HANKWEAVE_TELEMETRY*` variables and configuration-file settings instead. Runtime-prefixed variables are excluded from both codon harness pass-through sets. Finally, `anthropicBaseUrl` interacts with the internal proxy. The proxy is disabled by default; the documented `--proxy` switch enables it. When enabled, `anthropicBaseUrl` supplies ProxyRunner's upstream, and the Claude SDK child receives the proxy's own URL as its `ANTHROPIC_BASE_URL` override; that proxy forwards to the configured upstream. With the proxy disabled, the child inherits the ambient `ANTHROPIC_BASE_URL` pass-through. The `anthropicBaseUrl` field only selects the proxy's upstream: neither setting is a universal Pi or Bedrock gateway, and `--without-proxy` is a hidden compatibility flag rather than a primary setup interface. **See also:** [Hankweave JSON](/reference/hankweave-json) for file-layer keys; [Hanks](/concepts/hanks) for model precedence; [LLM proxy](/reference/llm-proxy) for proxy operation; [Telemetry](/reference/telemetry) for telemetry settings. ## Sentinel-scoped provider keys `HANKWEAVE_SENTINEL_` gives a sentinel's provider lookup its own first-choice credential. The registry checks the sentinel spelling first, then the standard variable, and records which source initialized the provider. As the prefix table showed, these variables never reach codon agents. | Sentinel spelling | Standard variable | | --------------------------------------------- | -------------------------- | | `HANKWEAVE_SENTINEL_ANTHROPIC_API_KEY` | `ANTHROPIC_API_KEY` | | `HANKWEAVE_SENTINEL_OPENAI_API_KEY` | `OPENAI_API_KEY` | | `HANKWEAVE_SENTINEL_GROQ_API_KEY` | `GROQ_API_KEY` | | `HANKWEAVE_SENTINEL_GEMINI_API_KEY` | `GEMINI_API_KEY` | | `HANKWEAVE_SENTINEL_DEEPSEEK_API_KEY` | `DEEPSEEK_API_KEY` | | `HANKWEAVE_SENTINEL_AWS_BEARER_TOKEN_BEDROCK` | `AWS_BEARER_TOKEN_BEDROCK` | A Bedrock sentinel accepts `AWS_BEARER_TOKEN_BEDROCK` or an explicit `AWS_ACCESS_KEY_ID` plus `AWS_SECRET_ACCESS_KEY` pair. It signs with `aws4fetch`, not an SDK credential-provider chain. Profile, SSO, container, and instance-metadata sources work for codons but not sentinels. The provider-health-check and codon-self-test credential planes are described in [Authentication and models](/operate/authentication-and-models). **See also:** [AWS Bedrock](/reference/aws-bedrock) for the broader AWS credential story. ## Provider API keys Where the sentinel spellings above end, the standard provider variables begin. The provider registry consumes these standard names, and each registry key has the sentinel override shown in the previous section. `ZAI_API_KEY` and `OPENROUTER_API_KEY` are the exceptions: they are consumed by the embedded Pi harness rather than the registry catalog. | Provider path | Standard variable | Sentinel spelling | Consumer / since | | -------------------------- | -------------------------- | --------------------------------------------- | --------------------------------------------- | | Anthropic | `ANTHROPIC_API_KEY` | `HANKWEAVE_SENTINEL_ANTHROPIC_API_KEY` | Registry, Claude SDK, Pi injection, wizard | | OpenAI metered models | `OPENAI_API_KEY` | `HANKWEAVE_SENTINEL_OPENAI_API_KEY` | Registry, Pi injection, wizard | | Google Gemini | `GEMINI_API_KEY` | `HANKWEAVE_SENTINEL_GEMINI_API_KEY` | Registry, Pi injection, wizard; changed 0.8.0 | | Groq | `GROQ_API_KEY` | `HANKWEAVE_SENTINEL_GROQ_API_KEY` | Registry | | DeepSeek | `DEEPSEEK_API_KEY` | `HANKWEAVE_SENTINEL_DEEPSEEK_API_KEY` | Registry; since 0.7.3 | | Bedrock bearer | `AWS_BEARER_TOKEN_BEDROCK` | `HANKWEAVE_SENTINEL_AWS_BEARER_TOKEN_BEDROCK` | Registry; since 0.9.0 | | GLM | `ZAI_API_KEY` | – | Pi; since 0.7.4 | | Moonshot-Kimi / OpenRouter | `OPENROUTER_API_KEY` | – | Pi; since 0.7.5 | `ANTHROPIC_API_KEY` feeds the registry, Claude SDK pass-through, Pi's enforced-provider injection, and welcome-wizard detection. For the default direct-Anthropic Claude route, it is the required credential; a local Claude Code login alone does not satisfy the normal startup self-test. `HW_INTERNAL_CLAUDE_LEGACY_AUTH` changes that check only for internal or development use and is not the setup recipe. Metered OpenAI models use `OPENAI_API_KEY`. `pi/openai-codex/*` uses a ChatGPT subscription whose OAuth credential is stored by Pi through `pi login`, so that route does not require an environment key. `GEMINI_API_KEY` is the Google key spelling used by Hankweave's live registry, Pi injection, and wizard. `DEEPSEEK_API_KEY` uses `DEEPSEEK_BASE_URL` when supplied, defaulting to `https://api.deepseek.com` after trailing slashes are stripped. `ZAI_API_KEY` serves GLM models in Pi; `OPENROUTER_API_KEY` serves Moonshot-Kimi/OpenRouter models there. `GROQ_API_KEY` initializes the registry provider, whose health-check model falls back to the registry's cheapest model. **See also:** [Authentication and models](/operate/authentication-and-models) for credential choice; [Model resolution](/reference/model-resolution) for model spellings. ## Claude Agent SDK harness variables Provider keys are one input to a codon run; the harness that executes the codon is another. The Claude Agent SDK harness creates a restricted child environment. It does not inherit all of `process.env`. | Name or pattern | Direction | Important boundary | | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | `PATH`, `HOME`, `USER`, `SHELL`, `TMPDIR`, `LANG`, `LC_ALL`, `CLAUDE_CONFIG_DIR` | Explicitly supplied | Essential set | | `CLAUDE_CODE_*` | Passed through | Includes cloud-provider selectors | | `ANTHROPIC_*` | Passed through | With the internal proxy enabled, the child receives the proxy URL; otherwise ambient `ANTHROPIC_BASE_URL` passes through | | `HANKWEAVE_` | Passed after stripping | `RUNTIME_*` and `SENTINEL_*` are excluded | | `HTTPS_PROXY`, `HTTP_PROXY`, `ALL_PROXY`, `NO_PROXY` | Passed in Bedrock mode | Upper- and lowercase forms | | `NODE_EXTRA_CA_CERTS` | Passed in Bedrock mode | Bedrock-mode only | | `HANKWEAVE_AWS_*` aliases and AWS keys in `codon.env` | Stripped in Bedrock mode; not passed as harness-controlled AWS settings | Bedrock credentials remain ambient | Every `CLAUDE_CODE_*` variable passes through, including `CLAUDE_CODE_USE_BEDROCK` and `CLAUDE_CODE_USE_VERTEX`. Bedrock mode sets `CLAUDE_CODE_USE_BEDROCK=1`; `CLAUDE_CODE_SKIP_BEDROCK_AUTH` marks gateway-managed authentication for preflight. Every `ANTHROPIC_*` variable passes through. When the internal proxy is enabled, the SDK child receives the proxy's own URL as `ANTHROPIC_BASE_URL`; when it is disabled, the child inherits the ambient `ANTHROPIC_BASE_URL` pass-through. The `anthropicBaseUrl` configuration field supplies the proxy's upstream only. `CLAUDE_PATH_TO_CLAUDE_EXECUTABLE` selects a custom Claude Code CLI. `CLAUDE_CONFIG_DIR` changes the `~/.claude` credential/configuration directory; Windows fallback also consults `ProgramData`. `HW_INTERNAL_CLAUDE_LEGACY_AUTH` is internal/development-only, as described in the provider section. In Bedrock mode, proxy variables and `NODE_EXTRA_CA_CERTS` are forwarded. AWS settings remain ambient-only: Bedrock mode strips `HANKWEAVE_AWS_*` aliases and filters AWS keys from `codon.env` so a harness switch cannot silently change account or region. **See also:** [AWS Bedrock](/reference/aws-bedrock) for credential setup; [Authentication and models](/operate/authentication-and-models) for harness selection. ## Embedded Pi harness variables The embedded Pi harness takes the opposite approach to the SDK child environment: it resolves provider credentials in the Hankweave process and does not build a child environment at all. The five enforced keys are `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `OPENAI_API_KEY`, `OPENROUTER_API_KEY`, and `ZAI_API_KEY`. They become in-memory Pi runtime keys and take precedence over Pi's on-disk credential store. Other Pi providers, including DeepSeek, Groq, and xAI, resolve their own keys from `process.env`. When a provider key exists only in the effective codon environment (`codon.env` or a stripped `HANKWEAVE_` pass-through), Pi injects it as a runtime key. The in-process overlay is used for provider-credential resolution, the Bash tool's spawn environment, and self-tests. **See also:** [Hank JSON](/reference/hank-json) for codon `env`; [Authentication and models](/operate/authentication-and-models) for provider choice and self-tests. ## Resolve AWS environment variables Bedrock mode draws on the ambient AWS environment for credentials and region. The sentinel factory and Claude Agent SDK use different region paths, which is why the table below separates consumers. | Variable or source | Consumer | Purpose | | ------------------------------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------ | | `AWS_REGION` | Sentinel factory and Claude SDK Bedrock mode | Region input | | `AWS_DEFAULT_REGION` | Sentinel factory and Claude SDK Bedrock mode | Fallback after `AWS_REGION` for the sentinel factory; forwarded to the Bedrock child | | `AWS_PROFILE` | Claude SDK Bedrock mode and ambient detection | Profile-based region or credentials | | Shared default profile | Claude SDK Bedrock mode and ambient detection | Region or credentials when defined | | `AWS_SHARED_CREDENTIALS_FILE` | Ambient detection | Credentials file | | `AWS_CONFIG_FILE` | Ambient detection | Configuration file | | `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` / `AWS_CONTAINER_CREDENTIALS_FULL_URI` | Ambient detection | Container credentials | | `AWS_WEB_IDENTITY_TOKEN_FILE` | Ambient detection | Web identity | | `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN` | Ambient detection; first two for explicit sentinel pair | Credentials | | `AWS_EC2_METADATA_SERVICE_ENDPOINT` / `_MODE` | Ambient detection | Metadata endpoint controls | | `AWS_EC2_METADATA_DISABLED=true` | Ambient detection | Stops the IMDS probe | The sentinel factory uses `AWS_REGION`, then `AWS_DEFAULT_REGION`, then `us-east-1`. The Claude SDK Bedrock child instead lets `AWS_PROFILE` or a region-defining default profile resolve the region when the environment variables are absent; its `us-east-1` fallback applies only when neither profile path resolves one. Ambient detection also checks shared files, container and web-identity sources, explicit access keys, metadata settings, and the shared files' default profile. `AWS_EC2_METADATA_DISABLED=true` disables the instance-role probe. **See also:** [AWS Bedrock](/reference/aws-bedrock) for credential mechanics; [Authentication and models](/operate/authentication-and-models) for provider-plane boundaries. ## Telemetry and tracing variables | Variable | Accepted value or default | Effect | | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | `HANKWEAVE_TRACE_BRAINTRUST` | Set; since 0.7.0 | Enables Braintrust post-run upload | | `HANKWEAVE_TRACE_LANGFUSE` | Set; since 0.7.0 | Enables Langfuse post-run upload | | `HANKWEAVE_TRACE_BINARY` | Command | Replaces the trace command; default `bunx hankweave-trace` under Bun, otherwise `npx hankweave-trace` | | `DO_NOT_TRACK` | `1` | Opts out of telemetry | | `HANKWEAVE_TELEMETRY` | `0` or `false` | Controls telemetry opt-out | | `HANKWEAVE_TELEMETRY_ENDPOINT` | URL; default `https://hw-telemetry.southbridge.ai` | Selects the endpoint | | `HANKWEAVE_TELEMETRY_DEBUG` | `1` | Enables telemetry debug output | | `POSTHOG_API_KEY` | Key | Overrides the embedded public write-only PostHog key | | `CI` | `true` or `1` | Contributes to CI auto-disable | | `GITHUB_ACTIONS`, `TRAVIS`, `CIRCLECI`, `GITLAB_CI`, `JENKINS_URL`, `BUILDKITE`, `DRONE`, `CI_NAME`, `CODEBUILD_BUILD_ID`, `TF_BUILD` | Exists | Contributes to CI auto-disable | Setting either trace variable registers a post-run upload through `hankweave-trace`; setting both registers both flags. Startup runs `hankweave-trace config` and prints `--- hankweave-trace config ---`. Detected problems produce `[hankweave-trace] WARNING: tracing is misconfigured — upload on exit will likely fail.` Telemetry's opt-out precedence and privacy map belong to [Telemetry](/reference/telemetry). The server's telemetry resolver reads the non-`RUNTIME_` `HANKWEAVE_TELEMETRY*` names; because they are ordinary `HANKWEAVE_` variables, the same names are also eligible for prefix-stripped codon pass-through. They are not `HANKWEAVE_RUNTIME_*` settings. CI detection combines `CI` with existence checks for the listed CI-provider variables. The first-run welcome wizard sets `DO_NOT_TRACK=1` for the session when the user declines, and prints permanent `export DO_NOT_TRACK=1` advice; pressing Ctrl+C at the prompt also opts the session out without printing that advice. **See also:** [Observability](/operate/observability) for `hankweave-trace` operation. ## Redirect execution state and replay `HANKWEAVE_CACHE_DIR` redirects the `~/.hankweave/` state-directory default. Telemetry identity (`telemetry.json`), telemetry debug JSONL, and the runtime-extraction cache follow it. `HANKWEAVE_REPLAY_SPEED_MS` defaults to `5` and is read only for timestamp-stripped recordings. `HANKWEAVE_REPLAY_MAX_DELAY_MS` caps timestamp-derived gaps. Both affect replay and test paths; real runs do not read them. These reads are internal or test-only rather than user-facing catalog entries: `HANKWEAVE_TEST_IS_COMPILED`, `NODE_ENV=test`, `npm_execpath`, `npm_command`, and `ProgramData`. **See also:** [Execution directory](/reference/execution-directory) for managed paths; [Telemetry](/reference/telemetry) for telemetry files. ## Keep environment secrets masked `--validate` masks values by variable name. After uppercasing, names matching `SECRET|TOKEN|PASSWORD|PASSWD|PASSPHRASE|CREDENTIAL|PRIVATE|KEY|AUTH|BEARER|SESSION|COOKIE|SIGNING|SIGNATURE|ACCESS|CERT|ENCRYPT|SALT` reveal only the last four characters; short values under those names are fully masked. Names containing `PUBLIC` or `PUBLISHABLE` force display unless they also contain `SECRET`, `PRIVATE`, `TOKEN`, `PASSWORD`, or `PASSWD` – so `LANGFUSE_PUBLIC_KEY` shows while `LANGFUSE_SECRET_KEY` stays masked. The release capture in the prefix section shows this in practice: system `FIXTURE_SECRET` appears as `••••••ABCD (24 chars)` and codon `FIXTURE_TOKEN` as `••••••cdef (20 chars)`, while `FIXTURE_SHORT=abc` and `FIXTURE_MODE=docs` are clear. Masking is by name, not by whether the value looks secret. The companion captures include unset stripping, provider-not-configured, missing-required-key, misspelled-runtime-key, and non-number-runtime-key cases. Masking on output is only half the story; placement matters too. Keep secrets in the system environment, directly or through a `HANKWEAVE_` pass-through, rather than in `codon.env`. Values in `hank.json` become configuration, logs, and checkpoint content. [Codons](/concepts/codons) explains that boundary. **See also:** [Hank JSON](/reference/hank-json) for the `env` field; [The three HANKWEAVE\_ prefixes](#the-three-hankweave_-prefixes) for the captured echo. ## Replace obsolete variable spellings When updating older environment settings, check the Google key name, the supported runtime mappings, and the sentinel provider list: * Hankweave's live provider registry, Pi enforced-provider injection, wizard, and shipped bundle use `GEMINI_API_KEY`; they do not use `GOOGLE_API_KEY`. The old Google-first read and the “Both GOOGLE\_API\_KEY and GEMINI\_API\_KEY are set. Using GOOGLE\_API\_KEY.” warning survive only in removed Pi/gemini shim source at the tag, which is not part of the shipped package or reachable live path. Use `GEMINI_API_KEY` and `HANKWEAVE_SENTINEL_GEMINI_API_KEY`. * The runtime schema declares `HANKWEAVE_RUNTIME_ANTHROPIC_BASE_URL`, `HANKWEAVE_RUNTIME_SHIM_IDLE_TIMEOUT`, and `HANKWEAVE_RUNTIME_IGNORE_RIG_FAILURES`. The first and third are working environment spellings; `HANKWEAVE_RUNTIME_SHIM_IDLE_TIMEOUT` is schema-only because a non-empty environment value remains a string and fails strict numeric validation. Other unknown runtime spellings are startup errors rather than inert settings. * Sentinel lookup covers six providers: Anthropic, OpenAI, Groq, Gemini, DeepSeek, and Bedrock bearer. Budget settings have no environment spelling. See [Hanks](/concepts/hanks) for configuration-layer order and how budget ceilings combine. > **VersionNote:** In 0.8.0, the live Hankweave Google key changed to `GEMINI_API_KEY` and the sentinel spelling became `HANKWEAVE_SENTINEL_GEMINI_API_KEY`. Rename `GOOGLE_API_KEY` in profiles; do not rely on the retained, unreachable shim behavior. **See also:** [Hankweave JSON](/reference/hankweave-json) for file-key corrections; [Upgrading](/start/upgrading) for release migration.