Skip to content
triage

go · zero deps · entropy + secrets

Security triage for any string.

Score bytes by Shannon entropy, classify what they structurally are — URL, IP, path, hex, base64, UUID — and detect leaked secrets, with redaction. Standard library only.

MIT licensed · no third-party dependencies · Go 1.23+

triage.go
res := triage.Classify([]byte("AKIAIOSFODNN7EXAMPLE"), 4.5)
res.Entropy   // 3.68
res.Category  // "Base64"
for _, s := range res.Secrets {
    fmt.Printf("[%s] %s: %s\n", s.Severity, s.Rule, s.Match)
    // [HIGH] AWS Access Key: AKIA…
}

what you get

Point it at any string.

One small, dependency-free engine: it measures randomness, works out what the bytes structurally are, and flags anything that looks like a leaked credential.

Zero dependencies

Go standard library only — no third-party imports, no supply-chain surface. Drop it into any module and it just builds.

Entropy scoring

Shannon entropy with a configurable bits/byte threshold, so you can flag high-entropy blobs — packed data, keys, ciphertext — from ordinary text.

Content classification

URL, email, IPv4/IPv6 (validated), domain, Windows/Unix paths, hex, base64, and UUID — a structural label for whatever the bytes really are.

Secret detection

15+ providers — AWS, PEM private keys, GitHub/GitLab/Slack/Stripe/Google/Anthropic/OpenAI tokens, JWTs, and generic key=value — each reported with byte offsets.

Redaction

Redact / RedactWith never mutate the input, merge overlapping matches, and mask without leaking the secret's length.

Safe & fast

RE2 patterns — ReDoS-safe and compiled once — plus O(n) entropy and deliberately low false positives.

usage

Classify once, or scan with your own rules.

Call Classify for a one-shot verdict on a byte slice, or build a reusable Scanner with custom rules, an allowlist, and redaction baked in.

// One-shot: entropy + category + secrets
res := triage.Classify(b, 4.5)

fmt.Println(res.Entropy, res.Category)

for _, s := range res.Secrets {
    fmt.Printf("[%s] %s @ %d\n",
        s.Severity, s.Rule, s.Start)
}
// Reusable scanner: custom rules + allowlist
sc := triage.NewScanner(
    triage.WithRules(myRules...),
    triage.WithAllowlist("AKIAIOSFODNN7EXAMPLE"),
)

hits := sc.Scan(b)
clean := sc.Redact(b) // input untouched
  • Classify
  • Scanner
  • Scan
  • Redact
  • RedactWith
  • WithRules
  • WithAllowlist

install

Add it to your module.

One import, no transitive dependencies. Requires Go 1.23+.

go get go get github.com/richardwooding/triage
import import "github.com/richardwooding/triage"

This library powers txtr's --triage / --secrets modes. Full API on the Go Reference.