Skip to content
hbenaliPublic

About

Mask secrets and personal data in logs so they can be shared safely

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

53 Commits

Folders and files

Repository files navigation

logscrub

logscrub: share your logs, not your secrets

Try it in your browser: the real engine compiled to WebAssembly, so what you paste never leaves the page.

Mask secrets and personal data in logs so they can be shared safely (bug reports, tickets, chat).

some-command | logscrub > clean.log
logscrub app.log                 # files work too
logscrub --check app.log         # CI gate: exit 1 if anything would be masked
logscrub --report app.log        # counts per detector, never the matched text
logscrub -r -i logs/             # clean a whole directory in place (add --backup-suffix .bak to keep originals)
logscrub app.log.gz              # gzip input is read transparently
logscrub --mode pseudonym app.log          # stable tags for emails and IPs: the log stays debuggable
logscrub --mode pseudonym --map-file map.json app.log > out.log   # ... and `logscrub restore --map-file map.json out.log` reverses it
logscrub --config logscrub.toml app.log    # allow-list, custom rules, enable/disable detectors
logscrub serve                             # local web UI: paste or drop a log, see what would be masked
logscrub --check --report --report-format sarif app.log > logscrub.sarif   # for CI and code scanning
$ printf 'GET /cb?access_token=abc123\nconnect postgres://app:s3cret@db/x\n' | logscrub
GET /cb?access_token=[REDACTED:kv-secret]
connect postgres://[REDACTED:url-credentials]@db/x

What it masks

Secrets: AWS access and secret keys, GitHub / GitLab / Slack / Stripe tokens, JWTs, PEM private keys (including multi-line blocks), Authorization headers and long Bearer tokens, user:password@ in URLs, and password= / token= / "api_key": "..." style pairs.

Personal data: email addresses, IPv4 and IPv6 addresses (loopback is left alone), payment card numbers (Luhn-checked, known issuer prefixes), and, if you enable it, international phone numbers.

Provider tokens (Docker Hub, Anthropic, OpenAI, Google, npm, PyPI, SendGrid, Hugging Face and more), cookies and session ids, IBANs, and user names in home-directory paths are covered too; the full list with what each one finds is on the Detectors page, and logscrub --list-detectors prints it. SSNs, MAC addresses and a high-entropy catch-all are available as opt-in detectors. Version strings (Chrome/126.0.0.0), timestamps, MAC addresses, ssh://git@host and [email protected] are guarded by tests so they stay untouched.

Pseudonym mode replaces emails and IPs with [email:k3x9p2qa]-style tags derived from an HMAC key, so the same address maps to the same tag across a file and across runs (give --key-file or LOGSCRUB_KEY). Secrets always get a fixed marker, never a tag. See the wiki for the config file. The roadmap is in docs/SPEC.md.

Web UI

Try it without installing anything: https://logscrub.hbenali.ovh/ (the engine runs in your browser as WebAssembly; open the network tab and you will see no request carrying your text). Locally:

The logscrub web UI: a log pasted on the left, every match highlighted by detector in the result below

logscrub serve opens a local page (default http://127.0.0.1:8080): paste or drop a log, see every match highlighted by detector, toggle detectors, switch between markers and stable tags, and download the cleaned text. It uses the same engine as the CLI. The text is processed in memory by the local process; the page loads nothing from anywhere else (strict CSP, no CDN, no analytics). It listens on loopback only unless you pass --allow-remote, because it has no authentication. See the wiki.

Stable tags for emails and IPs, dark theme

The cleaned text with stable tags such as [email:ggyjbrrk] and [ipv4:znrrpfi2]; secrets keep fixed markers

Why another one

  • Linear-time matching. Go's RE2 engine: hostile input cannot trigger ReDoS.
  • Measured false positives. A "must not change" corpus of realistic logs runs in CI; max_tokens=100 and ssh://git@host stay untouched.
  • Bounded memory, fail closed. Streams line by line; a line it cannot scan safely is an error (exit 3), never passed through.
  • No network, no files written, never echoes what it finds. Reports and errors contain counts and ids only.
  • One static binary, a distroless Docker image, signed releases, and a web UI that cannot phone home.

In CI and pre-commit

- uses: hbenali/[email protected]       # GitHub Action: fails if a file would be masked
  with: { files: build.log }
- repo: https://github.com/hbenali/logscrub   # pre-commit hook
  rev: 1.2.1
  hooks: [{ id: logscrub }]

See Using it in CI for SARIF / JSON reports and code scanning.

Stability

From 1.0, the command-line flags, exit codes, the config file format and the [REDACTED:id] / [kind:tag] output formats are stable across 1.x. New detectors may be added in minor releases, so a log that was clean before can have new matches; --check is the way to notice.

Install

# macOS and Linux: Homebrew
brew install hbenali/tap/logscrub

# Ubuntu 22.04, 24.04, 26.04 (amd64): PPA
sudo add-apt-repository ppa:hbenali/logscrub
sudo apt install logscrub

# Fedora 43, 44, rawhide (x86_64): Copr
sudo dnf copr enable hbenali/logscrub
sudo dnf install logscrub

# Any Linux with snapd (amd64): Snap Store
sudo snap install logscrub

# Docker (Docker Hub; the same image is at ghcr.io/hbenali/logscrub)
docker run --rm -i hbenali/logscrub < app.log

# From source (Go 1.26+)
go install github.com/hbenali/logscrub/cmd/logscrub@latest

The PPA and Copr packages install the binary, man page and shell completions, and the package manager keeps them up to date. The snap is strictly confined: it reads and writes files in your home directory and on removable media only (for other files, pipe them in: sudo cat /var/log/app.log | logscrub).

Prebuilt binaries (linux, macOS and windows; amd64 and arm64) and .deb, .rpm and .apk packages are on Releases. They come with a checksum file and build attestations: gh attestation verify FILE --repo hbenali/logscrub. Check an install with logscrub --version. More detail, including shell completion: Installation.

Limits

Regex detection cannot find secrets with no recognisable shape (a password in prose, an unlabelled random string) or encoded ones (base64, URL-encoded). Review the output before sharing it publicly; --check in CI lowers the risk, it does not remove it.

Docs: wiki, SECURITY.md, CONTRIBUTING.md. MIT licensed.

About

Mask secrets and personal data in logs so they can be shared safely

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages