Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Choose a scanning workflow

Start with the source boundary you need. Then choose a detection policy and an execution route. These are separate decisions: a backend changes how KeyHog executes, while a preset changes what detection work it performs.

Choose in 30 seconds

Your boundaryStart hereDo not substitute
One checked-out repository in GitHub ActionsGitHub ActionAn organization inventory job
One checkout in GitLab, CircleCI, Jenkins, Buildkite, or a shell runnerCI secret scanningAction-specific inputs or outputs
A Git provider organization, cloud bucket, or partitioned estateMass scanningOne oversized repository gate
A local working treeYour first scanGit history unless you select it
Staged content or changed linesPre-commit or --git-diffA full checkout scan when the policy is diff-only
Repeated one-file or bounded-stdin requests on UnixDaemon and warm scansDirectories, Git, archives, remote sources, or verification
A local host and mounted filesystemsSystem-wide triageRepository or cloud inventory ownership

Then make three independent choices:

  1. Select the source boundary. This determines which bytes are eligible.
  2. Keep the default detection policy unless you accept a documented fast, deep, or precision tradeoff.
  3. Use calibrated automatic routing for normal scans. Select an explicit backend only for diagnosis, measurement, or a required-accelerator gate.

If any source reports incomplete coverage, preserve that status with the findings and report. A partial scan is not a clean scan.

Choose the source boundary

TaskCommand or workflowWhat it covers
Scan a working tree oncekeyhog scan .Files present below the selected path. It does not add Git history automatically.
Scan staged contentkeyhog scan --git-staged or keyhog hook installExact blobs in the Git index. It does not scan unstaged working-tree bytes.
Gate a pull-request checkoutGitHub Action or keyhog scan .The checked-out tree. Add a committed baseline when existing findings should remain visible without blocking adoption.
Gate only pull-request changeskeyhog scan --git-diff <base>Changed lines relative to the selected base. This is narrower than scanning the checkout.
Scan reachable commit additionskeyhog scan --git-history .Added lines from reachable commit patches, bounded by max_commits and the ancestry present in the checkout. A credential on a branch this checkout never had, or one left behind by git commit --amend, is missed with no coverage gap.
Scan the repository object databasekeyhog scan --git-blobs .Deduplicated blobs from refs, reflogs, stashes, annotated tags, and unreachable or dangling objects still present in .git. This is broader than reachable commit history, but cannot recover objects already pruned from the clone.
Verify a releasekeyhog scan --git-history . --git-blobs . --verifyReachable additions and blobs, plus live checks for eligible detectors. Verification sends credential-derived requests to provider endpoints.
Scan a Git provider or cloud inventory--github-org, --gitlab-group, --bitbucket-workspace, --s3-bucket, --gcs-bucket, or --azure-container-urlOne provider inventory. Partition larger estates into independent jobs with separate reports and exit codes.
Scan GitHub collaboration content--github-collaborationIssues, pull requests, discussions, wikis, and gists selected by the collaboration workflow.
Audit a hostkeyhog scan-systemEligible local mounted filesystems and discovered Git histories under one space ceiling.
Continuously guard a repositorykeyhog guard add <repo> --mode repoPerpetual Git repository indexing with in-memory clean attestation caching for instant pre-commit scans.
Reuse a warm scanner on UnixStart keyhog daemon start, then scan one file or bounded stdinKeeps the compiled scanner and accelerator warm for repeated single-file or stdin requests.
Stream mass directory batcheskeyhog scan --daemon=mass ...Streams bounded source batches from large directories or trees to a mass-enabled daemon.
Monitor local directories in foregroundkeyhog watch <path>...A foreground filesystem-event loop with an in-process scanner.
Inspect a native executable or firmware imagekeyhog scan --binary app.binPrintable strings and supported native object sections, on a build with the binary feature. A directory walk records binaries as skipped and does not reinterpret them as text; --no-default-excludes does not change that. A directory containing only skipped binaries exits 13 because zero source bytes reached the scanner. A mixed tree can still exit 0 with an advisory binary gap, so inspect coverage_gap_summary.

Read Your first scan for a local repository, CI secret scanning for direct CI jobs, and Mass repository and cloud scanning for inventory partitioning and coverage.

Choose a scan policy

PolicyCommandResolved behavior
Defaultkeyhog scan .Decode depth 10, ML enabled, and entropy evidence for eligible structured candidates. Decoding is capped at --decode-size-limit, 512K by default, applied per chunk rather than per file. Generic source-file entropy discovery is off. The global confidence floor is 0.40 unless detector policy owns a different floor.
Fast presetkeyhog scan . --fastNamed regex and multiline matching remain. Decode, entropy discovery, and ML are off in the base preset. An explicit compatible option such as --decode-depth 2 can refine it.
Deep presetkeyhog scan . --deepSource-file entropy and comment scanning at full confidence, heuristic evidence beside entropy ML, decode depth 10, and prepared decode chunks up to 1 MiB.
Precision presetkeyhog scan . --precisionEntropy discovery and the relaxed keyword bridge are off, ML remains on for eligible candidates, decode depth is 1, and every confidence floor is at least 0.85.
Lockdown modekeyhog scan . --lockdownLinux-only fail-closed process protection. It is a security execution mode, not a detection preset. It requires sufficient locked-memory capacity and refuses incompatible completeness-reducing, network, daemon, cache, and plaintext-output requests.

The three presets are mutually exclusive bases. Compatible explicit options refine them; a precision confidence override may raise but never lower 0.85. Lockdown refuses fast and other completeness-reducing switches, and always runs in process. See Configuration and Hardening.

The default decode cap can hide an encoded credential

Decide this one before you trust a clean result on a repository with large files. A Base64-encoded credential in a chunk above --decode-size-limit is never decoded, so it is never reported. The scan exits 0:

file size    keyhog scan <file>                       with --deep
400K         1 finding, exit 1, status success        1 finding, exit 1
510K         1 finding, exit 1, status success        1 finding, exit 1
520K         0 findings, exit 0, status partial       1 finding, exit 1
600K         0 findings, exit 0, status partial       1 finding, exit 1

The miss is reported, but only in the envelope. coverage_gap_summary carries scanner decode-through declined by --decode-size-limit, and scan_status becomes partial. The exit code stays 0, so a CI gate that branches on the exit code alone passes over a real credential. Gate on the gap reason, not the exit code.

Position in the file governs this, not size. The cap applies per chunk, and a file is read in 1 MiB windows, so only the short tail window of a large file can fall under the 512K limit. An encoded credential in the interior of any file above about 1 MiB is never decoded, at any file size:

2000K file, payload at end of file       1 finding, exit 1
2000K file, payload in the middle        0 findings, exit 0
3000K file, payload at end of file       1 finding, exit 1
3000K file, payload in the middle        0 findings, exit 0

That is also why the size table above looks erratic: planting at the end of the file tests the one position that can still succeed, and the tail window’s size rises and falls as the file grows. Do not infer a safe file size from a fixture that passed, and do not build a regression fixture that plants at the end.

Either preset choice restores it. --deep raises the ceiling as part of its policy, and --decode-size-limit 4M raises it without changing anything else:

keyhog scan . --decode-size-limit 4M

Choose an execution route

Normal scans use auto. An explicit backend is a diagnostic or benchmark contract, not a recommendation for routine routing.

RouteSelect it withUse case and boundary
Calibrated automatic routingRun keyhog calibrate-autoroute, then keyhog scan .Chooses the fastest parity-checked eligible backend for the exact host, binary, detector policy, and workload class. A normal scan does not benchmark.
Portable CPU-only buildInstall with cargo install --locked keyhogThis is the default on every host. It includes local, remote, container, and native binary sources without Hyperscan, GPU, or Ghidra build prerequisites. A scalar-only build has no routing choice and needs no autoroute cache.
Explicit pure-Rust CPU--backend cpuDiagnose the portable path or compare it in a benchmark. --no-gpu is not equivalent because Hyperscan may remain eligible.
Hyperscan or VectorscanLet calibrated auto select it, or diagnose with --backend simdAccelerated CPU trigger matching followed by the shared extraction and policy pipeline. It requires a compatible build and runtime.
CUDA, native Metal, or WGPULet calibrated auto select an eligible peerGPU region-presence matching followed by the same confirmation pipeline. GPU availability does not mean the GPU is fastest for every workload.
Required GPU--require-gpu, [system].gpu = "required", or diagnostic `–backend gpu-cudagpu-metal
Warm Unix daemon & GuardStart keyhog daemon start; use --daemon=on or keyhog guardRemoves repeated scanner startup for eligible single-file or stdin requests, and serves perpetual repository guard commit transactions with clean attestation caching.

Use keyhog --version --full to inspect compiled capability, keyhog backend --self-test --json to prove backend health, and keyhog backend --autoroute --json to inspect the measured route. These commands answer different questions: discovery, correctness, and comparative selection.

Choose a detector corpus mode

--detectors <DIR> selects a custom detector directory. Choose how it participates in the corpus:

ModeCommandResult
Replace--detectors ./reviewed --detectors-mode replaceUses only the custom directory. This is also the compatibility behavior when an explicit custom directory omits the mode.
Overlay--detectors ./extra --detectors-mode overlayAdds the custom directory to the embedded corpus. Duplicate detector IDs fail corpus loading.

The selected corpus owns matching, validation, entropy, suppression, ML, and declared decode-transform policy. Replace mode does not inherit detector-local policy from the embedded corpus. See Detectors.

What KeyHog can scan

The default and official release builds support the sources below. Reduced source builds can omit feature-gated Git, web, cloud, container, and verifier support. Every enabled source feeds the same compiled detector pipeline.

SourceHow to point at itChapter
Working treekeyhog scan <path>... (default)Your first scan
stdin / single file--stdin or keyhog scan path/to/fileDaemon and warm scans
Git history--git-history <repo>Deep recovery
Git diff / staged--git-diff <range>, --git-stagedPre-commit hook
GitHub org / repos--github-org, --github-collaboration (issues, PRs, discussions, wiki, gists)GitHub collaboration scans
GitLab group--gitlab-groupMass scanning
Bitbucket workspace--bitbucket-workspaceMass scanning
S3 / GCS / Azure Blob--s3-bucket, --gcs-bucket, --azure-container-urlMass scanning
Docker image--docker-image <ref>Mass scanning
Web URLs--url <url>...HTTP and wire scanning
HAR captureskeyhog scan capture.harHTTP and wire scanning
Archives, compressed files, and supported containerspass the containing path; formats are detected during filesystem and remote-source expansionSource archives

How KeyHog decides what is real

Precision is the product. A finding survives several independent stages before it reaches your terminal.

StageWhat it doesChapter
DetectorsThe embedded detector catalog is compiled from TOML data under detectors/; query the running binary for its exact countDetectors
Entropy and shapevectorized entropy plus declarative charset/grouping shape checksHow detection works
On-device MoEa small mixture-of-experts model scores ambiguous candidates locallyHow detection works
Context and suppressionexample-credential, vendored-bundle, comment, and ${{ secrets.NAME }} suppression by defaultSuppressions
Verificationoptional live checks for detectors with a verification plan; these checks send credential-derived requests to the serviceVerification

How KeyHog stays fast

CapabilityWhat it buys youBoundaryChapter
Autoroute calibrationPicks the fastest correct backend for the exact host, binary, detector corpus, policy, and workload class.Normal scans consume persisted evidence. They do not benchmark or guess on a cache miss.Autoroute calibration
Parallel scan workersUses the available CPU cores by default. --threads <N> caps scanner workers when a shared runner has a smaller CPU budget.Concurrent KeyHog processes each own a worker pool. Divide the host budget across partitions instead of letting every process claim every core.CLI reference
Dedicated readersOverlaps filesystem reads with scanning. The reader count derives from the scan worker pool by default.Set --reader-threads only after profiling the target storage path.CLI reference
Incremental scansReuses trusted clean-file proofs so repeated scans of one tree skip unchanged files; an all-hit run starts no backend dispatch.Keep one cache per repository or partition. Do not share it across unrelated or untrusted workspaces.Mass scanning
Partition concurrencyRuns independent repositories, provider targets, or buckets in parallel with independent retry boundaries.Preserve one envelope and raw exit code per partition.Mass scanning
Verification limitsControls live provider traffic separately with --verify-concurrency, --verify-rate, and --verify-batch.Provider quotas, not scanner worker count, own this concurrency.Verification
GPU region presenceUses VYRE CUDA, native Metal, or WGPU dispatch for the whole corpus at once when measured routing evidence selects it.GPU availability alone does not prove it is fastest for the workload.Backends and routing
Hyperscan SIMD prefilterUses vectorized literal and regex prefiltering on the accelerated CPU path.Let calibrated automatic routing compare it with every eligible peer.Backends and routing
Daemon and warm scansServes IDE-save and single-file scans without cold start on Unix.Directories, Git, archives, remote sources, verification, and policy changes are not daemon work.Daemon and warm scans

The generated scaling matrix measures these controls instead of prescribing a fixed thread count. Run make -C benchmarks readme-scaling on the target host. The result binds the binary, detector corpus, exact workload bytes, effective CPU limit, filesystem identity, page-cache policy, raw trials, and process exit status.

What KeyHog emits

OutputUseChapter
Eleven formatstext, json, json-envelope, jsonl, jsonl-envelope, sarif, csv, github-annotations, gitlab-sast, html, junitOutput formats
Baselinesaccept known findings once, then fail only on new secrets; entries match the detector and credential value, never the pathFail only on new secrets
Exit codesstable codes for clean, findings, and error so scripts branch reliablyExit codes

How KeyHog protects the secrets it reads

A scanner holds credentials in memory by design, so KeyHog hardens the process that does it.

PropertyWhat it meansChapter
Local defaultlocal filesystem, Git, stdin, archive, decoding, and detector work do not send findings or telemetryHardening and data handling
In-process scan hardeningLinux and macOS in-process scans attempt core-dump and debugger-attachment protections before reading inputHardening and data handling
Linux lockdown mode--lockdown fails closed unless memory locking and dump protections apply, and it refuses network verification and plaintext outputHardening and data handling
Credential buffer zeroizationthe report credential buffer is zeroized on drop; reports redact unless --show-secrets is explicitHardening and data handling
Authenticated execution packskeyhog install compiles, signs, and verifies the execution-pack generation it publishes, and a scan refuses artifacts whose identity or verification key does not matchInstall

Every subcommand

CommandPurpose
scanscan any source and report findings (--verify adds live credential checks)
scan-systemaudit eligible local mounted filesystems and discovered Git histories under one --space ceiling; --include-network opts into network mounts (guide)
watchcontinuously scan one or more directories as files change
diffdiff two baselines or artifacts: NEW / REMOVED / UNCHANGED
explainshow a detector’s spec, regex, severity, and rotation guide
detectorslist and inspect the embedded detector corpus
configprint the resolved scan configuration without scanning
hookinstall or remove the git pre-commit hook
daemonstart, stop, or query the warm-scan daemon (Unix)
calibrateshow or update per-detector Bayesian confidence calibration
calibrate-autorouteprime autoroute across every policy preset and workload bucket
backendinspect hardware, routing heuristics, and autoroute evidence
bloom-diagnosticmeasure the production Bloom rejection gate and prove enabled-versus-bypassed finding parity
doctorhealth-check the install: host, PATH, corpus, scan and GPU self-test
installcompile, authenticate, calibrate, and install execution packs for this host
triageimport redacted findings into scoped suppression and pattern feedback
guardmanage the perpetual repository and filesystem guard
uninstallremove the binary (dry run unless --yes)
completionemit shell completions (bash, zsh, fish, powershell, elvish)

The full flag surface for every command is in the CLI reference.

Update or repair with cargo install --locked --force keyhog, then run keyhog doctor to verify the replacement.