--- summary: "CLI reference for `openclaw secrets` (store, reload, audit, configure, apply)" read_when: - Re-resolving secret refs at runtime - Managing team-scoped values in the shared secret store - Auditing plaintext residues and unresolved refs - Configuring SecretRefs and applying one-way scrub changes title: "Secrets CLI" --- # `openclaw secrets` Manage SecretRefs and keep the active runtime snapshot healthy. | Command | Role | | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `reload` | Gateway RPC (`secrets.reload`): re-resolves refs and atomically publishes the owner-aware runtime snapshot (no config writes); eligible owner failures may publish as cold or stale warnings | | `store` | Manages team-scoped secret and environment values in the local shared state SQLite database | | `audit` | Read-only scan of config/auth/generated-model stores and legacy residues for plaintext, unresolved refs, and precedence drift (exec refs skipped unless `--allow-exec`) | | `configure` | Interactive planner for provider setup, target mapping, and preflight (requires a TTY) | | `apply` | Executes a saved plan (`--dry-run` validates only and skips exec checks by default; write mode rejects exec-containing plans unless `--allow-exec`), then scrubs targeted plaintext residues | Recommended operator loop: ```bash openclaw secrets audit --check openclaw secrets configure --plan-out /tmp/openclaw-secrets-plan.json openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run openclaw secrets apply --from /tmp/openclaw-secrets-plan.json openclaw secrets audit --check openclaw secrets reload ``` If your plan includes `exec` SecretRefs/providers, pass `--allow-exec` on both the dry-run and write `apply` commands. If the closing `audit --check` still reports plaintext findings, update the remaining reported target paths and rerun the audit. Exit codes for CI/gates: - `audit --check` returns `1` on findings. - Unresolved refs return `2` (regardless of `--check`). - Store validation and disclosure-policy failures return `2`. - `store get` returns `3` when the name is missing. Related: [Secrets Management](/gateway/secrets) · [1Password plugin](/plugins/onepassword) · [SecretRef Credential Surface](/reference/secretref-credential-surface) · [Security](/gateway/security) ## Shared secret store `openclaw secrets store` routes writes through the Gateway that owns the local state directory. With the Gateway stopped, it takes exclusive offline ownership until the write and cleanup settle. If the running Gateway is older or cannot be reached, the command refuses without a local fallback; update or stop that Gateway before retrying. The store is Gateway-wide and team-scoped, and `--scope team` is the only accepted value. `--scope me` exits `2` with `Identity scope is not supported yet; use --scope team.` Entries also arrive from **Settings -> Secrets** in the Control UI, and from the agent's [`secrets` tool](/tools/secrets). That tool asks you to type a credential into a masked prompt. It stores the credential without the value reaching the model. ```bash openclaw secrets store list openclaw secrets store set openclaw secrets store get openclaw secrets store rm ... openclaw secrets store import [--from ] ``` Naming and value rules: - Names must match `^[A-Z][A-Z0-9_]{0,127}$`. - Values are limited to 64 KiB (65,536 UTF-8 bytes). An oversized value exits `2` whether it arrives from stdin, `--value`, or `--value-file`. - A `secret` entry may not be empty, because an empty credential cannot be diagnosed later. `get` refuses secret kinds, and listings mask them. `env` entries may be empty. - Known redaction placeholders such as `__OPENCLAW_REDACTED__` cannot be stored as values. CLI `set` and `import` skip redacted inputs for existing usable entries with an explicit unchanged message; a placeholder without a usable existing entry exits `2`. - `--kind secret|env` explicitly changes an entry's kind. Otherwise `set` and `import` preserve the entry's current kind when saving, including protection changes made while input or confirmation is pending. Only new names use automatic detection: names ending in a common credential suffix such as `_API_KEY`, `_TOKEN`, `_PASSWORD`, `_PRIVATE_KEY`, or `_SECRET` become `secret`, and other names become `env`. File paths passed to `--value-file` or `--from` must identify regular files. Named pipes and device paths are rejected; use stdin for streamed input. ### Set values safely `--value` is accepted only when the resolved kind is `env`: ```bash openclaw secrets store set LOG_LEVEL --kind env --value debug ``` For `secret` values, `--value` is refused with exit code `2` because command-line arguments can leak through shell history and process listings. It is also refused if another writer changes the entry to `secret` before the value is saved. Explicit `--kind env` still reclassifies the entry. Use one of the three safe inputs instead: - Pipe stdin when stdin is not a TTY. - Pass `--value-file `. `--value-file -` means stdin. - Run interactively and enter the value in the no-echo prompt. Examples: ```bash op read 'op://Engineering/OpenAI/apiKey' | \ openclaw secrets store set OPENAI_API_KEY --kind secret openclaw secrets store set TLS_PRIVATE_KEY \ --kind secret \ --value-file ./client-key.pem ``` `set` creates or updates a name without duplicate entries. Add `--dry-run` to validate and preview the operation without writing. An online write refreshes affected config references in the Gateway. If that refresh fails after saving, the error reports the saved change and directs you to `openclaw secrets reload`; it does not replay the write locally. `audit` reports previously stored or resolved placeholders as `PLACEHOLDER_VALUE` and counts them as unresolved credentials (exit `2`). For a corrupt store-backed Gateway token, run `openclaw doctor --fix`, restart the Gateway, and reconnect or re-pair devices. See [Gateway token recovery](/cli/doctor/recovery#invalid-gateway-tokens). Secret egress substitution is blocked until each secret has at least one exact allowed host. Bind or replace hosts with repeatable `--allow-host` flags. This policy-only form does not ask for or replace an existing secret value: ```bash openclaw secrets store set OPENAI_API_KEY --allow-host api.openai.com openclaw secrets store set SERVICE_TOKEN \ --allow-host api.example.com \ --allow-host uploads.example.com openclaw secrets store set SERVICE_TOKEN --clear-allowed-hosts ``` Hosts are normalized to lowercase ASCII/punycode. Schemes, paths, ports, and wildcards are rejected. `store list` shows allowed hosts because they are policy metadata, not secret material. ### Read values ```bash openclaw secrets store list --json openclaw secrets store list --plain openclaw secrets store get LOG_LEVEL ``` Secret values never appear in human, `--json`, or `--plain` output. `store get` refuses a `secret` entry as write-only by design and exits `2`. It exits `3` when the name does not exist. Environment-kind values are readable. Team-scoped `env` entries reach Gateway-hosted commands run by OpenClaw's own exec tool, including OpenClaw Code Mode calls into `openclaw:core:exec` and Codex `gateway_exec`. Explicit per-call env wins over store values. Sandbox, remote `node`, ACP, and Codex-native shell execution do not receive them. `secret` entries stay out of subprocesses by default. With `secrets.egressProxy.enabled: true`, Gateway-hosted exec receives only authenticated sentinels and the Gateway replaces them at HTTPS egress. See [Secret egress proxy](/gateway/secrets#secret-egress-proxy). Store entries do not reach commands run inside an external agent harness. The Codex app-server and its sandbox exec-server, and ACP children such as Claude Code, build their own child environment and never pass through OpenClaw's exec preparation. In eligible Codex turns, use `gateway_exec` to enter the OpenClaw-managed Gateway environment path instead. ### Remove values ```bash openclaw secrets store rm OLD_TOKEN openclaw secrets store rm OLD_TOKEN LEGACY_PASSWORD --yes openclaw secrets store rm OLD_TOKEN --dry-run ``` Removing a missing name succeeds quietly. Without `--yes`, the CLI asks for confirmation. Removed rows are soft-deleted and purged after 30 days. ### Import dotenv files Import dotenv-format assignments from a regular file or stdin: ```bash openclaw secrets store import --from .env openclaw secrets store import --from .env --dry-run openclaw secrets store import --from .env --yes op read 'op://Engineering/service-account/dotenv' | openclaw secrets store import --yes ``` The importer supports quoted values and multiline quoted values such as PEM keys. Use `--yes` to skip confirmation and `--dry-run` to inspect the import without writing. Like `store set`, import preserves an existing entry's kind and uses the name-based rule only for new names. Pass `--kind secret|env` to explicitly reclassify all imported entries. The store CLI commands do not accept `--url` or `--token` and do not route through the Gateway. The Control UI uses the admin-scoped `secrets.store.*` RPC methods instead. Those methods refresh the runtime automatically when a changed name is referenced by active config. ## Reload runtime snapshot ```bash openclaw secrets reload openclaw secrets reload --json openclaw secrets reload --url ws://127.0.0.1:18789 --token ``` Uses gateway RPC method `secrets.reload`. Healthy owners refresh independently. Eligible failed owners become stale only when their ref identities, provider definitions, and complete non-secret owner contract are unchanged. New or changed failures become cold. This degraded activation succeeds and reports `warningCount`. Strict or unmapped failures return an error and preserve the previously active snapshot. Options: `--url `, `--token `, `--timeout `, `--json`. ## Audit Scans OpenClaw state for: - plaintext secret storage - unresolved refs - precedence drift (auth profile store credentials shadowing `openclaw.json` refs) - store residue (a team store value duplicated by plaintext in `openclaw.json`) - generated `agents/*/agent/models.json` residues (provider `apiKey` values and sensitive provider headers) - legacy residues (legacy auth store entries, OAuth reminders) The `.env` scan covers the effective state directory and the directory containing the active config. When both paths name the same file, it is scanned once. Sensitive provider header detection is name-heuristic based: it flags headers whose name matches common auth/credential fragments (`authorization`, `x-api-key`, `token`, `secret`, `password`, `credential`). Doctor and secrets audit share the plaintext classification for `openclaw.json`. Known non-secret provider API-key markers such as `ollama-local`, SecretRefs, and non-sensitive provider headers do not produce plaintext warnings. Real plaintext keys still do. ```bash openclaw secrets audit openclaw secrets audit --check openclaw secrets audit --json openclaw secrets audit --allow-exec ``` Report shape: - `status`: `clean | findings | unresolved` - `resolution`: `refsChecked`, `skippedExecRefs`, `resolvabilityComplete` - `summary`: `plaintextCount`, `unresolvedRefCount`, `shadowedRefCount`, `storeResidueCount`, `legacyResidueCount` - finding codes: `PLAINTEXT_FOUND`, `REF_UNRESOLVED`, `REF_SHADOWED`, `STORE_PLAINTEXT_RESIDUE`, `LEGACY_RESIDUE` ## Configure (interactive helper) Build provider and SecretRef changes interactively, run preflight, and optionally apply: ```bash openclaw secrets configure openclaw secrets configure --plan-out /tmp/openclaw-secrets-plan.json openclaw secrets configure --apply --yes openclaw secrets configure --providers-only openclaw secrets configure --skip-provider-setup openclaw secrets configure --agent ops openclaw secrets configure --json ``` Flow: provider setup first (add/edit/remove `secrets.providers` aliases), then credential mapping (select fields, assign `{source, provider, id}` refs), then preflight and optional apply. For `env` and `store` refs, no provider entry is required when `provider` matches that source's effective default: `secrets.defaults.env` or `secrets.defaults.store`, falling back to `default` when unset. Other aliases and all `file`/`exec` refs require a matching `secrets.providers` entry. Flags: - `--providers-only`: configure `secrets.providers` only, skip credential mapping - `--skip-provider-setup`: skip provider setup, map credentials to existing providers - `--agent `: scope auth profile target discovery and writes to one agent store - `--allow-exec`: allow exec SecretRef checks during preflight/apply (may execute provider commands) `--providers-only` and `--skip-provider-setup` cannot be combined. Notes: - Requires an interactive TTY. - Targets secret-bearing fields in `openclaw.json` plus the selected agent's auth profile store. The supported fields are listed in [SecretRef Credential Surface](/reference/secretref-credential-surface). - Supports creating new auth profile mappings directly in the picker flow. - Runs preflight resolution before apply. - Generated plans enable `scrubEnv` and `scrubAuthProfilesForProviderTargets`. `scrubLegacyAuthJson` stays disabled, because Doctor owns legacy `auth.json` migration. Apply is one-way for scrubbed plaintext values. - `--plan-out` refuses to create a plan whose UTF-8 serialized form exceeds 16 MiB (16,777,216 bytes), matching the `apply --from` input limit. - Without `--apply`, the CLI still prompts `Apply this plan now?` after preflight. - With `--apply` (and no `--yes`), the CLI prompts an extra irreversible-migration confirmation. - `--json` prints the plan + preflight report, but still requires an interactive TTY. ### Exec provider safety Package managers often expose symlinked command paths. Resolve the real binary path (for example with `realpath "$(command -v vault)"`) and configure that absolute, non-symlink path. Use `trustedDirs` to restrict executables to approved directories. Run `openclaw config validate` on the Gateway host to check manual exec command paths without executing providers. On Windows, provider paths are rejected when ACL verification is unavailable, with no provider-level bypass. ## Apply a saved plan ```bash openclaw secrets apply --from /tmp/openclaw-secrets-plan.json openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --allow-exec openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run --allow-exec openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --json ``` `--dry-run` validates preflight without writing files. Exec SecretRef checks are skipped by default in dry-run. Write mode rejects plans containing exec SecretRefs/providers unless `--allow-exec`. Use `--allow-exec` to opt in to exec provider checks/execution in either mode. `--from` must point to a regular file no larger than 16 MiB (16,777,216 bytes). The byte limit applies to the complete serialized file, including whitespace. What `apply` may update: - `openclaw.json` (SecretRef targets + provider upserts/deletes) - auth profile store (provider-target scrubbing) - legacy `auth.json` residues - `.env` files in the effective state and active-config directories, for known secret keys whose values were migrated Plan contract details (allowed target paths, validation rules, failure semantics): [Secrets Apply Plan Contract](/gateway/secrets-plan-contract). ### Why no rollback backups `secrets apply` intentionally does not write rollback backups containing old plaintext values. Safety comes from strict preflight plus atomic-ish apply, with best-effort in-memory restore on failure. ## Related - [CLI reference](/cli) - [Secrets management](/gateway/secrets) - [Vault SecretRefs](/plugins/vault) - [1Password plugin](/plugins/onepassword)