Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

histscrub

CI License: MIT

A local-machine secret sweep for macOS, written in Swift 6. gitleaks and friends scan your repositories; histscrub scans the laptop itself - the places secrets leak that no repo scanner ever looks: shell and REPL histories, .netrc, .git-credentials, .npmrc, .env files, and the permissions on the credential stores you actually rely on.

Findings are always redacted - histscrub shows you enough of a secret to find it, never enough to leak it again.

Demo

$ histscrub
histscrub · scanned 4 file(s), 11 lines

CRIT  ~/.git-credentials:1  URL with embedded credentials: https:…9@
CRIT  ~/.zsh_history:3  Stripe live key: sk_liv…Qr
CRIT  ~/.zsh_history:4  Anthropic API key: sk-ant…sT
WARN  ~/.netrc  mode 644 - should be 600
WARN  ~/.netrc:3  plaintext password in .netrc:   pass…23
WARN  ~/.zsh_history  mode 644 - should be 600

3 critical, 3 warning(s), 0 info

What it looks at

Default home sweep (histscrub, no arguments)

  • Shell histories: zsh, bash, fish, plus .zsh_sessions/
  • REPL histories: Python, Node, IRB, psql, mysql
  • Ad-hoc credential files: .netrc, .git-credentials, .npmrc, .pypirc, .docker/config.json
  • Permission checks on stores that are supposed to hold secrets (.aws/credentials, ~/.ssh private keys) - their contents are expected, but world-readable mode bits are not

Directory scan (histscrub ~/Developer)

Walks the tree for stray .env*, *.pem, *.key, and id_* files, skipping node_modules, .git, build output, and caches.

Detections

High-confidence token shapes (AWS, GitHub, Slack, Stripe, Google, Anthropic, OpenAI, JWTs, private-key blocks) are flagged everywhere. Looser heuristics (SECRET=/PASSWORD= assignments, --password on the command line, curl -u user:pass) apply only to histories and .env files, where a match is far more likely to be a real leak than a false positive.

The design choice that matters

A secret in ~/.aws/credentials is normal - that file exists to hold it. The same key pasted into your shell history is a leak. histscrub treats expected stores and ad-hoc exposure differently, so it stays quiet about the former and loud about the latter. That is the difference between a scanner you run once and one you keep.

Install

Requires Swift 6 (Xcode 16+ or a Swift 6 toolchain).

git clone https://github.com/GlyphSH/histscrub
cd histscrub
swift build -c release
.build/release/histscrub --version

Usage

histscrub [--json] [dir ...]

Exit codes

Code Meaning
0 clean, or informational findings only
1 warnings
2 critical findings
histscrub --json | jq '.findings[] | select(.severity == "crit")'

Design notes

  • Swift 6 with complete strict-concurrency checking; all model types Sendable.
  • A testable HistscrubKit library core; the executable is a thin CLI over it.
  • Zero dependencies - native Swift Regex, no ArgumentParser.
  • Binary files (NUL byte) and anything over 10 MB are skipped; metafied zsh history with invalid UTF-8 is tolerated, not fatal.

Development

swift test

License

MIT

About

Local-machine secret sweep for macOS: scans shell/REPL histories and ad-hoc credential files for leaked tokens. Redacted findings. Swift 6, zero dependencies.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages