#How do I stop my claw from dropping API keys in our private chats?
1 messages · Page 1 of 1 (latest)
Short answer: not reliably, if the raw key still lives in a file the agent can read.
The hard fix is to keep file read enabled, but move secrets off plaintext config and into SecretRefs. Then OpenClaw keeps secrets in the runtime snapshot, and SecretRef-managed provider creds persist as non-secret markers, not the resolved key.
What to use:
- Fresh setup:
openclaw onboard --secret-input-mode ref - Existing setup:
openclaw secrets configure - Then verify/scrub leftovers:
openclaw secrets audit --check
Relevant docs:
- https://docs.openclaw.ai/gateway/secrets
- https://docs.openclaw.ai/cli/secrets
- https://docs.openclaw.ai/reference/secretref-credential-surface
- https://docs.openclaw.ai/cli/onboard
One important nuance: logging.redactSensitive: "tools" helps with logs/status output, but it is not the same as preventing the model from quoting plaintext it can read.
So, bluntly:
- Prompt rules / AGENTS.md reduce accidents
- SecretRefs are the real answer
- If a key remains in a readable plaintext file, there is no airtight “never leak it” switch
Paste openclaw --version and I can tell you the safest migration path for your setup.
Yeah i'm in the process of setting up a keyring coicidentally and that's when she dropped em TWICE
Yeah, that’s a rotate-now situation, sadly.
If the real keys hit chat twice, I’d assume they’re burned:
- Rotate/revoke those keys now
- Delete the leaked chat messages if you can
- Move the creds to SecretRefs so OpenClaw reads markers, not plaintext files
Best fix going forward:
openclaw secrets configure- then
openclaw secrets audit --check
If you’re still wiring up the keyring, map it through a SecretRef provider (env, file, or exec). That’s the supported way to keep file read available without leaving raw API keys in readable config.
Docs:
One more blunt note: prompt rules can reduce accidents, but they are not a hard boundary. If the model can read plaintext secrets, assume it can eventually spill them.
Paste openclaw --version and I can give you the quickest safe setup for your exact keyring path.
i'm on 2026.4.15 on debian 13
i already have .env setup for everything but gws can't use it
2026.4.15 is new enough, yep. I’d use SecretRefs immediately, not prompt-only guardrails.
My recommendation on Debian 13:
Best quick fix
- Rotate the leaked keys
- Run:
openclaw secrets configure openclaw secrets audit --check openclaw secrets reload - Store the creds as refs, not plaintext
Simplest reliable ref on Debian: env-backed refs
Example manual pattern:
openclaw config set models.providers.openai.apiKey \
--ref-provider default \
--ref-source env \
--ref-id OPENAI_API_KEY
If you’re using a real keyring and want that instead, use a file or exec SecretRef provider. That works too, but the gateway service/user has to be able to read from that keyring at runtime.
So the decision is basically:
- Env refs: easiest, least fragile, my recommendation
- Keyring via file/exec ref: stronger separation, a bit more setup
Docs:
If you tell me which keyring you’re wiring up, I can give you the exact config set / provider config for it.
If by gws you mean the gateway service, that’s probably the issue.
A repo-local .env is often not enough for the daemon, because OpenClaw loads:
.envfrom the current working directory- plus the global fallback
~/.openclaw/.env
For a systemd user service on Debian, the reliable move is:
- Put the keys in
~/.openclaw/.env - Point your creds at those env vars via SecretRefs
- Restart and verify
Useful commands:
openclaw secrets configure
openclaw gateway restart
openclaw models status
Alternative if you want shell env import:
{
env: {
shellEnv: {
enabled: true,
timeoutMs: 15000
}
}
}
Docs:
- https://docs.openclaw.ai/help/faq#env-vars-and-env-loading
- https://docs.openclaw.ai/gateway/secrets
- https://docs.openclaw.ai/cli/secrets
So the clean pattern is:
~/.openclaw/.envfor the daemon-visible env- SecretRefs in config/auth profiles
- no plaintext keys in readable config files
If you want, I can give you the exact minimal setup for OPENAI_API_KEY / ANTHROPIC_API_KEY on Debian.
nah gws as in google workspace
Ah, gotcha, my bad.
If you mean the Google Chat / Google Workspace service account side, env is supported.
OpenClaw supports:
GOOGLE_CHAT_SERVICE_ACCOUNTGOOGLE_CHAT_SERVICE_ACCOUNT_FILE- and
channels.googlechat.serviceAccountRef
For your don’t-ever-spill-it goal, I would not use serviceAccountFile in an agent-readable location. Better:
{
channels: {
googlechat: {
serviceAccountRef: {
source: "env",
provider: "default",
id: "GOOGLE_CHAT_SERVICE_ACCOUNT"
}
}
}
}
That way:
- the config holds a ref
- not the raw JSON
- and the model doesn’t need to read a credentials file to use it
Docs:
- https://docs.openclaw.ai/gateway/configuration-reference
- https://docs.openclaw.ai/reference/secretref-credential-surface
If you mean Gmail/Calendar/Drive via gog OAuth instead of Google Chat service account JSON, that’s a different credential path, so say which one and I’ll give you the exact safe setup.
i'm mainly using gmail/drive via oauth
Ah, okay, that changes the answer a bit.
For Gmail/Drive via OAuth, the annoying truth is:
- OpenClaw stores those creds in auth profiles on the gateway host
- OAuth-mode profiles do not support SecretRef-backed credentials
So for that specific case, there is not currently a supported “keep full file read and make OAuth tokens impossible to read” switch.
Docs backing that:
- https://docs.openclaw.ai/concepts/oauth
- https://docs.openclaw.ai/gateway/authentication
- https://docs.openclaw.ai/reference/secretref-credential-surface
So your real options are:
- Keep OAuth, but make the auth/state store unreadable to the agent
- you can still keep normal file read for your workspace/project files
-
Split trust boundaries
- run the gateway/state under a separate user or host
- let the agent use Gmail/Drive tools, but not browse the token store as files
-
Switch to static creds/service-account flows where possible
- those can use SecretRefs
- but that depends on the exact Google workflow, and it’s not a drop-in replacement for every Gmail/Drive OAuth use case
So, bluntly: for Google OAuth specifically, prompt rules are only a soft guard. If the model can read the auth store, it can still leak it.
If you want, I can help you design the least painful split so you keep normal file read for your project, but wall off the OAuth state.
so when i use gws auth login it mentions something about using env variables GOOGLE_WORKSPACE_CLIENT_ID and ...CLIENT_SECRET, which i've set in .env but it doesn't ever seem to use them. It also stores my plaintext secret in client_secret.json in the .config/gws directory, and i'd like for that to not be plaintext but idk how since i don't think it can use .env string replacement
Two important bits:
-
The current
gwsenv var names include_CLI_
Use:GOOGLE_WORKSPACE_CLI_CLIENT_IDGOOGLE_WORKSPACE_CLI_CLIENT_SECRET
If you set
GOOGLE_WORKSPACE_CLIENT_ID/...CLIENT_SECRET,gwswill ignore them. -
gwsdoes not need OpenClaw.envstring replacement
It reads env vars directly, and current docs say it can also load them from a.envfile.
So the clean way to avoid plaintext ~/.config/gws/client_secret.json is:
- set the
..._CLI_CLIENT_IDand..._CLI_CLIENT_SECRETvars in the environment wheregws auth loginactually runs - don’t keep
~/.config/gws/client_secret.json - then run
gws auth login
One important caveat: this protects against file reads, not against a tool/agent that can inspect process env or run arbitrary commands. So it helps for your exact “don’t leak via readable files” goal, but it is not absolute isolation.
If you’re launching gws through the OpenClaw gateway/service, a repo-local .env may not be the one that process sees. In that case put the vars in the service’s real env, not just a shell-local file.
Docs/source that back this:
<https://github.com/googleworkspace/cli/blob/main/README.md>- env vars listed there are
GOOGLE_WORKSPACE_CLI_CLIENT_IDandGOOGLE_WORKSPACE_CLI_CLIENT_SECRET
If you already used the _CLI_ names and 2026.4.15 still ignores them, that smells like an upstream gws bug/regression, not an OpenClaw config limitation.
i have those variables set, but when i delete client_secret.json it says gws ouath is "not configured" until i put the json file back
Yeah, that sounds like a real gws bug or docs mismatch.
If deleting ~/.config/gws/client_secret.json makes gws auth login say OAuth is “not configured”, then in practice 2026.4.15 is still depending on that file for the login flow, even if the ..._CLI_CLIENT_ID / ..._CLI_CLIENT_SECRET env vars are set.
So the honest answer is:
- env-only does not seem to be working for this flow
- there probably is not a supported “no plaintext
client_secret.json” path right now forgws auth login
One nuance, though: the bigger secret is the refresh token, and gws docs say those are encrypted at rest. client_secret.json is still not great to leave lying around, but it is a smaller problem than a plaintext refresh token.
If your goal is “assistant can keep file read privileges and still can’t spill this”, then the real fix is stronger isolation, like:
- run
gws/ OpenClaw under a different Unix user - or use a short-lived token flow instead of stored OAuth client material
- or wait for/fix an upstream env-only auth path
Given your repro, I’d file it here:
https://github.com/googleworkspace/cli/issues
Something like: docs say GOOGLE_WORKSPACE_CLI_CLIENT_ID / _SECRET are an alternative to client_secret.json, but gws auth login still reports OAuth “not configured” unless the file exists.
well i only need the secret json to login to gws to generated the enc credentials, so i just removed the plaintext key from there and put a ref to the env variable name and i can manually replace it in the future if i need it again
Yeah, that’s a pretty sane workaround.
As long as the encrypted creds are already generated, normal gws use should keep working. You’d only need the real client secret back for things like:
- a fresh
gws auth login - re-consent / scope changes
- recovering from revoked/broken auth
Only caveat: that “ref” in client_secret.json is basically your own placeholder, not something gws will resolve automatically, so future-you will need to swap the real value back in before reauth.
Glad you found a workable middle ground 👍
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it for the next person.
i think the answer to this thread is "use an OS keyring" tbh
Yep, mostly.
I’d phrase it as:
Use an OS keyring for the actual long-lived auth material.
That’s the right answer for the sensitive part.
Small nuance: it doesn’t fully solve gws wanting client_secret.json around for the login/bootstrap path, but it does solve the more important bit, which is keeping refresh tokens / reusable creds out of plaintext files.
So, short version:
- best general answer: use an OS keyring
- annoying current caveat:
gws auth loginmay still want plaintext client client config at setup time
That’s a good summary for the thread.
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.