Skip to main content

Scrub secrets and credentials from AI coding assistant session logs

Project description

agentscrub

agentscrub scans local AI agent logs for leaked secrets

Find and redact leaked secrets in local AI coding-agent logs.

agentscrub is an open-source CLI that runs locally and scans AI coding-agent histories, transcripts, tool-call logs, command traces, caches, and local state files.

AI tools like Claude Code, Codex CLI, Cursor, Gemini CLI, Windsurf, Cline, Continue, and others can store sensitive data locally: pasted API keys, .env contents, database URLs, JWTs, OAuth tokens, cloud keys, and shell output. Malware, rogue extensions, compromised packages, or anyone with local machine access can scan those logs for secrets. agentscrub reports masked findings, creates backups, and redacts leaked copies after confirmation.

Example Claude Code history before cleanup (demo secrets):

user: I pasted the staging env for the deploy:
      DATABASE_URL=postgres://app:xK9mP2nL5qR8@db.internal:5432/app
      NPM_TOKEN=npm_A4bC8dEfG2hIjKlMnOpQrSt5UvWxYz3456

Claude Code: The failing request used:
             Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MX0.SflKxwRJSMeK

After agentscrub run:

user: I pasted the staging env for the deploy:
      DATABASE_URL=[REDACTED]
      NPM_TOKEN=[REDACTED]

Claude Code: The failing request used:
             Authorization: Bearer [REDACTED]

https://github.com/user-attachments/assets/9a770a0c-aaa1-42cd-aca8-5e7421c163ea

Set up daily cleaning and never worry again about the fact that you shared some secret with your AI agent:

pipx install agentscrub
agentscrub schedule install   # daily cron job at 03:00, backup before every run

Quick start

# Install
pip install agentscrub

# Or, recommended for CLI tools
pipx install agentscrub

# Read-only audit. Writes nothing.
# If scanners are missing, agentscrub offers to install them automatically.
agentscrub scan

# Redact in place. Asks for confirmation and takes a backup first.
agentscrub run

# Optional: backup + redact daily at 03:00
agentscrub schedule install
agentscrub schedule status

Safety model

  • scan is read-only. It never modifies a file. Use it to see what's exposed.
  • run writes an encrypted timestamped backup of the files it may change before touching anything. Restore with agentscrub rollback.
  • Live login and config files are preserved by design. Files like ~/.claude/.credentials.json, ~/.codex/auth.json, ~/.gemini/oauth_creds.json, and agent config files are scanned and reported but never modified. Full list below.
  • Raw secrets are never printed in reports. Each match gets a stable proof hash so you can correlate the same secret across files without exposing it.
  • All scanners run locally. Nothing leaves your machine.

How it works

flowchart TD
    A[Agent dirs<br/>~/.claude, ~/.codex, ~/.cursor, ...] --> B[3 scanners find secrets]
    B --> C{Live login<br/>or config file?}
    C -->|Yes| D[Reported<br/>Never modified]
    C -->|No| E[Backup +<br/>Redact in place]

What it covers

agentscrub detects supported tools automatically. No config file is required. Each row lists every folder agentscrub recognises across Linux, macOS, and Windows; the first one that exists on your machine is scanned. Plain-text logs, JSONL sessions, and JSON state files are scrubbed in place; SQLite databases (.sqlite, .db, .vscdb) are scrubbed via SQL UPDATE on text columns containing detected secrets.

Tool Where session/log data lives Notes
Claude Code ~/.claude/ JSONL sessions, file-history snapshots, project trees
OpenAI Codex CLI ~/.codex/ sessions/, history.jsonl, logs_*.sqlite, state_*.sqlite
Cursor (CLI/IDE) ~/.cursor/ projects/ (IDE chats), chats/ (CLI), acp-sessions/, logs/
Cursor (server) ~/.cursor-server/ remote-dev / SSH server-side trees
Cursor (desktop) ~/Library/Application Support/Cursor/User/workspaceStorage/, ~/.config/Cursor/User/workspaceStorage/, ~/AppData/Roaming/Cursor/User/workspaceStorage/ chats live in state.vscdb (SQLite)
Google Antigravity ~/.antigravity-server/ server-side IDE state
Windsurf ~/.codeium/windsurf/ (XDG canonical), ~/.config/Codeium/Windsurf/, ~/AppData/Roaming/Codeium/Windsurf/, ~/.windsurf/ Cascade conversation history
Windsurf (server) ~/.windsurf-server/ remote-dev / SSH server-side trees
Windsurf (desktop) ~/Library/Application Support/Windsurf/User/workspaceStorage/, ~/.config/Windsurf/User/workspaceStorage/, ~/AppData/Roaming/Windsurf/User/workspaceStorage/ desktop IDE workspaceStorage
Gemini CLI ~/.gemini/ tmp/<project_hash>/chats/, plus the Antigravity brain/, skills/, commands/ trees
Zed AI ~/.local/share/zed/, ~/Library/Application Support/Zed/, ~/AppData/Roaming/Zed/, legacy ~/.config/zed/conversations/ conversation history in threads/threads.db (SQLite)
OpenCode ~/.local/share/opencode/ (state, sessions) and ~/.config/opencode/ (config) state/session data plus global config
Crush (Charm) ~/.local/share/crush/ (state, logs) and ~/.config/crush/ (config) per-workspace .crush/ state, crush.log
Cline VS Code globalStorage/saoudrizwan.claude-dev/ (cross-OS) or ~/.cline/data/ (CLI mode) tasks/<id>/, state/, checkpoints/
GitHub Copilot Chat Code/User/workspaceStorage/*/GitHub.copilot-chat/ (cross-OS, scoped to the Copilot extension only) chatSessions/, transcripts/, plus state.vscdb chat data
Aider ~/.aider/ repo-local .aider.input.history / .aider.chat.history.md are out of scope. Pass them with --also <path>
Continue ~/.continue/ CLI sessions in ~/.continue/sessions/

Live login & config files preserved (scanned, reported, never modified)

agentscrub run will not write to any of the following. They're the live credentials your agent needs to keep working. They're still scanned and any matched patterns are reported, so you can review them by hand if needed.

Tool Preserved file(s)
Claude Code ~/.claude/.credentials.json, ~/.claude/settings.json, ~/.claude.json
Codex CLI ~/.codex/auth.json, ~/.codex/.credentials.json, ~/.codex/config.toml
Cursor ~/.cursor/mcp.json
Windsurf ~/.codeium/windsurf/mcp_config.json, ~/.codeium/mcp_config.json, ~/.config/Codeium/Windsurf/mcp_config.json, ~/.windsurf/mcp.json, ~/.windsurf/mcp_config.json
Gemini CLI ~/.gemini/oauth_creds.json, ~/.gemini/mcp-oauth-tokens.json, ~/.gemini/settings.json, ~/.gemini/google_accounts.json, ~/.gemini/trustedFolders.json, ~/.gemini/installation_id, ~/.gemini/user_id, ~/.gemini/antigravity/mcp_config.json
OpenCode ~/.local/share/opencode/auth.json, ~/.local/share/opencode/mcp-auth.json, ~/.config/opencode/opencode.{json,jsonc}, ~/.config/opencode/tui.{json,jsonc}
Crush ~/.local/share/crush/mcp.json, ~/.local/share/crush/crush.json, ~/.config/crush/crush.json
Aider ~/.aider.conf.yml
Continue ~/.continue/config.yaml, ~/.continue/config.json, ~/.continue/config.ts, ~/.continue/.env
Cline (VS Code) <globalStorage>/saoudrizwan.claude-dev/settings/cline_mcp_settings.json, …/secrets.json
Cline (CLI) ~/.cline/data/settings/cline_mcp_settings.json, ~/.cline/data/secrets.json, ~/.cline/data/globalState.json
Generic everything under ~/.mcp-auth/

The goal is to remove leaked copies from logs, histories, and caches without breaking agent logins or runtime configuration.

Each scan or run writes one masked audit to ~/.agentscrub/logs/:

  • scan-YYYYMMDD-HHMMSS.txt: complete file-by-file audit with detected pattern type, hit count, and proof hash for every affected file.

Old reports are rotated automatically: agentscrub keeps the newest 30 scan audits and newest 30 cron stdout logs, and removes legacy summary reports.

Raw credentials are never printed in reports. Proof hashes let you recognize the same secret across files without exposing the secret itself.

How it finds secrets

Three open-source scanners run locally, in parallel; agentscrub merges and deduplicates their findings:

Tool Finds
gitleaks JWTs, generic API keys, npm/GitHub tokens
TruffleHog Postgres URIs, GCP/AWS keys, Dockerhub, OAuth, Stripe, Groq, and dozens more
Titus (NoseyParker successor) Username/password pairs, connection URIs, PostHog, LinkedIn, hundreds of generic rules

JSON lines are parsed and secrets are replaced inside string values only, preserving file structure even when secrets contain " or {} characters. SQLite databases are updated via SQL on text columns containing detected secrets.

Install

Requirements: Python ≥ 3.10 and rsync

# Familiar Python install
pip install agentscrub

# Recommended CLI install: isolated environment, clean upgrades/uninstall
pipx install agentscrub

# Optional PII model and structured personal-data redaction
pipx inject agentscrub onnxruntime transformers huggingface-hub numpy

On Linux, pip install --user agentscrub may put the command in ~/.local/bin; add that directory to PATH if your shell cannot find agentscrub.

Detection tools

agentscrub uses three detector binaries: gitleaks, TruffleHog, and Titus.

You do not install them by hand. On first agentscrub scan or agentscrub run, missing detectors are offered automatically:

2 detector(s) missing: TruffleHog, Titus
Install official release binaries to ~/.agentscrub/bin?
Continue? [Y/n]

Downloaded binaries are SHA256-verified against each tool's official release checksums and stored in:

~/.agentscrub/bin/

If a detector is missing, agentscrub scan and agentscrub run show the installer prompt before scanning.

Usage

# See what's exposed. No writes.
agentscrub scan

# Redact (asks for confirmation, creates backup first)
agentscrub run

# Non-interactive (for cron / CI)
agentscrub run --yes

# Restore a previous backup
agentscrub rollback

# Set up daily 3am cron job, then verify the installed user crontab entry
agentscrub schedule install
agentscrub schedule status
crontab -l | grep agentscrub

# Remove the scheduled job
agentscrub schedule uninstall

# Scan an extra directory not in the auto-detect list
agentscrub run --also ~/my-other-ai-tool

# Fast redaction for a tiny terminal/screen text update from stdin
printf '%s' "$terminal_update" | agentscrub redact-text

# Watch/follow stdin and redact chunks as they arrive
tail -f app.log | agentscrub watch-text --alert

# Opt in to heuristic detection of unknown high-entropy token-like strings
printf '%s' "$terminal_update" | agentscrub redact-text --entropy
tail -f app.log | agentscrub watch-text --entropy --alert

# Redact personal information from finite stdin (optional PII extra)
printf 'Contact Maria Garcia at maria@example.com, SSN 123-45-6789' \
  | agentscrub pii-text

# List detected PII without printing the matched values
printf 'Contact Maria Garcia at maria@example.com' \
  | agentscrub pii-detect --count

# Limit the run to specific tools. Repeatable or comma-separated.
agentscrub run --only claude
agentscrub run --only claude,codex
agentscrub --list-tools             # show every known tool ID

# Keep more backups (default: 3)
agentscrub run --max-backups 10

watch-text is the lightweight streaming path for secret and credential patterns. It reads stdin in chunks, emits redacted text immediately, and does not load the PII model. Add --entropy to also catch long, varied token-shaped strings without known vendor prefixes. This is intentionally opt-in: hashes, IDs, and some ordinary generated values can look like secrets. It is not enabled by the scheduled run; that path remains detector-based. Use pii-text for a finite text input when names, addresses, phone numbers, government IDs, or other personal data also need to be redacted.

For a text file, use the watcher as a streaming detector. With --exit-on-detect, status 2 means a match was redacted and status 0 means no match was found:

agentscrub watch-text --entropy --exit-on-detect < output.log >/dev/null

Binary files are not safely redacted in place. To inspect printable strings inside one, pass them through strings first:

strings -a -n 32 artifact.bin \
  | agentscrub watch-text --entropy --exit-on-detect >/dev/null

This checks printable content only; it is not proof that arbitrary binary bytes contain no secret.

Optional PII detection

The PII commands use the local Rampart ONNX model and are separate from the standard secret-only scan and run commands. Install the optional dependencies with:

# pip / virtualenv
pip install 'agentscrub[pii]'

# pipx
pipx inject agentscrub onnxruntime transformers huggingface-hub numpy

The model is downloaded from Hugging Face on first use, then loaded from the local cache. No input text is sent to a remote service. pii-text replaces detected values with stable labels such as [GIVEN_NAME_1] and [EMAIL_1]; pii-detect prints labels, offsets, and short proof hashes rather than the matched values. Both commands read stdin and write the transformed or diagnostic output to stdout.

Backup & rollback

Every live run creates an encrypted backup of the files it may change before touching anything. The encryption key is generated once at ~/.agentscrub/key and stored with 0600 permissions so scheduled runs work without prompts.

~/.agentscrub/backups/
  claude/
    20260429-030000.partial.tar.gz.enc    ← newest
    20260428-030000.partial.tar.gz.enc
    20260427-030000.partial.tar.gz.enc
  codex/
    20260429-030000.partial.tar.gz.enc
    ...

Oldest backups are rotated out automatically (default: keep 3 per tool). Old plaintext backup folders from earlier versions remain restorable and are rotated out normally as newer encrypted backups are created.

To restore:

agentscrub rollback

# Available restore points
#   1  2026-04-29 03:00   3 tools  (today)  47M
#      Claude Code, OpenAI Codex CLI, OpenCode config
#   2  2026-04-28 03:00   9 tools  (yesterday)  348M
#      Claude Code, Cursor, Cursor (desktop), Gemini CLI, +5 more
#
# Restore point # (or q to quit): 1

Use agentscrub rollback --by-tool for advanced single-tool restores.

Scheduled cleanup

agentscrub schedule install adds one entry to the current user's crontab:

0 3 * * * agentscrub run --yes ...

The command verifies the entry after writing it, so a green success means crontab -l can see it. Scheduled runs write stdout/stderr logs to ~/.agentscrub/logs/YYYYMMDD.log; old scan audits and cron logs are rotated automatically.

What it does NOT catch

Gap Why
Plain prose passwords (my password is hunter2) No pattern; indistinguishable from normal text
Short secrets < 8 chars Below minimum length for all three tools
Secrets in binary files Skipped by design
PII in ordinary scan/run logs Not included in the standard secret-only scan; use pii-text or pii-detect with the optional PII extra

Adding a new AI tool

Edit src/agentscrub/discover.py_REGISTRY:

dict(
    tool="my-tool",
    display="My AI Tool",
    dirs=["~/.my-tool/sessions"],
    exclude_dirs={"cache"},
    exclude_files={"credentials.json"},
),

Open a PR. Contributions are welcome.

Upgrade / uninstall

pipx upgrade agentscrub
pipx uninstall agentscrub

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentscrub-1.1.32.tar.gz (77.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentscrub-1.1.32-py3-none-any.whl (64.4 kB view details)

Uploaded Python 3

File details

Details for the file agentscrub-1.1.32.tar.gz.

File metadata

  • Download URL: agentscrub-1.1.32.tar.gz
  • Upload date:
  • Size: 77.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for agentscrub-1.1.32.tar.gz
Algorithm Hash digest
SHA256 5ae10e4d7e04119ae358ef51dc2f4149a61082e63d278c9bf80631376f784bee
MD5 a3f37af05385e929b2b1a5a5441e0b3a
BLAKE2b-256 08f95c55ffea2015cc4c31139c64dc1d663ab71f089b7c9693a2f62fb76b311b

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentscrub-1.1.32.tar.gz:

Publisher: release.yml on ppravdin/agentscrub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agentscrub-1.1.32-py3-none-any.whl.

File metadata

  • Download URL: agentscrub-1.1.32-py3-none-any.whl
  • Upload date:
  • Size: 64.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for agentscrub-1.1.32-py3-none-any.whl
Algorithm Hash digest
SHA256 1c8fa958dfde404f2826a416a524db717910fded77963cb2706e0a6540a33fa3
MD5 1dd45160b55500c4fdbb19fb934605bd
BLAKE2b-256 a4ba2821f86c47f012c1c9831609f751fc0707c39f7abde1e1550c1acd8f1d96

See more details on using hashes here.

Provenance

The following attestation bundles were made for agentscrub-1.1.32-py3-none-any.whl:

Publisher: release.yml on ppravdin/agentscrub

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page