Gateway

Secrets, storage, and logs

Deployment and host trust

  • Full-disk encryption on the gateway host; prefer a dedicated OS user account for the Gateway if the host is shared.
  • Published package dependencies: pnpm-lock.yaml is the reviewed source dependency graph. Plugin packages bundle runtime dependencies by default; native-heavy plugins resolve them at install time from exact-pinned direct dependencies, and the root openclaw package also resolves dependencies at install time. Root and plugin tarballs ship neither npm-shrinkwrap.json nor package-lock.json. See Dependency locking.
  • Secure file operations: OpenClaw uses @openclaw/fs-safe for root-bounded file access, atomic writes, archive extraction, temp workspaces, and secret-file helpers. Optional native acceleration defaults off; set OPENCLAW_FS_SAFE_NATIVE_MODE=auto to use an installed platform binding or require to fail closed when native support is unavailable. Details: Secure file operations.
  • Shared Slack workspace risk: if everyone in Slack can message the bot, the core risk is delegated tool authority - any allowed sender can induce tool calls (exec, browser, network/file tools) within the agent's policy, prompt/content injection from one sender can affect shared state/devices/outputs, and if the shared agent has sensitive credentials/files, any allowed sender can potentially drive exfiltration via tool usage. Use separate agents/gateways with minimal tools for team workflows; keep personal-data agents private.
  • Company-shared agent (acceptable pattern): fine when everyone using the agent is in the same trust boundary (for example one company team) and the agent is strictly business-scoped. Run it on a dedicated machine/VM/container, use a dedicated OS user + dedicated browser/profile/accounts, and do not sign that runtime into personal Apple/Google accounts or personal password-manager/browser profiles. Mixing personal and company identities on the same runtime collapses the separation and increases personal-data exposure risk.

Secrets on disk

Assume anything under ~/.openclaw/ (or $OPENCLAW_STATE_DIR/) may contain secrets or private data:

Path Contents
openclaw.json Config may include tokens (gateway, remote gateway), provider settings, and allowlists.
credentials/** Channel credentials (for example WhatsApp creds), pairing allowlists, legacy OAuth imports.
state/openclaw.sqlite Shared runtime state, including native MCP OAuth access/refresh tokens, dynamic client registration secrets, and discovery state.
agents/<agentId>/agent/openclaw-agent.sqlite Per-agent runtime state, including model auth profiles.
agents/<agentId>/agent/auth-profiles.json Legacy model-auth migration source; doctor imports supported records into the per-agent SQLite database.
agents/<agentId>/agent/codex-home/** Per-agent Codex app-server account, config, skills, plugins, native thread state, diagnostics (default).
$CODEX_HOME/** or ~/.codex/** Native Codex runtime state. The ordinary harness accesses it only with explicit plugins.entries.codex.config.appServer.homeScope: "user". The separate supervision connection accesses it when its resolved home scope is "user", which is the default for stdio or Unix when unset. Contains the native Codex account, config, plugins, and thread store. Supervision lists source metadata and keeps a continued Chat's canonical native branch and later turns on that connection; branching copies bounded persisted user and assistant history into an authenticated, model-locked OpenClaw Chat. Enable only for an owner-controlled Gateway. See Codex harness and Codex supervision.
secrets.json (optional) File-backed secret payload used by file SecretRef providers (secrets.providers).
agents/<agentId>/agent/auth.json Legacy compatibility file; static api_key entries are scrubbed when discovered.
agents/<agentId>/agent/openclaw-agent.sqlite Per-agent runtime state, including session rows and transcripts that can contain private messages and tool output.
agents/<agentId>/sessions/** Legacy session migration sources and archives that can contain private messages and tool output.
bundled plugin packages Installed plugins (plus their node_modules/).
sandboxes/** Tool sandbox workspaces; can accumulate copies of files read/written inside the sandbox.

Credential storage map

Also useful for backup decisions:

  • WhatsApp: ~/.openclaw/credentials/whatsapp/<accountId>/creds.json
  • Telegram bot token: config/env or channels.telegram.tokenFile (regular file only; symlinks rejected)
  • Discord bot token: config/env or SecretRef (env/file/exec/store providers)
  • Slack tokens: config/env (channels.slack.*)
  • Pairing allowlists: ~/.openclaw/credentials/<channel>-allowFrom.json (default account) / <channel>-<accountId>-allowFrom.json (non-default accounts)
  • Model auth profiles: ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite (auth_profile_store)
  • MCP OAuth sessions: ~/.openclaw/state/openclaw.sqlite (mcp_oauth_stores)
  • Legacy OAuth import: ~/.openclaw/credentials/oauth.json

Hardening: keep permissions tight (700 on dirs, 600 on files); use full-disk encryption on the gateway host; prefer a dedicated OS user account if the host is shared.

File permissions

  • ~/.openclaw/openclaw.json: 600 (user read/write only)
  • ~/.openclaw: 700 (user only)

openclaw doctor can warn and offer to tighten these.

Workspace .env files

OpenClaw loads workspace-local .env files for agents and tools, but never lets them silently override gateway runtime controls:

  • Provider credential environment variables are blocked from untrusted workspace .env files - for example GEMINI_API_KEY, GOOGLE_API_KEY, XAI_API_KEY, MISTRAL_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY, PERPLEXITY_API_KEY, BRAVE_API_KEY, TAVILY_API_KEY, EXA_API_KEY, FIRECRAWL_API_KEY, and provider auth keys declared by installed trusted plugins. Put provider credentials in the Gateway process environment, ~/.openclaw/.env ($OPENCLAW_STATE_DIR/.env), the config env block, or an optional login-shell import instead.
  • Any key starting with OPENCLAW_ is blocked from untrusted workspace .env files, reserving the whole runtime namespace so a future OPENCLAW_* control is fail-closed by default rather than silently inheritable from checked-in or attacker-supplied .env content.
  • Channel and provider endpoint-routing settings are also blocked from workspace .env overrides (for example MATRIX_HOMESERVER, MATTERMOST_URL, IRC_HOST, SYNOLOGY_CHAT_INCOMING_URL, AZURE_SPEECH_ENDPOINT, and other keys ending in _ENDPOINT), so a cloned workspace cannot redirect bundled connector traffic through local endpoint config. These must come from the gateway process environment, global runtime dotenv, explicit config, or env.shellEnv.
  • Trusted process/OS environment variables, global runtime dotenv, config env, and enabled login-shell import still apply - this only constrains workspace .env file loading.

Workspace .env files frequently live next to agent code, get committed by accident, or get written by tools; blocking provider credentials prevents a cloned workspace from substituting attacker-controlled provider accounts.

Logs and transcripts

OpenClaw stores session transcripts on disk under ~/.openclaw/agents/<agentId>/sessions/*.jsonl for session continuity and optional memory indexing - any process/user with filesystem access can read them. Treat disk access as the trust boundary and lock down ~/.openclaw permissions; run agents under separate OS users or hosts for stronger isolation.

Gateway logs may include tool summaries, errors, and URLs; session transcripts can include pasted secrets, file contents, command output, and links.

  • Log/transcript redaction is always on and cannot be disabled by config.
  • Add custom patterns for your environment via logging.redactPatterns (tokens, hostnames, internal URLs).
  • When sharing diagnostics, prefer openclaw status --all (pasteable, secrets redacted) over raw logs.
  • Prune old session transcripts and log files if you do not need long retention.

Details: Logging

Secret scanning

CI runs the in-repo scripts/detect-private-keys.mts scanner over every tracked regular file except colocated *.test.ts fixtures and the iOS Fastfile; pull requests run the base branch's copy of the scanner and fail if the base branch lacks it. The local detect-private-key pre-commit hook runs the same scanner over the text files pre-commit hands it. If CI fails, remove or rotate the committed key material, then reproduce locally:

bash
node scripts/detect-private-keys.mts
Was this useful?
On this page

On this page