Help us shape the future of Go! Take the 2026 Go Developer Survey

detect

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package detect runs compiled rules over text fragments and produces findings.

Index

Constants

View Source
const (
	ContextLocal   = "local"   // localhost, private network, docker-compose service, .env.test
	ContextExample = "example" // .env.example / .env.sample / templates
)

Finding contexts. A credential for a local or development service, or in an example/template file, is still reported (a strict policy must see it), but it is capped at low confidence and does not block under balanced.

View Source
const (
	High   = "high"   // provider-specific format, or four or more independent signals
	Medium = "medium" // three independent signals; blocks under balanced too
	Low    = "low"    // fewer signals, or a generic value in a test/example file: review under balanced
)

Confidence levels are qualitative evidence levels, not probabilities: they say how strong the evidence is that a value is a live credential in production code, counted from independent signals (no single signal, in particular entropy, is enough). They are not calibrated against any dataset's labels; measured precision per level is in bench/results.

View Source
const ContextCapPrefix = "capped at low: "

ContextCapPrefix starts the evidence line of a finding capped at low for its local/example context.

View Source
const DefaultPasswordEvidence = "" /* 137-byte string literal not displayed */

DefaultPasswordEvidence is the evidence line of a default password reported outside test, example and documentation files.

View Source
const DefaultPasswordReason = "default-password-in-test-or-doc"

DefaultPasswordReason is the ledger reason for a one-word default password plus digits (admin123, Welcome@2024) in a test, example or documentation file, where it is dropped. Elsewhere it is reported at low confidence with DefaultPasswordEvidence: production configs really do contain these, and an attacker tries them first.

View Source
const FixtureCap = "capped at low: unstructured value in a test/example file"

FixtureCap is the evidence line of a generic value capped at low because it sits in a test/example file.

View Source
const UUIDCredentialEvidence = "UUID-shaped value under a credential-named key: kept at low confidence (UUIDs are usually identifiers)"

UUIDCredentialEvidence is the evidence line of a UUID reported because its key names a credential.

View Source
const YieldsTag = "http-auth"

YieldsTag marks non-generic rules that still give way to provider rules on the same span: an HTTP Bearer value that is also a JWT or a GitHub token is reported once, by the provider rule.

Variables

View Source
var CredentialKey = regexp.MustCompile(`(?i)(?:secret|token|passw|pwd|passphrase|api[_-]?key|apikey|auth(?:orization)?|credential|private[_-]?key|access[_-]?key|key)[a-z0-9_]{0,8}["'\x60]?\s*(?::=|=>|[:=,])\s*["'\x60]?$`)

CredentialKey matches a credential-named key before a value: tokenValue = , "SecretID": , secretVal := , api_key", , Authorization: .

View Source
var DefaultIgnoreMarkers = []string{
	"secretscan:allow", "gitleaks:allow", "pragma: allowlist secret", "trufflehog:ignore", "nosecret", "noqa: secret",
}

DefaultIgnoreMarkers are recognized inline suppressions from common tools.

View Source
var RequestIDKey = regexp.MustCompile(`(?i)(?:(?:request|idempoten|correlation|trace|transaction|session[_-]?id|client[_-]?id|tenant|subscription|object|resource|message|change|sync|csrf|xsrf|nonce|state|lock|lease|revision|etag|continuation|pagination|next|page|cursor|upload|batch|job|order|device|instance|install)[a-z0-9_-]{0,20}|(?:^|[^a-z])[a-z0-9_-]*?(?:id|ids|guid|uuid))["'\x60]?\s*(?::=|=>|[:=,])\s*["'\x60]?$`)

RequestIDKey matches keys whose values are identifiers even when the name contains "token" or "key": request/correlation/idempotency tokens, concurrency and paging tokens (AWS WAF ChangeToken, NextToken, sync tokens, CSRF/state nonces) and any key ending in id (keyId, secret_id). A UUID under such a key is an ID, unlike access_token = <uuid>.

Functions

func Blocks

func Blocks(policy, confidence string) bool

Blocks reports whether a finding of this confidence blocks under a policy: strict blocks everything; balanced blocks medium and high and lists low (weak evidence, generic values in test/example files) for review. See bench/results for the measured trade-off.

func BlocksFinding

func BlocksFinding(policy, testFixtures string, f Finding) bool

BlocksFinding applies the policy to a finding. testFixtures "block" (the CLI default) makes balanced also block generic values capped at low only for sitting in a test/example file; "review" lists them instead. Provider formats there are high confidence and always block.

Local and example credentials (Context set) never block under balanced: they are listed for review. strict blocks everything.

func ConfidenceRank

func ConfidenceRank(c string) int

ConfidenceRank orders confidence levels; unknown values rank lowest.

func DecodeBasicAuth

func DecodeBasicAuth(b64 string) (user, password string, ok bool)

DecodeBasicAuth decodes an HTTP Basic credential (base64 of "user:password"). It reports ok only for printable text with a non-empty user and password; random base64 or encoded binary does not qualify.

func EmbeddedReason

func EmbeddedReason(line, secret string) string

EmbeddedReason reports when secret is only a slice of a longer token in line (a digest, commit SHA or base64 payload), the class of false positive where a provider pattern matches inside unrelated data.

func Fingerprint

func Fingerprint(f Finding) string

Fingerprint is gitleaks-compatible: [commit:]file:rule:line.

func IsTestPath

func IsTestPath(path string) bool

IsTestPath reports whether path looks like test, fixture, example or doc content.

func MeetsSeverity

func MeetsSeverity(f Finding, min string) bool

MeetsSeverity reports whether f is at or above min.

func NoiseReason

func NoiseReason(secret string, quoted bool, path string) string

NoiseReason applies the same value filters used for generic rules to an arbitrary candidate (e.g. from another scanner's report) and returns why it is noise, or "". Callers must only use it for candidates that are not in a provider-specific format.

func Redact

func Redact(f *Finding, pct int)

Redact masks the secret in a finding. pct is the percentage hidden (100 = fully redacted).

func Shannon

func Shannon(s string) float64

Shannon returns the Shannon entropy (bits per character) of s.

func ValidatorNames

func ValidatorNames() []string

ValidatorNames lists the implemented validators (tests check it matches config.Validators).

Types

type Detector

type Detector struct {
	// contains filtered or unexported fields
}

Detector applies a ruleset.

func New

func New(rs *config.Ruleset, opts Options) *Detector

New creates a detector.

func (*Detector) Detect

func (d *Detector) Detect(f Fragment) []Finding

Detect scans one fragment and returns its findings.

func (*Detector) Ruleset

func (d *Detector) Ruleset() *config.Ruleset

Ruleset returns the compiled rules.

func (*Detector) Scan

func (d *Detector) Scan(f Fragment) Result

Scan scans one fragment, returning findings and the suppression ledger.

func (*Detector) SkipPath

func (d *Detector) SkipPath(path string) bool

SkipPath reports whether a path is globally allowlisted, so sources can avoid reading it at all.

type Finding

type Finding struct {
	RuleID       string   `json:"RuleID"`
	Description  string   `json:"Description"`
	Severity     string   `json:"Severity"`
	Tags         []string `json:"Tags"`
	File         string   `json:"File"`
	StartLine    int      `json:"StartLine"`
	EndLine      int      `json:"EndLine"`
	StartColumn  int      `json:"StartColumn"`
	EndColumn    int      `json:"EndColumn"`
	Match        string   `json:"Match"`
	Secret       string   `json:"Secret"`
	Line         string   `json:"Line,omitempty"`
	Entropy      float64  `json:"Entropy"`
	Decoded      string   `json:"Decoded,omitempty"` // encoding chain, e.g. "base64"
	Commit       string   `json:"Commit,omitempty"`
	Author       string   `json:"Author,omitempty"`
	Email        string   `json:"Email,omitempty"`
	Date         string   `json:"Date,omitempty"`
	Message      string   `json:"Message,omitempty"`
	Fingerprint  string   `json:"Fingerprint"`
	SecretHash   string   `json:"SecretHash"` // sha256 of the raw secret; stable across redaction
	Verification string   `json:"Verification,omitempty"`
	// Remediation is filled in after detection (rotation, keyless
	// alternative, replacement expression); see package remediate.
	Remediation *remediate.Guidance `json:"Remediation,omitempty"`
	// Confidence (high/medium/low) and the independent evidence behind it.
	Confidence string   `json:"Confidence"`
	Evidence   []string `json:"Evidence,omitempty"`
	// Blocking is set by the policy: strict blocks every finding, balanced
	// blocks high and medium confidence and reports low for review.
	Blocking bool `json:"Blocking"`
	// Context is "local" (a local/development service: localhost, private
	// network, docker-compose, .env.test) or "example" (.env.example and
	// other templates). Such findings are capped at low confidence.
	Context string `json:"Context,omitempty"`
	// Source and Triage are set when re-scoring another scanner's report.
	Source string `json:"Source,omitempty"`
	Triage string `json:"Triage,omitempty"`
	// contains filtered or unexported fields
}

Finding is one detected secret.

type Fragment

type Fragment struct {
	Raw       string
	FilePath  string
	StartLine int // 1-based line number of the first line of Raw
	Commit    string
	Author    string
	Email     string
	Date      string
	Message   string
}

Fragment is a unit of text to scan, with its origin.

type IgnoreSet

type IgnoreSet struct {
	// contains filtered or unexported fields
}

IgnoreSet suppresses known findings. It understands:

  • gitleaks fingerprints: [commit:]file:rule:line
  • sha256:<hex> of a secret (survives line moves and file renames)
  • rule:<id> or rule:<id>:<file> (suppress a rule globally or for one file)

func NewIgnoreSet

func NewIgnoreSet() *IgnoreSet

NewIgnoreSet returns an empty set.

func (*IgnoreSet) Add

func (s *IgnoreSet) Add(entry string)

Add inserts one entry.

func (*IgnoreSet) Ignored

func (s *IgnoreSet) Ignored(f Finding) bool

Ignored reports whether a finding is suppressed.

func (*IgnoreSet) LoadBaseline

func (s *IgnoreSet) LoadBaseline(path string) error

LoadBaseline adds every finding from a previous JSON report.

func (*IgnoreSet) LoadIgnoreFile

func (s *IgnoreSet) LoadIgnoreFile(path string) error

LoadIgnoreFile adds entries from an ignore file (.secretscanignore or .gitleaksignore). Missing files are not an error.

type Options

type Options struct {
	MaxDecodeDepth int      // 0 disables base64/hex/percent decoding
	IgnoreMarkers  []string // inline markers that suppress a finding on that line
	NoNoiseFilters bool     // audit mode: disable heuristic false-positive filters
	// RecordSuppressed keeps every filtered candidate (not just counts).
	RecordSuppressed bool
}

Options tune detection.

type Result

type Result struct {
	Findings   []Finding
	Suppressed []Suppressed   // only when Options.RecordSuppressed
	Counts     map[string]int // suppression reason -> count (always)
}

Result is the outcome of scanning one fragment.

type Suppressed

type Suppressed struct {
	RuleID     string `json:"RuleID"`
	File       string `json:"File"`
	StartLine  int    `json:"StartLine"`
	Commit     string `json:"Commit,omitempty"`
	Reason     string `json:"Reason"`
	Secret     string `json:"Secret"`
	SecretHash string `json:"SecretHash"`
}

Suppressed is a candidate that matched a rule but was filtered out. The ledger exists so nothing is ever dropped invisibly: counts are always reported and --show-suppressed lists every entry with its reason.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL