openclaw - 💡(How to fix) Fix [Bug]: pre-`#75095` plaintext-token entries in `~/.openclaw/logs/config-audit.jsonl` are never scrubbed after upgrade — live Slack/Telegram/etc. credentials persist at rest indefinitely

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

PR #75095 (closing #60826, merged 2026-05-01) added redactConfigAuditArgv so newly-written entries in ~/.openclaw/logs/config-audit.jsonl mask token-shaped values. But the audit log is pure append-only with no rotation, retention, or one-shot scrub. Any user who ran openclaw config set <path> <secret-value> between commit 748d6821d2 (audit added 2026-02-14) and commit a853c5e8c2 (redactor merged 2026-05-01) — roughly 2.5 months of releases — still has plaintext tokens (Slack xoxb-/xapp-, Telegram bot tokens, gateway tokens, etc.) sitting in their config-audit.jsonl after upgrading to current main (verified on f2458d8828/2026.5.6). Confirmed with two unredacted Slack tokens still at rest on this box despite running an up-to-date redactor-aware build.

Root Cause

  1. On startup (or via openclaw doctor --fix), the gateway / CLI runs a one-shot scrubber that rewrites ~/.openclaw/logs/config-audit.jsonl through redactConfigAuditArgv so every entry's argv and execArgv fields are masked the same way new entries are. Idempotent — safe to re-run on subsequent doctor invocations because already-masked entries pass through unchanged.

Fix Action

Fix / Workaround

  1. Have any user account that, on a pre-#75095 OpenClaw build (i.e. before a853c5e8c2, merged 2026-05-01), ran openclaw config set <path> <secret-value> for a secret-bearing path — channels.slack.botToken, channels.slack.appToken, gateway.auth.token, channels.telegram.botToken, etc. The audit log was added 2026-02-14 (commit 748d6821d2) without argv redaction, so all writes during that window persisted full argv at rest.
  2. Upgrade to current main (or any release ≥ 2026.5.6) which has redactConfigAuditArgv in place.
  3. Observe ~/.openclaw/logs/config-audit.jsonl.
  4. Read entries written in the unredacted window. Expect plaintext token values in the argv field.

…and offered a workaround:

"Manual scrub script that post-processes the log file: We wrote one (scrub-config-audit-log.js) but this should be fixed at the source."

Both entries pre-date the upgrade to a redactor-aware build but persist at rest on the now-current build. File mode is 0600 (-rw-------) and parent directory is 0700, so the initial blast radius is owner-only.

Code Example

$ wc -l ~/.openclaw/logs/config-audit.jsonl
72 /home/orin/.openclaw/logs/config-audit.jsonl

$ grep -c -E 'xoxb-[A-Za-z0-9-]{20,}' ~/.openclaw/logs/config-audit.jsonl
1

$ grep -c -E 'xapp-[A-Za-z0-9-]{20,}' ~/.openclaw/logs/config-audit.jsonl
1

$ grep -oE 'xoxb-[A-Za-z0-9-]{30,}|xapp-[A-Za-z0-9-]{30,}' ~/.openclaw/logs/config-audit.jsonl | sort -u | head | sed 's/[A-Za-z0-9]/X/g'
XXXX-X-XXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX

---

# After running `openclaw config set wizard.lastRunCommand 'xoxb-…03cT'` against `f2458d8828`:
"argv": ["…/node", "…/openclaw.mjs", "config", "set", "wizard.lastRunCommand", "xoxb-1…03cT"]

---

Verbatim of the at-rest leak (token characters obfuscated to `X`; the actual file on this box still has the live token bytes). Two example entries from this box's `~/.openclaw/logs/config-audit.jsonl`, both written `2026-05-02` by the previous build:


{"ts":"2026-05-02T00:03:08.906Z","source":"config-io","event":"config.write","configPath":"…/openclaw.json","pid":1590116,"ppid":1590101,"cwd":"…","argv":["…/node","…/openclaw.mjs","config","set","channels.slack.appToken","xapp-X-XXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"],"execArgv":["--disable-warning=ExperimentalWarning"],,"suspicious":[],"result":"rename",}
{"ts":"2026-05-02T00:03:48.471Z","source":"config-io","event":"config.write","configPath":"…/openclaw.json","pid":1590563,"ppid":1590548,"cwd":"…","argv":["…/node","…/openclaw.mjs","config","set","channels.slack.botToken","xoxb-XXXXXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX"],"execArgv":["--disable-warning=ExperimentalWarning"],,"suspicious":[],"result":"rename",}


Both entries pre-date the upgrade to a redactor-aware build but persist at rest on the now-current build. File mode is `0600` (`-rw-------`) and parent directory is `0700`, so the initial blast radius is owner-only.
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

PR #75095 (closing #60826, merged 2026-05-01) added redactConfigAuditArgv so newly-written entries in ~/.openclaw/logs/config-audit.jsonl mask token-shaped values. But the audit log is pure append-only with no rotation, retention, or one-shot scrub. Any user who ran openclaw config set <path> <secret-value> between commit 748d6821d2 (audit added 2026-02-14) and commit a853c5e8c2 (redactor merged 2026-05-01) — roughly 2.5 months of releases — still has plaintext tokens (Slack xoxb-/xapp-, Telegram bot tokens, gateway tokens, etc.) sitting in their config-audit.jsonl after upgrading to current main (verified on f2458d8828/2026.5.6). Confirmed with two unredacted Slack tokens still at rest on this box despite running an up-to-date redactor-aware build.

Steps to reproduce

  1. Have any user account that, on a pre-#75095 OpenClaw build (i.e. before a853c5e8c2, merged 2026-05-01), ran openclaw config set <path> <secret-value> for a secret-bearing path — channels.slack.botToken, channels.slack.appToken, gateway.auth.token, channels.telegram.botToken, etc. The audit log was added 2026-02-14 (commit 748d6821d2) without argv redaction, so all writes during that window persisted full argv at rest.
  2. Upgrade to current main (or any release ≥ 2026.5.6) which has redactConfigAuditArgv in place.
  3. Observe ~/.openclaw/logs/config-audit.jsonl.
  4. Read entries written in the unredacted window. Expect plaintext token values in the argv field.

Example reproducer on this box (mode-0600 file, owner-only readable, but the secrets are still at rest):

$ wc -l ~/.openclaw/logs/config-audit.jsonl
72 /home/orin/.openclaw/logs/config-audit.jsonl

$ grep -c -E 'xoxb-[A-Za-z0-9-]{20,}' ~/.openclaw/logs/config-audit.jsonl
1

$ grep -c -E 'xapp-[A-Za-z0-9-]{20,}' ~/.openclaw/logs/config-audit.jsonl
1

$ grep -oE 'xoxb-[A-Za-z0-9-]{30,}|xapp-[A-Za-z0-9-]{30,}' ~/.openclaw/logs/config-audit.jsonl | sort -u | head | sed 's/[A-Za-z0-9]/X/g'
XXXX-X-XXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX

(Lengths match Slack xapp-1-… app-level tokens and xoxb-… bot tokens. Full token bytes have been redacted from this report; original strings are still in the log file at rest.)

A fresh openclaw config set on the same box now produces correctly-redacted entries — xoxb-1…03cT, xapp-1…KEqa, 123456…aaaa — confirming the new redactor works for forward writes:

# After running `openclaw config set wizard.lastRunCommand 'xoxb-…03cT'` against `f2458d8828`:
"argv": ["…/node", "…/openclaw.mjs", "config", "set", "wizard.lastRunCommand", "xoxb-1…03cT"]

So the gap is purely the historical residue.

Expected behavior

Either:

  1. On startup (or via openclaw doctor --fix), the gateway / CLI runs a one-shot scrubber that rewrites ~/.openclaw/logs/config-audit.jsonl through redactConfigAuditArgv so every entry's argv and execArgv fields are masked the same way new entries are. Idempotent — safe to re-run on subsequent doctor invocations because already-masked entries pass through unchanged.

    Or

  2. On first observation of an entry written before the redactor commit (or before a stamped "redactor min version" marker), rotate the log: rename the unredacted file to config-audit.jsonl.pre-redactor.<ts> for the user to delete manually, and start a fresh config-audit.jsonl.

Either path closes the door without losing forensic value (hashes, mtimes, suspicion flags, etc., are preserved — only the argv field is masked).

Actual behavior

appendConfigAuditRecord and appendConfigAuditRecordSync (src/config/io.audit.ts:441-467) are pure append-only, mode-0600 writes with no rotation, retention, or migration logic anywhere in the file or its callers. No openclaw doctor --fix action touches it. No upgrade hook touches it. The historical entries persist forever.

Source pointers (current main f2458d8828):

  • src/config/io.audit.ts:86-115redactConfigAuditArgv (the forward-only fix from #75095).
  • src/config/io.audit.ts:124-132snapshotConfigAuditProcessInfo, the only call site for the redactor. Used at write time, never on existing file content.
  • src/config/io.audit.ts:441-467appendConfigAuditRecord / appendConfigAuditRecordSync. Pure appendFile / appendFileSync. No rotation, no retention, no scrub of pre-existing content.
  • grep -rn 'config-audit\|configAudit' src/ shows no rewrite/migrate/scrub/rotate/prune/cleanup callers.

The original issue #60826 already flagged this in its third Impact bullet:

"Credentials persist in the log file indefinitely unless manually scrubbed"

…and offered a workaround:

"Manual scrub script that post-processes the log file: We wrote one (scrub-config-audit-log.js) but this should be fixed at the source."

The PR (#75095) addressed the forward-write half of the problem but did not land the scrub script and did not add a doctor or upgrade-time scrub action. So users who follow the reporter's exact upgrade path still end up with the same plaintext credentials at rest.

OpenClaw version

2026.5.6 (commit f2458d8828)

Operating system

Ubuntu 24.04

Install method

Source checkout

Model

N/A

Provider / routing chain

N/A

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Verbatim of the at-rest leak (token characters obfuscated to `X`; the actual file on this box still has the live token bytes). Two example entries from this box's `~/.openclaw/logs/config-audit.jsonl`, both written `2026-05-02` by the previous build:


{"ts":"2026-05-02T00:03:08.906Z","source":"config-io","event":"config.write","configPath":"…/openclaw.json","pid":1590116,"ppid":1590101,"cwd":"…","argv":["…/node","…/openclaw.mjs","config","set","channels.slack.appToken","xapp-X-XXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"],"execArgv":["--disable-warning=ExperimentalWarning"],…,"suspicious":[],"result":"rename",…}
{"ts":"2026-05-02T00:03:48.471Z","source":"config-io","event":"config.write","configPath":"…/openclaw.json","pid":1590563,"ppid":1590548,"cwd":"…","argv":["…/node","…/openclaw.mjs","config","set","channels.slack.botToken","xoxb-XXXXXXXXXXXXXX-XXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX"],"execArgv":["--disable-warning=ExperimentalWarning"],…,"suspicious":[],"result":"rename",…}


Both entries pre-date the upgrade to a redactor-aware build but persist at rest on the now-current build. File mode is `0600` (`-rw-------`) and parent directory is `0700`, so the initial blast radius is owner-only.

Impact and severity

No response

Additional information

No response

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Either:

  1. On startup (or via openclaw doctor --fix), the gateway / CLI runs a one-shot scrubber that rewrites ~/.openclaw/logs/config-audit.jsonl through redactConfigAuditArgv so every entry's argv and execArgv fields are masked the same way new entries are. Idempotent — safe to re-run on subsequent doctor invocations because already-masked entries pass through unchanged.

    Or

  2. On first observation of an entry written before the redactor commit (or before a stamped "redactor min version" marker), rotate the log: rename the unredacted file to config-audit.jsonl.pre-redactor.<ts> for the user to delete manually, and start a fresh config-audit.jsonl.

Either path closes the door without losing forensic value (hashes, mtimes, suspicion flags, etc., are preserved — only the argv field is masked).

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING