#12839: feat(vault): add vault proxy mode for credential isolation
docs
gateway
cli
agents
size: XL
trusted-contributor
Cluster:
Model Authentication Enhancements
## Summary
- Add vault proxy infrastructure that keeps model API keys out of the gateway process by routing requests through an nginx reverse proxy sidecar that injects credentials from an age-encrypted vault file
- Add `openclaw vault` CLI (init, status, add, remove, list, migrate) for managing age-encrypted secrets with a provider registry mapping providers to proxy ports
- Extend vault proxy support to web search providers (Brave, Perplexity, Grok/xAI) and add Groq, Mistral, xAI, Brave, Perplexity to the provider registry
## Details
**Architecture:** Two Docker networks enforce isolation — the gateway has no route to the internet and no access to plaintext keys. The vault sidecar decrypts `vault.age` at startup, renders an nginx config with credentials, and proxies
requests to upstream APIs.
**Config:** `vault.enabled` + `vault.proxies` in `openclaw.json`. When active, `normalizeProviders()` rewrites `baseUrl` to the proxy URL and substitutes a placeholder API key.
**CLI:** `openclaw vault init` generates an age keypair; `vault add/remove` manage individual secrets with automatic proxy configuration for known providers; `vault migrate` moves plaintext `apiKey` values from config into the encrypted
vault.
**Security:**
- `--proxy-host` validated against hostname regex to prevent SSRF
- `--json --reveal` risk documented in vault.md
- Vault file written with mode 0600, atomic rename
## Test plan
- [x] 143 tests pass across 8 test files
- [x] Proxy resolution, baseUrl rewriting, schema validation (commit 1)
- [x] CLI subcommands: init, add, remove, list, migrate, status (commit 2)
- [x] Web search execute-path tests: Brave, Perplexity, Grok route through vault proxy with auth headers omitted (commit 3)
- [x] Hostname validation rejects SSRF payloads (`attacker.com/path#`, `-bad-host`, empty)
- [x] `buildDefaultProxyMap()` and `findProviderBySecretName()` helper coverage
- [ ] Manual: deploy with docker-compose.vault.yml, verify gateway cannot reach upstream APIs directly
## Use of AI
- Idea / Architecture myself ; code / tests and documentation generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR introduces a “vault proxy” mode intended to keep provider API keys out of the gateway process. It adds:
- A new `vault` config section (`vault.enabled`, `vault.proxies`, `vault.file`, `vault.publicKey`) and schema validation.
- Vault proxy integration in model auth and provider normalization: when a proxy mapping exists, provider `baseUrl` is rewritten to the proxy URL and auth resolution returns a fixed placeholder key.
- Web-search provider support for routing through the vault proxy, omitting auth headers when proxied.
- A new `openclaw vault` CLI for initializing an age-encrypted vault file and managing secrets / migrating plaintext `apiKey` values.
The changes primarily touch the agent configuration pipeline (`ensureOpenClawModelsJson` → `normalizeProviders`), auth resolution (`resolveApiKeyForProvider`, `resolveModelAuthMode`), and tool execution paths for web search. The CLI and vault operations live under `src/cli/vault-cli.ts` and `src/vault/operations.ts` and are registered via the sub-CLI registry.
<h3>Confidence Score: 3/5</h3>
- This PR is close to mergeable but has a likely CLI registration bug that can break the `openclaw` CLI entrypoint when the vault subcommand is loaded.
- Main logic paths look coherent and are covered by tests, but `registerVaultCli()` appears to register a `vault` command that is already declared in the sub-CLI registry. That duplication commonly causes Commander to throw or behave unexpectedly in real runs, and current tests don’t exercise the full CLI registration flow.
- src/cli/vault-cli.ts, src/cli/program/register.subclis.ts, src/agents/tools/web-search.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#12059: feat(agents): Add Azure AI Foundry credential support
by lisanyambere · 2026-02-08
77.4%
#21884: feat(models): auth improvements — status command, heuristics, multi...
by kckylechen1 · 2026-02-20
75.9%
#9163: Fix: Save Anthropic setup token to config file
by vishaltandale00 · 2026-02-04
75.0%
#15756: [Security]: strip provider apiKey from models.json before prompt se...
by SecBear · 2026-02-13
74.6%
#14836: fix: strip apiKey from models.json to prevent credential exposure
by pahud · 2026-02-12
74.5%
#13079: feat: Add OpenAI-compatible API option to CLI for self-hosted models
by MikeWang0316tw · 2026-02-10
74.0%
#16663: feat: GCP Secret Manager integration for external secrets management
by amor71 · 2026-02-15
73.8%
#20212: feat: Add Kilo Gateway provider
by jrf0110 · 2026-02-18
72.9%
#8821: Security: Holistic capability-based sandbox (replaces pattern-match...
by tonioloewald · 2026-02-04
72.6%
#16766: fix(model): apply provider baseUrl/headers override to registry-fou...
by dzianisv · 2026-02-15
72.6%