#23444: Gateway: move auth token storage to state dotenv by default
gateway
commands
size: M
trusted-contributor
Cluster:
Gateway Token Management
## Summary
- add shared gateway token storage helpers to persist `OPENCLAW_GATEWAY_TOKEN` in `~/.openclaw/.env` (0600)
- write `gateway.auth.token` as `${OPENCLAW_GATEWAY_TOKEN}` on startup token bootstrap persistence, onboarding writes, and non-interactive onboarding writes
- add doctor migration path to move literal `gateway.auth.token` values into state dotenv and rewrite config to env reference
- update startup log/message copy and onboarding token note text to reflect dotenv-backed storage
## Scope
- `src/gateway/gateway-token-env.ts`
- `src/gateway/startup-auth.ts`
- `src/wizard/onboarding.ts`
- `src/commands/onboard-non-interactive/local.ts`
- `src/commands/doctor.ts`
- related focused tests
## Validation
- `pnpm test src/gateway/gateway-token-env.test.ts`
- `pnpm test src/gateway/startup-auth.test.ts`
- `pnpm test src/wizard/onboarding.test.ts`
- `pnpm test:e2e src/commands/doctor.migrates-gateway-token-to-dotenv.e2e.test.ts`
- `pnpm test:e2e src/commands/onboard-non-interactive.gateway.e2e.test.ts`
- `pnpm test:e2e src/gateway/gateway.e2e.test.ts`
- `pnpm check`
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Migrates gateway auth token storage from inline config (`openclaw.json`) to a separate dotenv file (`~/.openclaw/.env`) with environment variable reference (`${OPENCLAW_GATEWAY_TOKEN}`).
**Key changes:**
- New `gateway-token-env.ts` module with helpers for token storage, env reference handling, and dotenv upsert with 0600 permissions
- `startup-auth.ts` now persists generated tokens to dotenv and writes env reference to config
- `doctor.ts` detects literal tokens in config and offers migration to dotenv storage
- Onboarding flows (interactive and non-interactive) write tokens to dotenv on first setup
- Updated messaging throughout to reflect new storage location
- Comprehensive test coverage including E2E tests for migration path
**Architecture:**
- Token resolution follows precedence: literal config token → env reference → env var fallback
- Migration is safe: `doctor` only migrates when token mode is active and token is not already an env reference
- Backward compatibility maintained through `CLAWDBOT_GATEWAY_TOKEN` support in regex pattern
- File permissions enforced at 0600 for `.env` and 0700 for state directory
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with proper security handling and comprehensive test coverage
- The implementation demonstrates solid engineering practices: proper file permissions (0600 for dotenv, 0700 for state dir), safe migration path that checks for existing env references, comprehensive test coverage including E2E tests, backward compatibility with legacy token names, and proper escaping via JSON.stringify for non-alphanumeric tokens. The changes are well-scoped and follow existing patterns in the codebase.
- No files require special attention
<sub>Last reviewed commit: 9b6e6a3</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22658: Fix onboard ignoring OPENCLAW_GATEWAY_TOKEN env var
by Clawborn · 2026-02-21
80.9%
#19937: fix(gateway): validate token/password auth modes and isolate gatewa...
by NewdlDewdl · 2026-02-18
79.0%
#19885: test(gateway,browser): isolate tests from ambient OPENCLAW_GATEWAY_...
by NewdlDewdl · 2026-02-18
78.7%
#23780: Gateway: fail closed on insecure state directory permissions
by bmendonca3 · 2026-02-22
77.3%
#21651: fix(gateway): token fallback + operator.admin scope superset in pai...
by lan17 · 2026-02-20
76.1%
#9163: Fix: Save Anthropic setup token to config file
by vishaltandale00 · 2026-02-04
75.6%
#11455: fix(gateway): default gateway.mode to local when unset
by AnonO6 · 2026-02-07
75.5%
#23364: Gateway: add risk-ack interlock for dangerous Control UI flags
by bmendonca3 · 2026-02-22
75.5%
#23719: Gateway: fail closed startup on insecure state/config permissions
by bmendonca3 · 2026-02-22
74.4%
#10093: fix: import gateway token from URL param into localStorage
by devjiro76 · 2026-02-06
74.4%