performance improvements and rule improvements

This commit is contained in:
Mick Grove 2026-04-22 23:39:19 -07:00
commit 7ee1fd5163
26 changed files with 370 additions and 86 deletions

4
.gitignore vendored
View file

@ -6,7 +6,7 @@
*.profile.json
*.json
!webserver/static/sample-report.json
!docs/access-map-viewer/sample-report.json
!docs/report-viewer/sample-report.json
!testdata/parsers/context_verifier_golden.json
!testdata/parsers/scan_findings_baseline.json
!testdata/parsers/tree_sitter_capture_baseline.json
@ -21,7 +21,7 @@ logs/*
*.html
!testdata/html_vulnerable.html
!testdata/html_embedded_vulnerable.html
!docs/access-map-viewer/index.html
!docs/report-viewer/index.html
!docs-site/overrides/*.html
*.dot
fuzz/*

View file

@ -3,8 +3,10 @@
All notable changes to this project will be documented in this file.
## [v1.97.0]
- Fixed the HTML access-map viewer dark mode so charts redraw correctly on theme changes and follow the system color scheme until manually overridden.
- Fixed the HTML report viewer dark mode so charts redraw correctly on theme changes and follow the system color scheme until manually overridden.
- Fixed [#344](https://github.com/mongodb/kingfisher/issues/344): baseline fingerprints no longer have to be hexadecimal. The fingerprint value emitted by scan output (JSON, JSONL, pretty, SARIF) can now be copied directly into a baseline file and will match on the next scan. `--manage-baseline` now writes fingerprints in decimal to match scan output, and legacy 16-char hex (and `0x`-prefixed hex) entries continue to be accepted, so existing baseline files keep working unchanged.
- Expanded the bundled ruleset to **938 rules** (817 standalone detectors + 121 dependent rules), with **484 standalone detectors** now including live HTTP / service-specific validation.
- Documentation: expanded coverage of the **Report Viewer & Triager** across `README.md`, `docs/USAGE.md`, and the docs site (`docs-site/docs/features/report-viewer.md`, `docs-site/docs/usage/basic-scanning.md`). The same viewer is available locally via `kingfisher view <report.json>` and as a hosted static upload-based page at [https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/). Both forms import Kingfisher, Gitleaks, and TruffleHog JSON/JSONL for cross-tool triage with fingerprint-based deduplication and blast-radius rendering.
## [v1.96.0]
- Added archive extraction for three Korean formats: HWPX (Hancom OWPML ZIP container), HWP (Hancom 5.x OLE2/CFBF binary — streams decoded via raw DEFLATE / zlib fallbacks), and EGG (ALZip; registered for enumeration and scanned as raw bytes since no open-source extractor exists).

View file

@ -7,7 +7,7 @@
<img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License" style="height: 24px;" />
</a>
<a href="https://github.com/mongodb/kingfisher">
<img src="https://img.shields.io/badge/Detection%20Rules-934-2ea043.svg" alt="Detection Rules" style="height: 24px;" />
<img src="https://img.shields.io/badge/Detection%20Rules-938-2ea043.svg" alt="Detection Rules" style="height: 24px;" />
</a>
<br>
<a href="https://github.com/mongodb/kingfisher/pkgs/container/kingfisher">
@ -17,7 +17,9 @@
Kingfisher is an open source secret scanner and **live secret validation** tool built in Rust.
It combines Intel's SIMD-accelerated regex engine (Hyperscan) with language-aware parsing to achieve high accuracy at massive scale, and **ships with 934 built-in rules** to detect, **validate**, and triage leaked API keys, tokens, and credentials before they ever reach production.
It combines Intel's SIMD-accelerated regex engine (Hyperscan) with language-aware parsing to achieve high accuracy at massive scale, and **ships with 938 built-in rules** (484 with live validation) to detect, **validate**, and triage leaked API keys, tokens, and credentials before they ever reach production.
Kingfisher also ships a **browser-based report viewer** that visualizes and triages findings from Kingfisher **and** from Gitleaks and TruffleHog JSON reports — so you can import scans from other tools and triage them in the same UI. A [hosted, upload-based copy of the viewer](https://mongodb.github.io/kingfisher/report-viewer/) is published on the Kingfisher docs site.
Designed for offensive security engineers and blue-team defenders alike, Kingfisher helps you scan repositories, cloud storage, chat, docs, and CI pipelines to find and verify exposed secrets quickly.
@ -49,19 +51,19 @@ Kingfisher is a high-performance, open source secret detection tool for source c
</div>
### Performance, Accuracy, and 934 Rules
### Performance, Accuracy, and 938 Rules
- **Performance**: multithreaded, Hyperscanpowered scanning built for huge codebases
- **Extensible rules**: 934 built-in rules plus YAML-defined custom rules ([docs/RULES.md](/docs/RULES.md))
- **Extensible rules**: 938 built-in rules (484 with live validation) plus YAML-defined custom rules ([docs/RULES.md](/docs/RULES.md))
- **Validate & Revoke**: live validation of discovered secrets, plus direct revocation for supported platforms (GitHub, GitLab, Slack, AWS, GCP, and more) ([docs/USAGE.md](/docs/USAGE.md))
- **Revocation support matrix**: current built-in revocation coverage across providers and rule IDs ([docs/REVOCATION_PROVIDERS.md](/docs/REVOCATION_PROVIDERS.md))
- **Blast Radius Mapping**: instantly map leaked keys to their effective cloud identities and exposed resources with `--access-map`. Supports 39 providers (see table below).
- **Blast Radius Mapping**: instantly map leaked keys to their effective cloud identities and exposed resources with `--access-map`. Supports 42 providers (see table below).
- **Broad AI SaaS coverage**: finds and validates tokens for OpenAI, Anthropic, Google Gemini, Cohere, AWS Bedrock, Voyage AI, Mistral, Stability AI, Replicate, xAI (Grok), Ollama, Langchain, Perplexity, Weights & Biases, Cerebras, Friendli, Fireworks.ai, NVIDIA NIM, Together.ai, Zhipu, and many more
- **Compressed Files**: Supports extracting and scanning compressed files for secrets, including `tar.gz`/`bz2`/`xz`, ZIP-family containers (`zip`, `jar`, `docx`, `xlsx`, `pptx`, `odt`, `epub`, `hwpx`, and more), `asar`, HWP (Hancom OLE2/CFBF binary with DEFLATE/zlib stream decoding), and EGG (ALZip; raw-byte scanning)
- **SQLite Database Scanning**: Automatically extracts and scans SQLite database contents for secrets stored in table rows
- **Python Bytecode (.pyc) Scanning**: Extracts and scans string constants from compiled Python (`.pyc`, `.pyo`) files
- **Baseline management**: generate and track baselines to suppress known secrets ([docs/BASELINE.md](/docs/BASELINE.md))
- **Checksum-aware detection**: verifies tokens with built-in checksums (e.g., GitHub, Confluent, Zuplo) — no API calls required
- **Built-in Report Viewer**: Visualize and triage findings locally with `kingfisher view ./report-file.json` (supports multiple files, directories, and imported Gitleaks/TruffleHog JSON reports)
- **Report Viewer (local + hosted)**: Visualize and triage Kingfisher, **Gitleaks, and TruffleHog** JSON output locally with `kingfisher view ./report.json` or online with the [hosted viewer](https://mongodb.github.io/kingfisher/report-viewer/). Multiple files, directories, and imported third-party reports are merged and deduplicated. See [docs/USAGE.md](/docs/USAGE.md#report-viewer-local-and-hosted).
- **Audit reporting**: Generate compliance-oriented HTML reports with scan metadata and validation ordering
- **Library crates**: Embed Kingfisher's scanning engine in your own Rust applications ([docs/LIBRARY.md](docs/LIBRARY.md))
@ -80,8 +82,31 @@ kingfisher scan /path/to/scan --view-report
NOTE: Replay has been slowed down for demo
![Kingfisher secret scanning demo](docs/kingfisher-usage-01.gif)
## Report Viewer Demo
Explore Kingfisher's built-in report viewer and its `--access-map`, which maps the blast radius of discovered credentials across 39 supported providers. The viewer also imports Gitleaks JSON and TruffleHog JSON/JSONL for local triage.
## Report Viewer (local and hosted)
Kingfisher ships a browser-based **report viewer and triager** for three formats:
- Kingfisher JSON / JSONL (with full `access_map` blast-radius data when present)
- **Gitleaks** JSON
- **TruffleHog** JSON / JSONL (verified findings are surfaced as active credentials)
There are two ways to use it:
1. **Locally via the CLI**`kingfisher view ./report.json` (bundled into every Kingfisher binary; no external services)
2. **Hosted** — [https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/) — a static, client-side upload-based copy of the same viewer. Drag in Kingfisher, Gitleaks, or TruffleHog reports and triage in your browser; nothing is uploaded to a server.
### Why use a visual viewer / triager?
Raw JSON from Kingfisher, Gitleaks, or TruffleHog is great for machines, but awful for humans making decisions on which findings are real and which need to be rotated first. The viewer lets a security engineer:
- **Skim hundreds of findings at a glance**, grouped by detector, file, repository, and validation status instead of one line per finding in a terminal.
- **Triage across multiple tools in one place** — import a Gitleaks report plus a TruffleHog report plus a Kingfisher scan of the same repo and look at them side-by-side with dedup, instead of eyeballing three different JSON schemas.
- **Prioritize real, validated secrets** — validated Kingfisher findings and TruffleHog-verified findings float to the top so you act on live credentials first.
- **Drop duplicates** — repeated imports and overlapping scans are deduplicated by fingerprint/secret identity so you don't open the same key five times.
- **See blast radius** — for Kingfisher reports generated with `--access-map`, the viewer renders the identity, permissions, and resources a leaked credential can reach, so you can tell a dev token apart from a production admin key.
- **Export triage decisions** — filter down to what matters and export a cleaned-up subset for a ticket, a rotation runbook, or an audit reviewer.
Tools like Gitleaks and TruffleHog surface candidates; Kingfisher's viewer helps you decide which ones to act on — and it works with their output too.
Note: when you pass `--view-report`, Kingfisher starts a web server on port `7890` (default) and opens it in your default browser. By default it binds to `127.0.0.1` for security. You'll see this near the end of the scan output, and **Kingfisher will keep running** until you stop it.
@ -104,6 +129,7 @@ kingfisher scan /path/to/scan --access-map --view-report
- [What Is Kingfisher?](#what-is-kingfisher)
- [Key Features](#key-features)
- [Report Viewer (local and hosted)](#report-viewer-local-and-hosted)
- [Compliance and Audit-Ready Scans](#compliance-and-audit-ready-scans)
- [Benchmark Results](#benchmark-results)
- [Getting Started](#getting-started)
@ -156,7 +182,26 @@ kingfisher scan /path/to/code
kingfisher scan /path/to/code --view-report
```
You can also open existing Kingfisher, Gitleaks, or TruffleHog JSON reports with `kingfisher view <report.json>`. For a shareable upload-based experience, the docs site also hosts the report viewer as a static page.
You can also open existing Kingfisher, Gitleaks, or TruffleHog JSON reports with `kingfisher view <report.json>`:
```bash
# Kingfisher report
kingfisher view kingfisher.json
# Import a Gitleaks JSON report
kingfisher view gitleaks-report.json
# Import a TruffleHog JSON or JSONL report
kingfisher view trufflehog-report.jsonl
# Combine multiple reports (deduplicated by fingerprint / secret identity)
kingfisher view kingfisher.json gitleaks.json trufflehog.jsonl
# Or load every JSON/JSONL report in a directory
kingfisher view ./reports/
```
For a shareable, upload-based experience, the docs site also hosts the same viewer as a static page: **[https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/)**. Everything runs client-side in the browser — no reports leave your machine.
### 4: Show only validated (live) secrets
@ -347,7 +392,7 @@ gh attestation verify kingfisher-linux-x64.tgz --repo mongodb/kingfisher
# Detection Rules
Kingfisher ships with [934 built-in rules](crates/kingfisher-rules/data/rules/) covering cloud keys, AI tokens, CI/CD secrets, database credentials, and SaaS API keys. Below is an overview — see the full list in [crates/kingfisher-rules/data/rules/](crates/kingfisher-rules/data/rules/):
Kingfisher ships with [938 built-in rules](crates/kingfisher-rules/data/rules/) covering cloud keys, AI tokens, CI/CD secrets, database credentials, and SaaS API keys. Below is an overview — see the full list in [crates/kingfisher-rules/data/rules/](crates/kingfisher-rules/data/rules/):
| Category | What we catch |
|----------|---------------|
@ -364,7 +409,7 @@ Kingfisher ships with [934 built-in rules](crates/kingfisher-rules/data/rules/)
## Write Custom Rules
Kingfisher ships with 605 built-in rules with HTTP and service-specific validation checks (AWS, Azure, GCP, etc.) to confirm if a detected string is a live credential.
Kingfisher ships with 484 built-in rules that include HTTP and service-specific validation checks (AWS, Azure, GCP, etc.) to confirm if a detected string is a live credential.
However, you may want to add your own custom rules, or modify a detection to better suit your needs / environment.
@ -730,7 +775,7 @@ kingfisher scan /tmp/repo --branch feature-1 \
|----------|-------------|
| [INSTALLATION.md](docs/INSTALLATION.md) | Complete installation guide including pre-commit hooks setup for git, pre-commit framework, and Husky |
| [INTEGRATIONS.md](docs/INTEGRATIONS.md) | Platform-specific scanning guide (GitHub, GitLab, AWS S3, Docker, Jira, Confluence, Slack, etc.) |
| [ACCESS_MAP.md](docs/ACCESS_MAP.md) | Access map: supported tokens and credential formats (39 providers including AWS, GCP, Azure, Stripe, Jira, and more) |
| [ACCESS_MAP.md](docs/ACCESS_MAP.md) | Access map: supported tokens and credential formats (42 providers including AWS, GCP, Azure, Alibaba Cloud, Stripe, Jira, monday.com, Asana, and more) |
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | High-level Mermaid architecture diagram of the CLI, scanner pipeline, validation, access map, and outputs |
| [DEPLOYMENT.md](docs/DEPLOYMENT.md) | Deployment models for self-serve CLI use, CI/pre-commit enforcement, centralized scanning, and embedded library integrations |
| [ADVANCED.md](docs/ADVANCED.md) | Advanced features: baselines, confidence levels, validation tuning, CI scanning, and more |

View file

@ -8,7 +8,10 @@ description: "Kingfisher release history: new features, rules, bug fixes, and im
All notable changes to this project will be documented in this file.
## [v1.97.0]
- Fixed the HTML access-map viewer dark mode so charts redraw correctly on theme changes and follow the system color scheme until manually overridden.
- Fixed the HTML report viewer dark mode so charts redraw correctly on theme changes and follow the system color scheme until manually overridden.
- Fixed [#344](https://github.com/mongodb/kingfisher/issues/344): baseline fingerprints no longer have to be hexadecimal. The fingerprint value emitted by scan output (JSON, JSONL, pretty, SARIF) can now be copied directly into a baseline file and will match on the next scan. `--manage-baseline` now writes fingerprints in decimal to match scan output, and legacy 16-char hex (and `0x`-prefixed hex) entries continue to be accepted, so existing baseline files keep working unchanged.
- Expanded the bundled ruleset to **938 rules** (817 standalone detectors + 121 dependent rules), with **484 standalone detectors** now including live HTTP / service-specific validation.
- Documentation: expanded coverage of the **Report Viewer & Triager** across `README.md`, `docs/USAGE.md`, and the docs site (`docs-site/docs/features/report-viewer.md`, `docs-site/docs/usage/basic-scanning.md`). The same viewer is available locally via `kingfisher view <report.json>` and as a hosted static upload-based page at [https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/). Both forms import Kingfisher, Gitleaks, and TruffleHog JSON/JSONL for cross-tool triage with fingerprint-based deduplication and blast-radius rendering.
## [v1.96.0]
- Added archive extraction for three Korean formats: HWPX (Hancom OWPML ZIP container), HWP (Hancom 5.x OLE2/CFBF binary — streams decoded via raw DEFLATE / zlib fallbacks), and EGG (ALZip; registered for enumeration and scanned as raw bytes since no open-source extractor exists).
@ -24,6 +27,8 @@ All notable changes to this project will be documented in this file.
- Added 61 new detection rules across 46 providers: Axiom (API token + PAT), Trigger.dev (secret key + PAT), Dub.co, Svix webhook signing secret, Liveblocks, Inngest (signing key + event key), Seam, Courier, Cal.com, Arcjet, WarpStream, Mem0, Mintlify, Pirsch, Tinybird, Tolgee (project key + PAT), Ory (API key + session + OAuth2 tokens), Xendit, Xata, Crossmint (server + client keys), DeepL (Free + Pro), Flagsmith, E2B, Infisical, WooCommerce (consumer key + secret), Nightfall AI, Ramp (client ID + secret), Hex.pm (personal + workspace tokens), Convex deploy key, MiniMax, Mappedin (key + secret), Pollinations (secret + publishable), Fal.ai, Aikido, Hack Club, GuardSquare, Browser Use, Composio, Gamma, Hex.tech, Mastra, redirect.pizza, Upstash, and WorkOS. Also added new prefixed-token rules for Netlify (`nfp_`), Cloudflare (`cfut_`), and Supabase (`sb_publishable_`). Added live HTTP validation for 30 of these rules.
- Added 32 new detection rules across 25 providers: Ghost CMS (admin + content keys), UpCloud (`ucat_`), Voiceflow (`VF.DM.`/`VF.WS.`), Robinhood Crypto (`rh-api-`), ClickUp (`pk_`), Unleash (client/admin + personal tokens), ConfigCat (standard + extended SDK keys), SaladCloud (`salad_cloud_`), Tigris (`tid_`/`tsec_`), Portainer (`ptr_`), Permit.io (`permit_key_`), Builder.io (`bpk-`), LiveKit (API key + secret), Close CRM (`api_`), Hetzner Cloud, Censys (API ID + secret), Wistia, PandaDoc, Pinata (key + secret), ZeroTier, Detectify, ChartMogul, Moralis, ButterCMS, and Loops. Includes HTTP validation for 19 of these rules.
- Removed 17 direct dependencies from the root crate by dropping unused deps (`p256`, `ed25519-dalek`, `jsonwebtoken`, `gitlab`, `lazy_static`, `base32`, `pem`, `byteorder`, `reqwest-middleware`, `sha1`, `time`, `ring`, `num_cpus`, `strum_macros`), replacing `once_cell` with `std::sync::{LazyLock, OnceLock}`, and using `std::thread::available_parallelism()` in place of `num_cpus`. Salt generation now uses `rand` instead of `ring`, and all `strum_macros::Display` imports are consolidated under `strum::Display`.
- Migrated the workspace to Rust Edition 2024 (MSRV 1.94) and refactored nested `if let` chains in core/scanner hot paths (content-type detection, origin parsing, GCP/Harness/Azure DevOps access maps, GitHub/GitLab repo parsing, dependent-variable pairing) to use stable let-chains for flatter control flow.
- Tightened lint hygiene by converting stable `#[allow(...)]` attributes to `#[expect(...)]` across the workspace (e.g. `dead_code`, `clippy::too_many_arguments`, `clippy::large_enum_variant`) so the compiler surfaces stale suppressions as warnings.
## [v1.95.0]
- Fixed scan performance regression: the rule profiler was unconditionally active even without `--rule-stats`, causing RwLock contention across scan threads. Scans are now ~15% faster than v1.94.0.

View file

@ -485,11 +485,11 @@ kingfisher access-map microsoftteams ./teams.webhook --json-out teams.access-map
### monday.com (`monday`)
- **Credential**: a single monday.com API token (read from a file for `kingfisher access-map monday <FILE>`).
- **Token types supported**: personal or account-level API tokens accepted by the monday.com GraphQL API with the `Authorization: <TOKEN>` header (monday.com's native scheme; the JWT-style token is sent verbatim, without the `Bearer` prefix).
- **Token types supported**: personal or account-level API tokens accepted by the monday.com GraphQL API with the `Authorization: <TOKEN>` header (the JWT-style token is sent verbatim, without the `Bearer` prefix — this matches monday.com's native scheme).
Kingfisher performs read-only enumeration against `https://api.monday.com/v2`:
- `me { id, name, email, is_admin, is_guest, is_view_only, created_at, last_activity, account { id, name, slug, plan { tier } }, teams { name } }` for caller identity, role, and account metadata
- `me { ..., account { id, name, slug, plan { tier } }, teams { name } }` for caller identity, role, and account metadata
- `workspaces(limit: 100) { id, name, kind, state }` for workspace-level resource exposure
- `boards(limit: 50) { id, name, board_kind, state }` for board-level resource exposure

View file

@ -43,7 +43,7 @@ finding-bytes + origin + start-offset + end-offset -> XXH3-64 -> finding_fingerp
```
This fingerprint is what you see reported in the finding output.
This fingerprint is what you see reported in the finding output. It is rendered as an unsigned decimal `u64` in every output format (pretty, JSON, JSONL, and SARIF) and is the same value written into [baseline files](../usage/baseline.md), so a fingerprint copied from a report can be pasted directly into a baseline.
---

View file

@ -1,40 +1,107 @@
---
title: "Hosted Report Viewer"
description: "Open the Kingfisher report viewer from the docs site and upload Kingfisher, Gitleaks, or TruffleHog JSON reports directly in your browser."
title: "Report Viewer & Triager (Kingfisher, Gitleaks, TruffleHog)"
description: "Triage Kingfisher, Gitleaks, and TruffleHog JSON findings in one browser-based viewer. Use the bundled local viewer via `kingfisher view` or the hosted static viewer on GitHub Pages."
---
Kingfisher ships a browser-based report viewer that can also be hosted from the documentation site as a static page.
# Report Viewer & Triager
[Open the hosted report viewer](../access-map-viewer/index.html)
Kingfisher ships a browser-based **report viewer and triager** for three formats:
## What it supports
- **Kingfisher** JSON / JSONL — with full `access_map` blast-radius data when available
- **Gitleaks** JSON
- **TruffleHog** JSON / JSONL — verified findings are surfaced as active credentials
- Upload local `Kingfisher` JSON and JSONL reports
- Upload local `Gitleaks` JSON reports
- Upload local `TruffleHog` JSON and JSONL reports
- Merge multiple uploaded reports in one browser session
- Explore findings, detector breakdowns, and access-map data when present
The same UI is available two ways:
## Hosted vs local viewer
- **Locally**, bundled into every Kingfisher binary: `kingfisher view ./report.json`
- **Hosted**, as a static upload-based copy on GitHub Pages: **[Open the hosted report viewer](../report-viewer/index.html)** ([https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/))
The hosted docs-site version is upload-based. It does not use the CLI-only local `/report` endpoint that powers `kingfisher view`.
Both render reports entirely client-side. Nothing about the uploaded report leaves the browser.
Use the hosted version when you want a hosted static viewer on GitHub Pages.
## Why a visual viewer/triager matters
Use the local CLI viewer when you want Kingfisher to open a report directly from disk:
Gitleaks and TruffleHog are great at emitting candidate matches; Kingfisher goes further by live-validating and mapping blast radius. But all three produce JSON, and raw JSON is not how a human decides which finding to rotate first. The viewer turns that output into a triage workflow:
- **Skim at a glance** — findings are grouped by detector, rule, file, and repository with counts and validation state, instead of one JSON object per line in a terminal.
- **Cross-tool triage in one place** — import a Gitleaks scan, a TruffleHog scan, and a Kingfisher scan of the same codebase and look at them side-by-side with deduplication, rather than reconciling three different schemas by hand.
- **Rotate real secrets first** — validated Kingfisher findings and TruffleHog-verified findings are surfaced as active credentials; unverified/static matches are marked as not attempted.
- **Dedup automatically** — the same secret appearing across multiple reports, directories, or scan runs collapses to one entry by fingerprint / secret identity.
- **See blast radius** — when a Kingfisher report was generated with `--access-map`, the viewer renders the identity, permissions, and resources the credential can reach, so you can tell apart a dev token from a production admin key.
- **Share and archive** — export filtered subsets for tickets, rotation runbooks, or audit reviewers.
Tools like Gitleaks and TruffleHog surface candidates. Kingfisher's viewer helps you decide which ones matter — and it works with their output, not just its own.
## Using the local viewer via the `kingfisher` CLI
The local viewer is part of the `kingfisher` binary — no separate install, no network calls.
```bash
kingfisher view report.json
# Open a Kingfisher scan report
kingfisher view kingfisher.json
# Import a Gitleaks JSON report
kingfisher view gitleaks-report.json
# Import a TruffleHog JSON or JSONL report
kingfisher view trufflehog-report.jsonl
# Combine multiple reports — deduplicated by fingerprint / secret identity
kingfisher view kingfisher.json gitleaks.json trufflehog.jsonl
# Or load every JSON/JSONL report in a directory (non-recursive)
kingfisher view ./reports/
```
`kingfisher view` starts a tiny local web server on `127.0.0.1:7890` and opens the browser automatically. Use `--port` to pick another port and `--address 0.0.0.0` to expose the viewer from a container or remote host.
You can also chain scanning and viewing in a single step:
```bash
# Scan and open the report in the browser when it finishes
kingfisher scan /path/to/code --view-report
# Same, but bind to all interfaces and a specific port (useful in Docker)
kingfisher scan /path/to/code \
--view-report \
--view-report-address 0.0.0.0 \
--view-report-port 7891
```
## Using the hosted viewer
The docs site publishes a static, upload-based copy of the viewer at:
**[https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/)**
Drag a Kingfisher, Gitleaks, or TruffleHog JSON report into the page (or use the file picker) to triage it in your browser. You can also merge multiple reports in one session by uploading them one after another — duplicates collapse automatically. It's useful when you want to:
- Hand a teammate a link rather than a binary
- Triage a report on a machine that doesn't have Kingfisher installed
- Show a finding with its blast-radius context without shipping the raw JSON around
## Sample data
You can test the hosted page with a bundled sample report:
- [Open sample report JSON](../access-map-viewer/sample-report.json)
- [Open sample report JSON](../report-viewer/sample-report.json)
## Notes
## Local vs hosted — quick comparison
- Everything runs client-side in the browser.
- Imported third-party reports are normalized for viewing and deduplicated by fingerprint logic in the viewer.
- Native-only CLI conveniences such as auto-loading `/report` remain part of the local `kingfisher view` workflow.
| Capability | `kingfisher view` (local) | Hosted viewer |
|---------------------------------------------------------|:-------------------------:|:-------------:|
| Open Kingfisher JSON/JSONL reports | Yes | Yes |
| Import Gitleaks JSON reports | Yes | Yes |
| Import TruffleHog JSON/JSONL reports | Yes | Yes |
| Merge multiple reports with deduplication | Yes | Yes |
| Render `access_map` blast-radius data | Yes | Yes |
| Runs fully client-side (no report leaves your machine) | Yes | Yes |
| Auto-load a report from disk via CLI argument | Yes | — |
| Shareable URL you can send to a teammate | — | Yes |
| Requires Kingfisher installed | Yes | No |
## Caveats for imported Gitleaks / TruffleHog reports
- Imported reports are display-oriented. They do not carry Kingfisher-native `access_map` data or drive `kingfisher validate` / `kingfisher revoke`.
- Fingerprints on imported findings use the importer's normalization, not Kingfisher's native fingerprinting.
- TruffleHog findings marked as verified are shown as active credentials; all other imported findings are treated as not attempted rather than inactive.
- For full validation and blast-radius mapping, re-scan the source with Kingfisher and (when authorized) add `--access-map`.

View file

@ -104,4 +104,5 @@ kingfisher scan /path/to/code --format json --output findings.json
- [Basic Scanning](../usage/basic-scanning.md) — full scanning guide with all options
- [Platform Integrations](../usage/integrations.md) — GitHub, GitLab, S3, Docker, Slack, and more
- [Writing Custom Rules](../rules/overview.md) — create detection rules for your own patterns
- [Access Map](../features/access-map.md) — blast radius mapping for 39 providers
- [Access Map](../features/access-map.md) — blast radius mapping for 42 providers
- [Report Viewer & Triager](../features/report-viewer.md) — local and hosted viewer for Kingfisher, Gitleaks, and TruffleHog JSON reports

View file

@ -2,7 +2,9 @@
title: Kingfisher — Open Source Secret Scanner with Live Validation
description: >-
Kingfisher is an open source secret scanner with live validation, blast radius
mapping, and credential revocation. 934 detection rules. Built in Rust by MongoDB.
mapping, and credential revocation. 938 detection rules (484 with live validation),
plus a browser-based report viewer that also triages Gitleaks and TruffleHog output.
Built in Rust by MongoDB.
template: home.html
hide:
- navigation

View file

@ -268,7 +268,7 @@ flowchart TD
### Loading Builtin Rules
Kingfisher currently ships with 934 built-in rules for common secret types:
Kingfisher currently ships with 938 built-in rules for common secret types:
```rust
use kingfisher_rules::{get_builtin_rules, Confidence};

View file

@ -1,13 +1,13 @@
---
title: "Built-in Rules List"
description: "Complete list of all 934 built-in secret detection rules in Kingfisher. Searchable and filterable by provider, confidence level, and validation support."
description: "Complete list of all 938 built-in secret detection rules in Kingfisher. Searchable and filterable by provider, confidence level, and validation support."
---
# Built-in Rules
Kingfisher ships with **934 detection rules** across **579 providers**
(813 detectors + 121 dependent rules).
Of these, **605** include live validation and **53** support direct revocation.
Kingfisher ships with **938 detection rules** across **580 providers**
(817 detectors + 121 dependent rules).
Of these, **605** include live validation and **57** support direct revocation.
!!! tip "Search"
Use the search box below to filter rules by provider name, rule ID, or confidence level.
@ -2196,6 +2196,14 @@ Of these, **605** include live validation and **53** support direct revocation.
<td></td>
</tr>
<tr>
<td>Dryrunsecurity</td>
<td>DryRun Security API Key</td>
<td><code>kingfisher.dryrunsecurity.1</code></td>
<td>Medium</td>
<td>Yes</td>
<td></td>
</tr>
<tr>
<td>Dub</td>
<td>Dub.co API Key</td>
<td><code>kingfisher.dub.1</code></td>
@ -2424,8 +2432,8 @@ Of these, **605** include live validation and **53** support direct revocation.
<td>Fal.ai API Key</td>
<td><code>kingfisher.falai.1</code></td>
<td>Medium</td>
<td></td>
<td></td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Fastly</td>
@ -2549,13 +2557,21 @@ Of these, **605** include live validation and **53** support direct revocation.
</tr>
<tr>
<td>Flagsmith</td>
<td>Flagsmith Server-Side Environment Key</td>
<td>Flagsmith Organisation API Key</td>
<td><code>kingfisher.flagsmith.1</code></td>
<td>Medium</td>
<td>Yes</td>
<td></td>
</tr>
<tr>
<td>Flagsmith</td>
<td>Flagsmith Environment Key</td>
<td><code>kingfisher.flagsmith.2</code></td>
<td>Medium</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Fleetbase</td>
<td>Fleetbase API Key</td>
<td><code>kingfisher.fleetbase.1</code></td>
@ -2881,7 +2897,7 @@ Of these, **605** include live validation and **53** support direct revocation.
<td><code>kingfisher.github.3</code></td>
<td>Medium</td>
<td>Yes</td>
<td></td>
<td>Yes</td>
</tr>
<tr>
<td>Github</td>
@ -2889,7 +2905,7 @@ Of these, **605** include live validation and **53** support direct revocation.
<td><code>kingfisher.github.4</code></td>
<td>Unknown</td>
<td>Yes</td>
<td></td>
<td>Yes</td>
</tr>
<tr>
<td>Github</td>
@ -2905,7 +2921,7 @@ Of these, **605** include live validation and **53** support direct revocation.
<td><code>kingfisher.github.6</code></td>
<td>Unknown</td>
<td>Yes</td>
<td></td>
<td>Yes</td>
</tr>
<tr>
<td>Github</td>
@ -3320,7 +3336,7 @@ Of these, **605** include live validation and **53** support direct revocation.
<td>hCaptcha Site Verify Secret Key</td>
<td><code>kingfisher.hcaptcha.1</code></td>
<td>Medium</td>
<td>Yes</td>
<td></td>
<td></td>
</tr>
<tr>
@ -6319,7 +6335,7 @@ Of these, **605** include live validation and **53** support direct revocation.
<td>Sshpass</td>
<td>SSH / SCP Password (sshpass)</td>
<td><code>kingfisher.sshpass.1</code></td>
<td>Medium</td>
<td>Low</td>
<td></td>
<td></td>
</tr>
@ -6972,6 +6988,22 @@ Of these, **605** include live validation and **53** support direct revocation.
<td></td>
</tr>
<tr>
<td>Upstash</td>
<td>Upstash Account Email</td>
<td><code>kingfisher.upstash.3</code></td>
<td>Medium</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Upstash</td>
<td>Upstash Management API Key</td>
<td><code>kingfisher.upstash.4</code></td>
<td>Medium</td>
<td>Yes</td>
<td></td>
</tr>
<tr>
<td>Uptimerobot</td>
<td>UptimeRobot API Key</td>
<td><code>kingfisher.uptimerobot.1</code></td>
@ -6984,7 +7016,7 @@ Of these, **605** include live validation and **53** support direct revocation.
<td>URI with Username and Secret</td>
<td><code>kingfisher.uri.1</code></td>
<td>Medium</td>
<td>Yes</td>
<td></td>
<td></td>
</tr>
<tr>
@ -7416,7 +7448,7 @@ Of these, **605** include live validation and **53** support direct revocation.
<td>Zapier Webhook URL</td>
<td><code>kingfisher.zapier.1</code></td>
<td>Medium</td>
<td>Yes</td>
<td></td>
<td></td>
</tr>
<tr>

View file

@ -300,7 +300,7 @@ kingfisher scan ./my-project \
## Custom Rules
Kingfisher currently ships with 934 built-in rules, but you may want to add your own custom rules or modify existing detection to better suit your needs.
Kingfisher currently ships with 938 built-in rules, but you may want to add your own custom rules or modify existing detection to better suit your needs.
First, review [RULES.md](../rules/overview.md) to learn how to create custom Kingfisher rules.

View file

@ -22,21 +22,23 @@ This generates a YAML file named `baseline-file.yml` in the current directory. T
ExactFindings:
matches:
- filepath: ruby_vulnerable.rb/
fingerprint: 056876f00ffd0622
fingerprint: '389162583612032034'
linenum: 52
lastupdated: Mon, 14 Jul 2025 10:17:56 -0700
- filepath: ruby_vulnerable.rb/
fingerprint: ce41d19b83b2b1b0
fingerprint: '14862156687550263216'
linenum: 53
lastupdated: Mon, 14 Jul 2025 10:17:56 -0700
- filepath: ruby_vulnerable.rb/
fingerprint: e8644d91fa6654f5
fingerprint: '16736108862611731189'
linenum: 40
lastupdated: Mon, 14 Jul 2025 10:17:56 -0700
```
`fingerprint` reuses Kingfisher's 64-bit *finding fingerprint* algorithm with offsets set to zero. It hashes the secret value together with the normalized filepath, so moving a secret around does not create a new entry.
Fingerprints in the baseline are written as decimal `u64` values — identical to the fingerprint shown in scan output (JSON, JSONL, pretty, SARIF), so you can copy a fingerprint directly from a report into this file. For backward compatibility the baseline also accepts the legacy 16-character zero-padded hex form (e.g. `056876f00ffd0622`) and explicit `0x`-prefixed hex, so baselines produced by older releases continue to work unchanged.
Running another scan with `--manage-baseline` rewrites the file so it only contains findings that still exist in the repository. Use the same YAML file with the `--baseline-file` option on future scans to hide all recorded findings:
```bash

View file

@ -133,11 +133,51 @@ kingfisher view ./reports/
The browser-based viewer also supports loading multiple files via drag-and-drop or the file picker, with the same fingerprint-based deduplication.
The local viewer also accepts Gitleaks JSON and TruffleHog JSON/JSONL as imported report formats. Imported findings are normalized into the viewer for triage, filtering, and export, which makes the viewer useful as a shared local workbench even when the original scan came from another tool.
#### Report viewer (local and hosted) {#report-viewer-local-and-hosted}
A static upload-based copy of the viewer can also be hosted from the docs site for GitHub Pages deployments. The hosted version keeps the same client-side report browsing flow, but it does not use the local CLI `/report` endpoint that powers `kingfisher view`.
The same viewer that powers `kingfisher view` and `--view-report` also accepts **Gitleaks JSON** and **TruffleHog JSON/JSONL** as imported report formats, and is published in two forms:
Imported reports are display-oriented. They do not include Kingfisher-native `access_map` data, `validate` / `revoke` commands, or the same fingerprint semantics as a native Kingfisher report. TruffleHog findings marked as verified are shown as active credentials; all other imported findings are treated as not attempted rather than inactive. For full validation context and blast-radius mapping, re-scan with Kingfisher and add `--access-map` when appropriate.
1. **Local CLI viewer** — bundled into every Kingfisher binary. No network calls, no install step beyond Kingfisher itself.
```bash
# Open a Kingfisher scan
kingfisher view kingfisher.json
# Open a Gitleaks report
kingfisher view gitleaks-report.json
# Open a TruffleHog report
kingfisher view trufflehog-report.jsonl
# Merge multiple reports (deduplicated by fingerprint / secret identity)
kingfisher view kingfisher.json gitleaks.json trufflehog.jsonl
# Or drop a directory of reports in and the viewer will ingest the JSON/JSONL files
kingfisher view ./reports/
```
`kingfisher view` starts a tiny local web server (default `127.0.0.1:7890`) and opens the report automatically in your browser. Use `--address 0.0.0.0` to expose the viewer from a container or remote host, and `--port <PORT>` if `7890` is busy.
2. **Hosted viewer** — [https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/)
A static, upload-based copy of the same UI published on GitHub Pages. Drag a Kingfisher, Gitleaks, or TruffleHog report into the page and triage it in your browser. Everything runs client-side — no reports leave your machine. Useful when you want to share a link rather than a binary, or triage a report on a machine that doesn't have Kingfisher installed.
#### Why use a visual viewer / triager for Gitleaks, TruffleHog, and Kingfisher output?
Raw JSON output from Kingfisher, Gitleaks, and TruffleHog is excellent input for CI, ticketing systems, and SIEMs, but it's not how a human makes rotation and risk decisions. The viewer gives security engineers:
- **A skimmable overview** — findings are grouped by detector, rule, file, and repository, with counts and validation state, instead of one JSON object per line.
- **Cross-tool triage in one UI** — import a Gitleaks scan, a TruffleHog scan, and a Kingfisher scan of the same codebase into the same session and look at them side-by-side with deduplication, instead of reconciling three different schemas.
- **Clear "this is live" signals** — validated Kingfisher findings and TruffleHog-verified findings are surfaced as active credentials so you rotate real keys first; unverified/static matches are marked as not attempted rather than active or inactive.
- **Fingerprint-aware deduplication** — the same secret appearing across multiple reports, directories, or scan runs collapses to one entry.
- **Blast-radius context** — when a Kingfisher report was produced with `--access-map`, the viewer renders the identity, permissions, and resources the leaked credential actually reaches, so you can tell apart a test token from a production admin key.
- **A shareable, offline-friendly workbench** — runs locally via `kingfisher view` or via the hosted static page; nothing about the report is exfiltrated.
Gitleaks and TruffleHog are great at surfacing candidate matches. Kingfisher's viewer turns their candidates (and its own) into a triageable workflow without changing the scanner you already use.
#### Caveats for imported reports
Imported Gitleaks and TruffleHog reports are display-oriented. They do not carry Kingfisher-native `access_map` data, they cannot be driven by `kingfisher validate` / `revoke`, and their fingerprints use the importer's normalization rather than Kingfisher's native fingerprinting. TruffleHog findings marked as verified are shown as active credentials; all other imported findings are treated as not attempted rather than inactive. For full validation context and blast-radius mapping, re-scan with Kingfisher and add `--access-map` when appropriate.
### Pipe any text directly into Kingfisher by passing `-`

View file

@ -1,8 +1,10 @@
site_name: Kingfisher
site_url: https://mongodb.github.io/kingfisher
site_description: >-
Open source secret scanner with live validation. 921 detection rules,
blast radius mapping, and credential revocation. Built in Rust by MongoDB.
Open source secret scanner with live validation. 938 detection rules,
blast radius mapping, credential revocation, and a browser-based
report viewer that also imports Gitleaks and TruffleHog output.
Built in Rust by MongoDB.
site_author: MongoDB
repo_url: https://github.com/mongodb/kingfisher
repo_name: mongodb/kingfisher
@ -96,6 +98,7 @@ nav:
- Rust Library Crates: reference/library.md
- Python Bindings: reference/python-bindings.md
- Benchmarks & Comparison: reference/comparison.md
- Report Viewer: https://mongodb.github.io/kingfisher/report-viewer/
- Changelog: changelog.md
extra:

View file

@ -13,8 +13,8 @@ import shutil
REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
DOCS_SRC = os.path.join(REPO_ROOT, "docs")
DOCS_DST = os.path.join(REPO_ROOT, "docs-site", "docs")
VIEWER_SRC_DIR = os.path.join(DOCS_SRC, "access-map-viewer")
VIEWER_DST_DIR = os.path.join(DOCS_DST, "access-map-viewer")
VIEWER_SRC_DIR = os.path.join(DOCS_SRC, "report-viewer")
VIEWER_DST_DIR = os.path.join(DOCS_DST, "report-viewer")
VIEWER_CLI_BOOTSTRAP = " loadCliReport();\n"
VIEWER_STATIC_BOOTSTRAP = (
" // Static docs-site build: skip the CLI-only /report bootstrap.\n"
@ -223,18 +223,18 @@ def transform_viewer_for_docs_site(content: str) -> str:
"""Disable the CLI-only embedded report bootstrap in the hosted viewer."""
if VIEWER_CLI_BOOTSTRAP not in content:
raise RuntimeError(
"Could not find CLI bootstrap marker in access-map viewer"
"Could not find CLI bootstrap marker in report viewer"
)
return content.replace(VIEWER_CLI_BOOTSTRAP, VIEWER_STATIC_BOOTSTRAP, 1)
def copy_access_map_viewer():
"""Publish a static-hosted copy of the access-map viewer into docs-site/docs."""
def copy_report_viewer():
"""Publish a static-hosted copy of the report viewer into docs-site/docs."""
src_index = os.path.join(VIEWER_SRC_DIR, "index.html")
dst_index = os.path.join(VIEWER_DST_DIR, "index.html")
if not os.path.exists(src_index):
print(
" WARNING: docs/access-map-viewer/index.html not found, "
" WARNING: docs/report-viewer/index.html not found, "
"skipping viewer publish"
)
return
@ -246,15 +246,15 @@ def copy_access_map_viewer():
transformed = transform_viewer_for_docs_site(content)
with open(dst_index, "w", encoding="utf-8") as f:
f.write(transformed)
print(" access-map-viewer/index.html -> access-map-viewer/index.html")
print(" report-viewer/index.html -> report-viewer/index.html")
sample_src = os.path.join(VIEWER_SRC_DIR, "sample-report.json")
sample_dst = os.path.join(VIEWER_DST_DIR, "sample-report.json")
if os.path.exists(sample_src):
shutil.copy2(sample_src, sample_dst)
print(
" access-map-viewer/sample-report.json -> "
"access-map-viewer/sample-report.json"
" report-viewer/sample-report.json -> "
"report-viewer/sample-report.json"
)
@ -269,7 +269,7 @@ def main():
print(f" WARNING: {src_name} not found, skipping")
copy_changelog()
copy_access_map_viewer()
copy_report_viewer()
print("Done.")

View file

@ -297,7 +297,7 @@ kingfisher scan ./my-project \
## Custom Rules
Kingfisher currently ships with 934 built-in rules, but you may want to add your own custom rules or modify existing detection to better suit your needs.
Kingfisher currently ships with 938 built-in rules, but you may want to add your own custom rules or modify existing detection to better suit your needs.
First, review [RULES.md](RULES.md) to learn how to create custom Kingfisher rules.

View file

@ -265,7 +265,7 @@ flowchart TD
### Loading Builtin Rules
Kingfisher currently ships with 934 built-in rules for common secret types:
Kingfisher currently ships with 938 built-in rules for common secret types:
```rust
use kingfisher_rules::{get_builtin_rules, Confidence};

View file

@ -128,11 +128,51 @@ kingfisher view ./reports/
The browser-based viewer also supports loading multiple files via drag-and-drop or the file picker, with the same fingerprint-based deduplication.
The local viewer also accepts Gitleaks JSON and TruffleHog JSON/JSONL as imported report formats. Imported findings are normalized into the viewer for triage, filtering, and export, which makes the viewer useful as a shared local workbench even when the original scan came from another tool.
#### Report viewer (local and hosted) {#report-viewer-local-and-hosted}
A static upload-based copy of the viewer can also be hosted from the docs site for GitHub Pages deployments. The hosted version keeps the same client-side report browsing flow, but it does not use the local CLI `/report` endpoint that powers `kingfisher view`.
The same viewer that powers `kingfisher view` and `--view-report` also accepts **Gitleaks JSON** and **TruffleHog JSON/JSONL** as imported report formats, and is published in two forms:
Imported reports are display-oriented. They do not include Kingfisher-native `access_map` data, `validate` / `revoke` commands, or the same fingerprint semantics as a native Kingfisher report. TruffleHog findings marked as verified are shown as active credentials; all other imported findings are treated as not attempted rather than inactive. For full validation context and blast-radius mapping, re-scan with Kingfisher and add `--access-map` when appropriate.
1. **Local CLI viewer** — bundled into every Kingfisher binary. No network calls, no install step beyond Kingfisher itself.
```bash
# Open a Kingfisher scan
kingfisher view kingfisher.json
# Open a Gitleaks report
kingfisher view gitleaks-report.json
# Open a TruffleHog report
kingfisher view trufflehog-report.jsonl
# Merge multiple reports (deduplicated by fingerprint / secret identity)
kingfisher view kingfisher.json gitleaks.json trufflehog.jsonl
# Or drop a directory of reports in and the viewer will ingest the JSON/JSONL files
kingfisher view ./reports/
```
`kingfisher view` starts a tiny local web server (default `127.0.0.1:7890`) and opens the report automatically in your browser. Use `--address 0.0.0.0` to expose the viewer from a container or remote host, and `--port <PORT>` if `7890` is busy.
2. **Hosted viewer** — [https://mongodb.github.io/kingfisher/report-viewer/](https://mongodb.github.io/kingfisher/report-viewer/)
A static, upload-based copy of the same UI published on GitHub Pages. Drag a Kingfisher, Gitleaks, or TruffleHog report into the page and triage it in your browser. Everything runs client-side — no reports leave your machine. Useful when you want to share a link rather than a binary, or triage a report on a machine that doesn't have Kingfisher installed.
#### Why use a visual viewer / triager for Gitleaks, TruffleHog, and Kingfisher output?
Raw JSON output from Kingfisher, Gitleaks, and TruffleHog is excellent input for CI, ticketing systems, and SIEMs, but it's not how a human makes rotation and risk decisions. The viewer gives security engineers:
- **A skimmable overview** — findings are grouped by detector, rule, file, and repository, with counts and validation state, instead of one JSON object per line.
- **Cross-tool triage in one UI** — import a Gitleaks scan, a TruffleHog scan, and a Kingfisher scan of the same codebase into the same session and look at them side-by-side with deduplication, instead of reconciling three different schemas.
- **Clear "this is live" signals** — validated Kingfisher findings and TruffleHog-verified findings are surfaced as active credentials so you rotate real keys first; unverified/static matches are marked as not attempted rather than active or inactive.
- **Fingerprint-aware deduplication** — the same secret appearing across multiple reports, directories, or scan runs collapses to one entry.
- **Blast-radius context** — when a Kingfisher report was produced with `--access-map`, the viewer renders the identity, permissions, and resources the leaked credential actually reaches, so you can tell apart a test token from a production admin key.
- **A shareable, offline-friendly workbench** — runs locally via `kingfisher view` or via the hosted static page; nothing about the report is exfiltrated.
Gitleaks and TruffleHog are great at surfacing candidate matches. Kingfisher's viewer turns their candidates (and its own) into a triageable workflow without changing the scanner you already use.
#### Caveats for imported reports
Imported Gitleaks and TruffleHog reports are display-oriented. They do not carry Kingfisher-native `access_map` data, they cannot be driven by `kingfisher validate` / `revoke`, and their fingerprints use the importer's normalization rather than Kingfisher's native fingerprinting. TruffleHog findings marked as verified are shown as active credentials; all other imported findings are treated as not attempted rather than inactive. For full validation context and blast-radius mapping, re-scan with Kingfisher and add `--access-map` when appropriate.
### Pipe any text directly into Kingfisher by passing `-`

View file

@ -1,10 +1,10 @@
# AGENTS.md
Guidance for editing the local report viewer under `docs/access-map-viewer/`.
Guidance for editing the local report viewer under `docs/report-viewer/`.
## Scope
- Applies to `docs/access-map-viewer/` and all files under it.
- Applies to `docs/report-viewer/` and all files under it.
- This file overrides broader documentation guidance for this subtree.
## Current Architecture

View file

@ -1784,6 +1784,7 @@
</div>
</div>
<div style="display:flex; gap:10px; align-items:center; flex-wrap:wrap; justify-content:flex-end;">
<a class="btn" href="https://github.com/mongodb/kingfisher" target="_blank" rel="noopener noreferrer">GitHub</a>
<button class="btn" id="theme-toggle" type="button">Light Mode</button>
<button class="btn" id="reset-btn" type="button">Clear and Load New Report(s)</button>
</div>
@ -2304,7 +2305,7 @@
"view-findings": document.getElementById("view-findings"),
};
const THEME_KEY = "access-map-viewer-theme";
const THEME_KEY = "report-viewer-theme";
const systemThemeQuery = window.matchMedia("(prefers-color-scheme: light)");
function getStoredThemePreference() {
@ -2581,7 +2582,7 @@
return JSON.parse(text);
} catch (e) {
const trimmed = text.trim();
const parts = trimmed.split(/\r?\n(?=\s*{)/g).filter(Boolean);
const parts = trimmed.split(/\r?\n(?=\s*[{\[])/g).filter(Boolean);
if (parts.length > 1) {
try {
return JSON.parse("[" + parts.join(",") + "]");
@ -3017,6 +3018,50 @@
}
function normalizeReportPayload(payload) {
if (Array.isArray(payload)) {
const topFormat = detectReportFormat(payload);
if (topFormat === "gitleaks") {
return normalizeImportedPayload(payload, "Gitleaks");
}
if (topFormat === "trufflehog") {
return normalizeImportedPayload(payload, "TruffleHog");
}
const entryFormats = [];
let hasImported = false;
for (const entry of payload) {
if (entry === null || typeof entry !== "object") {
entryFormats.push(null);
continue;
}
const fmt = detectReportFormat(entry);
entryFormats.push(fmt);
if (fmt === "gitleaks" || fmt === "trufflehog") {
hasImported = true;
}
}
if (!hasImported) {
return normalizeKingfisherPayload(payload);
}
const combined = { f: [], am: [], rd: null };
for (let i = 0; i < payload.length; i++) {
const entry = payload[i];
const fmt = entryFormats[i];
if (entry === null || typeof entry !== "object") continue;
let partial;
if (fmt === "trufflehog") {
partial = normalizeImportedPayload(entry, "TruffleHog");
} else if (fmt === "gitleaks") {
partial = normalizeImportedPayload(entry, "Gitleaks");
} else {
partial = normalizeKingfisherPayload(entry);
}
if (!partial) continue;
if (Array.isArray(partial.f)) combined.f.push(...partial.f);
if (Array.isArray(partial.am)) combined.am.push(...partial.am);
combined.rd = mergeRawReportData(combined.rd, partial.rd);
}
return combined;
}
const format = detectReportFormat(payload);
if (format === "trufflehog") {
return normalizeImportedPayload(payload, "TruffleHog");
@ -3252,7 +3297,7 @@
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (!line || line[0] !== "{") continue;
if (!line || (line[0] !== "{" && line[0] !== "[")) continue;
try {
const obj = JSON.parse(line);
entries.push(obj);

View file

@ -20,7 +20,7 @@ use tracing::{info, warn};
pub const DEFAULT_PORT: u16 = 7890;
// Embedded viewer assets - force rebuild
static VIEWER_ASSETS: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/docs/access-map-viewer");
static VIEWER_ASSETS: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/docs/report-viewer");
/// Default bind address for the report viewer (localhost only for security).
pub const DEFAULT_ADDRESS: &str = "127.0.0.1";