forked from mirrors/kingfisher
added kingfisher.github.9 to detect the new ~520-character stateless GitHub App installation token format (ghs_<APP_ID>_<JWT>). The legacy 36-character ghs_ rule
This commit is contained in:
parent
2320a7ff72
commit
5465d903cf
17 changed files with 676 additions and 20 deletions
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [v1.98.0]
|
||||||
|
- Fixed [#359](https://github.com/mongodb/kingfisher/issues/359): added `kingfisher.github.9` to detect the new ~520-character stateless GitHub App installation token format (`ghs_<APP_ID>_<JWT>`). The legacy 36-character `ghs_` rule (`kingfisher.github.5`) is retained for older / GHES-issued tokens that are still in circulation.
|
||||||
|
|
||||||
## [v1.97.0]
|
## [v1.97.0]
|
||||||
- **Report viewer cross-tool triage:** when a Kingfisher report is loaded alongside a Gitleaks or TruffleHog report, matching imported findings are enriched with Kingfisher's validation verdict, validation response, validate command, and revoke command. Matching is keyed on `commit + file + line` with a `file + line` fallback, and enriched rows show an "Enriched by Kingfisher" callout in the detail panel plus an "Enriched" chip in the findings table. Added a **Source** column to the findings table; a new **Duplicates Removed by Tool** dashboard panel showing per-tool cards for Kingfisher / TruffleHog / Gitleaks; and an upload-time **Deduplicate findings** toggle (on by default) so users can inspect the raw rows before fingerprint dedup when needed.
|
- **Report viewer cross-tool triage:** when a Kingfisher report is loaded alongside a Gitleaks or TruffleHog report, matching imported findings are enriched with Kingfisher's validation verdict, validation response, validate command, and revoke command. Matching is keyed on `commit + file + line` with a `file + line` fallback, and enriched rows show an "Enriched by Kingfisher" callout in the detail panel plus an "Enriched" chip in the findings table. Added a **Source** column to the findings table; a new **Duplicates Removed by Tool** dashboard panel showing per-tool cards for Kingfisher / TruffleHog / Gitleaks; and an upload-time **Deduplicate findings** toggle (on by default) so users can inspect the raw rows before fingerprint dedup when needed.
|
||||||
- Fixed the HTML report 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.
|
||||||
|
|
|
||||||
153
CONTRIBUTING.md
Normal file
153
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
# Contributing to Kingfisher
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to Kingfisher.
|
||||||
|
|
||||||
|
Kingfisher is an open-source project owned by MongoDB and licensed under the
|
||||||
|
[Apache License 2.0](LICENSE). We welcome bug reports, feature requests,
|
||||||
|
documentation improvements, rule additions, validation improvements, and code
|
||||||
|
contributions.
|
||||||
|
|
||||||
|
## Before You Start
|
||||||
|
|
||||||
|
- Be respectful and collaborative. Participation in this project is covered by
|
||||||
|
the [MongoDB Community Code of Conduct](https://www.mongodb.com/community-code-of-conduct).
|
||||||
|
- If you plan to submit a pull request, sign the
|
||||||
|
[MongoDB Contributor Agreement](https://www.mongodb.com/legal/contributor-agreement)
|
||||||
|
first.
|
||||||
|
- For security vulnerabilities, do not open a public issue. Follow
|
||||||
|
[SECURITY.md](SECURITY.md) instead.
|
||||||
|
|
||||||
|
## Ways to Contribute
|
||||||
|
|
||||||
|
- Report bugs with clear reproduction steps, environment details, and logs when
|
||||||
|
possible.
|
||||||
|
- Propose features or usability improvements through GitHub issues.
|
||||||
|
- Improve documentation in `README.md`, `docs/`, or `docs-site/`.
|
||||||
|
- Add or refine detection rules under
|
||||||
|
`crates/kingfisher-rules/data/rules/`.
|
||||||
|
- Improve validation, revocation, scanning performance, output formats, or
|
||||||
|
integrations.
|
||||||
|
|
||||||
|
## Reporting Bugs and Requesting Features
|
||||||
|
|
||||||
|
Before opening a new issue:
|
||||||
|
|
||||||
|
- Check whether an existing issue already covers the problem or request.
|
||||||
|
- Confirm the issue still reproduces on a recent `main` checkout or current
|
||||||
|
release when practical.
|
||||||
|
- Include the smallest reproducible example you can provide.
|
||||||
|
|
||||||
|
Use the repository issue templates when they fit your case.
|
||||||
|
|
||||||
|
## Development Setup
|
||||||
|
|
||||||
|
Kingfisher is a Rust workspace. The workspace minimum Rust version is `1.94`,
|
||||||
|
and CI currently uses Rust `1.94.1`.
|
||||||
|
|
||||||
|
Helpful commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo build
|
||||||
|
make tests
|
||||||
|
cargo test --workspace --all-targets
|
||||||
|
cargo fmt --all
|
||||||
|
cargo clippy --workspace --all-targets -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
For repository layout and project-specific guidance, see:
|
||||||
|
|
||||||
|
- [README.md](README.md)
|
||||||
|
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
|
||||||
|
- [docs/USAGE.md](docs/USAGE.md)
|
||||||
|
- [docs/RULES.md](docs/RULES.md)
|
||||||
|
|
||||||
|
## Contribution Guidelines
|
||||||
|
|
||||||
|
### Keep changes focused
|
||||||
|
|
||||||
|
- Prefer small, reviewable pull requests over large mixed changes.
|
||||||
|
- Avoid unrelated refactors in the same PR unless they are necessary for the
|
||||||
|
fix.
|
||||||
|
- Update tests and docs when behavior changes.
|
||||||
|
|
||||||
|
### Do not commit real secrets
|
||||||
|
|
||||||
|
Kingfisher is a secret scanner. Never add live credentials, customer data, or
|
||||||
|
real tokens anywhere in the repository, including:
|
||||||
|
|
||||||
|
- tests
|
||||||
|
- fixtures
|
||||||
|
- examples
|
||||||
|
- docs
|
||||||
|
- screenshots
|
||||||
|
- benchmark artifacts
|
||||||
|
|
||||||
|
Use clearly fake placeholders or provider-documented example values only.
|
||||||
|
|
||||||
|
### Rule contributions
|
||||||
|
|
||||||
|
If you are adding or updating a rule:
|
||||||
|
|
||||||
|
- Follow the schema and authoring guidance in [docs/RULES.md](docs/RULES.md).
|
||||||
|
- Prefer YAML-defined validation and revocation when the provider API supports
|
||||||
|
it.
|
||||||
|
- Keep patterns specific and efficient.
|
||||||
|
- Add realistic examples and relevant tests.
|
||||||
|
- Set rule confidence to `medium`.
|
||||||
|
|
||||||
|
Useful validation commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test -p kingfisher-rules
|
||||||
|
cargo test --workspace --all-targets
|
||||||
|
kingfisher scan ./testdata --rule <rule-family-or-id> --rule-stats
|
||||||
|
kingfisher validate --rule <rule-id> <token-or-secret>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Expectations
|
||||||
|
|
||||||
|
Run the narrowest relevant checks for your change before opening a PR, then run
|
||||||
|
broader checks when practical.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- Rule-only changes: `cargo test -p kingfisher-rules`
|
||||||
|
- General Rust changes: `make tests`
|
||||||
|
- Formatting: `cargo fmt --all`
|
||||||
|
- Linting: `cargo clippy --workspace --all-targets -- -D warnings`
|
||||||
|
|
||||||
|
If you cannot run a relevant check locally, say so in the pull request and
|
||||||
|
explain why.
|
||||||
|
|
||||||
|
## Documentation Changes
|
||||||
|
|
||||||
|
- Keep examples consistent with current CLI behavior.
|
||||||
|
- Update related docs when flags, outputs, or workflows change.
|
||||||
|
- After changing `docs-site/` sources, rebuild the site when practical:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docs-site/.venv/bin/mkdocs build -f docs-site/mkdocs.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pull Request Checklist
|
||||||
|
|
||||||
|
Before opening a PR, make sure you have:
|
||||||
|
|
||||||
|
- signed the MongoDB Contributor Agreement
|
||||||
|
- kept the change focused
|
||||||
|
- added or updated tests where needed
|
||||||
|
- updated docs where needed
|
||||||
|
- run the relevant local checks
|
||||||
|
- avoided adding any real secrets or sensitive data
|
||||||
|
|
||||||
|
In the PR description, include:
|
||||||
|
|
||||||
|
- what changed
|
||||||
|
- why it changed
|
||||||
|
- how you tested it
|
||||||
|
- any follow-up work or known limitations
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
|
||||||
|
If you are unsure whether a change is in scope, open an issue first so the
|
||||||
|
approach can be discussed before you spend time on implementation.
|
||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -5030,7 +5030,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kingfisher"
|
name = "kingfisher"
|
||||||
version = "1.97.0"
|
version = "1.98.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"asar",
|
"asar",
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ http = "1.4"
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "kingfisher"
|
name = "kingfisher"
|
||||||
version = "1.97.0"
|
version = "1.98.0"
|
||||||
description = "MongoDB's blazingly fast and accurate secret scanning and validation tool"
|
description = "MongoDB's blazingly fast and accurate secret scanning and validation tool"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
<a href="https://github.com/mongodb/kingfisher/pkgs/container/kingfisher">
|
<a href="https://github.com/mongodb/kingfisher/pkgs/container/kingfisher">
|
||||||
<img src="https://ghcr-badge.elias.eu.org/shield/mongodb/kingfisher/kingfisher" alt="ghcr downloads" />
|
<img src="https://ghcr-badge.elias.eu.org/shield/mongodb/kingfisher/kingfisher" alt="ghcr downloads" />
|
||||||
</a>
|
</a>
|
||||||
|
<a href="https://github.com/mongodb/kingfisher/releases">
|
||||||
|
<img src="https://img.shields.io/github/downloads/mongodb/kingfisher/total" alt="GitHub Downloads" style="height: 24px;" />
|
||||||
|
</a>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
Kingfisher is an open source secret scanner and **live secret validation** tool built in Rust.
|
Kingfisher is an open source secret scanner and **live secret validation** tool built in Rust.
|
||||||
|
|
@ -392,7 +395,7 @@ Kingfisher ships with [942 built-in rules](crates/kingfisher-rules/data/rules/)
|
||||||
|
|
||||||
## Write Custom Rules
|
## Write Custom Rules
|
||||||
|
|
||||||
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.
|
Of Kingfisher's 942 built-in rules, 484 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.
|
However, you may want to add your own custom rules, or modify a detection to better suit your needs / environment.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -362,3 +362,48 @@ rules:
|
||||||
- |
|
- |
|
||||||
GITHUB_CLIENT_ID=ac58d6da7d7a84c039b7
|
GITHUB_CLIENT_ID=ac58d6da7d7a84c039b7
|
||||||
GITHUB_SECRET=37d02377a3e9d849e18704c3ec883f9c5787d857
|
GITHUB_SECRET=37d02377a3e9d849e18704c3ec883f9c5787d857
|
||||||
|
|
||||||
|
- name: GitHub App Server-to-Server Token (stateless JWT format)
|
||||||
|
id: kingfisher.github.9
|
||||||
|
pattern: |
|
||||||
|
(?x)
|
||||||
|
(
|
||||||
|
ghs_[0-9]+_
|
||||||
|
[A-Za-z0-9_-]+ \. [A-Za-z0-9_-]+ \. [A-Za-z0-9_-]+
|
||||||
|
)
|
||||||
|
\b
|
||||||
|
min_entropy: 3.5
|
||||||
|
examples:
|
||||||
|
- 'ghs_12345_eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3NDU1NjgwMDAsImV4cCI6MTc0NTU2ODM2MCwiaXNzIjoiMTIzNDUiLCJzdWIiOiJnaXRodWJ8MTIzNDUifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
|
||||||
|
references:
|
||||||
|
- https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app
|
||||||
|
- https://github.com/mongodb/kingfisher/issues/359
|
||||||
|
validation:
|
||||||
|
type: Http
|
||||||
|
content:
|
||||||
|
request:
|
||||||
|
method: GET
|
||||||
|
url: https://api.github.com/user
|
||||||
|
headers:
|
||||||
|
Authorization: token {{ TOKEN }}
|
||||||
|
Accept: application/vnd.github+json
|
||||||
|
response_matcher:
|
||||||
|
- report_response: true
|
||||||
|
- match_all_words: true
|
||||||
|
type: WordMatch
|
||||||
|
words:
|
||||||
|
- '"login"'
|
||||||
|
- '"id"'
|
||||||
|
revocation:
|
||||||
|
type: Http
|
||||||
|
content:
|
||||||
|
request:
|
||||||
|
method: DELETE
|
||||||
|
url: https://api.github.com/installation/token
|
||||||
|
headers:
|
||||||
|
Authorization: token {{ TOKEN }}
|
||||||
|
Accept: application/vnd.github+json
|
||||||
|
response_matcher:
|
||||||
|
- report_response: true
|
||||||
|
- type: StatusMatch
|
||||||
|
status: [204]
|
||||||
11
docs-site/docs/blog/index.md
Normal file
11
docs-site/docs/blog/index.md
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
title: Kingfisher Blog
|
||||||
|
description: >
|
||||||
|
News, tutorials, and deep-dives on secret detection, credential validation,
|
||||||
|
and supply-chain security from the Kingfisher team at MongoDB.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Kingfisher Blog
|
||||||
|
|
||||||
|
Tutorials, release notes, and deep-dives on secret scanning, credential
|
||||||
|
validation, and supply-chain security.
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
---
|
||||||
|
date: 2026-04-26
|
||||||
|
title: "Beyond Detection: Live Validation, Blast Radius, and One-Command Revocation"
|
||||||
|
description: >
|
||||||
|
Detection alone is noise. Kingfisher answers the three questions that
|
||||||
|
actually matter when a secret leaks — is it live, what does it reach,
|
||||||
|
and can we revoke it now — across AWS, GCP, GitHub, GitLab, Slack,
|
||||||
|
and dozens of other providers.
|
||||||
|
categories:
|
||||||
|
- Features
|
||||||
|
tags:
|
||||||
|
- validation
|
||||||
|
- blast-radius
|
||||||
|
- revocation
|
||||||
|
- secret-scanning
|
||||||
|
---
|
||||||
|
|
||||||
|
# Beyond Detection: Live Validation, Blast Radius, and One-Command Revocation
|
||||||
|
|
||||||
|
A regex match on `AKIA[0-9A-Z]{16}` is the easy part. Every secret scanner
|
||||||
|
finds those. The hard part — and the part that decides whether your Tuesday
|
||||||
|
afternoon turns into an incident — is what happens **after** the match.
|
||||||
|
|
||||||
|
Kingfisher answers the three questions that actually matter:
|
||||||
|
|
||||||
|
1. **Is this credential alive right now?**
|
||||||
|
2. **What can it reach?**
|
||||||
|
3. **Can we kill it from here?**
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
## 1. Live validation, not just pattern matching
|
||||||
|
|
||||||
|
Out of Kingfisher's 820 standalone detectors, **484 include live validation
|
||||||
|
logic**. Every one of those calls the provider's own API and reports the
|
||||||
|
credential as `Active`, `Inactive`, or `NotAttempted` — so a 4,000-finding
|
||||||
|
scan collapses to the dozen findings that are actually live.
|
||||||
|
|
||||||
|
Validation runs automatically when you scan:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kingfisher scan github --organization my-org
|
||||||
|
```
|
||||||
|
|
||||||
|
Or you can run it standalone when you've already pulled a suspicious value
|
||||||
|
out of a paste, a log, or a customer ticket:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Hit GitHub's user API to confirm the token works
|
||||||
|
kingfisher validate --rule github "$GITHUB_TOKEN"
|
||||||
|
|
||||||
|
# AWS needs both halves of the keypair
|
||||||
|
kingfisher validate --rule aws \
|
||||||
|
--arg "$AWS_ACCESS_KEY_ID" \
|
||||||
|
"$AWS_SECRET_ACCESS_KEY"
|
||||||
|
|
||||||
|
# A GCP service account JSON, straight from the file
|
||||||
|
kingfisher validate --rule gcp "$(cat service-account.json)"
|
||||||
|
|
||||||
|
# A Postgres connection URI — does it actually authenticate?
|
||||||
|
kingfisher validate --rule postgres "$POSTGRES_URI"
|
||||||
|
```
|
||||||
|
|
||||||
|
Validation logic lives in the rule YAML, not in compiled Rust, which is
|
||||||
|
why coverage is high and growing — every new detector ships with a
|
||||||
|
validation block whenever the provider exposes a safe check call.
|
||||||
|
|
||||||
|
## 2. Blast radius mapping — what does this token actually reach?
|
||||||
|
|
||||||
|
A leaked AWS key bound to a single read-only S3 bucket and a leaked AWS key
|
||||||
|
bound to organization-wide `AdministratorAccess` are not the same incident.
|
||||||
|
The first is a Friday afternoon ticket. The second is a war room.
|
||||||
|
|
||||||
|
Add `--access-map` to a scan and Kingfisher authenticates each live
|
||||||
|
credential, enumerates what it can do, and writes the result alongside
|
||||||
|
the finding:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kingfisher scan github --organization my-org \
|
||||||
|
--access-map \
|
||||||
|
--format json \
|
||||||
|
--output findings.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Each cloud finding gets an `access_map` block with the identity, the
|
||||||
|
permissions, and the concrete resources reachable. Today this is supported
|
||||||
|
for **AWS, GCP, Azure Storage, Azure DevOps, GitHub, GitLab, Slack, and
|
||||||
|
Microsoft Teams.**
|
||||||
|
|
||||||
|
You can also run it standalone — useful when triaging a single credential
|
||||||
|
you've fished out of a paste or a customer report:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# What does this AWS keypair actually own?
|
||||||
|
kingfisher access-map aws ./aws.json --json-out aws.access-map.json
|
||||||
|
|
||||||
|
# Same for a GitHub token
|
||||||
|
kingfisher access-map github ./github.token --json-out github.access-map.json
|
||||||
|
|
||||||
|
# Or a GCP service account
|
||||||
|
kingfisher access-map gcp ./service-account.json --json-out gcp.access-map.json
|
||||||
|
```
|
||||||
|
|
||||||
|
The HTML report viewer (`--format html`) renders the access map as a
|
||||||
|
clickable tree — identity at the root, then services, then individual
|
||||||
|
resources and permissions. It's the fastest way to get a non-engineer
|
||||||
|
stakeholder to grasp severity in five seconds rather than five minutes.
|
||||||
|
|
||||||
|
## 3. Revocation — kill the token from where you found it
|
||||||
|
|
||||||
|
Validation tells you a credential is live. Blast radius tells you why it's
|
||||||
|
urgent. Revocation tells you it's done.
|
||||||
|
|
||||||
|
For every rule whose provider exposes a safe revocation API, Kingfisher
|
||||||
|
ships the revocation call as part of the rule definition. One command,
|
||||||
|
no console:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Revoke a GitHub PAT
|
||||||
|
kingfisher revoke --rule github "$GITHUB_TOKEN"
|
||||||
|
|
||||||
|
# Revoke a GitLab token
|
||||||
|
kingfisher revoke --rule gitlab "$GITLAB_TOKEN"
|
||||||
|
|
||||||
|
# Revoke a Slack bot token
|
||||||
|
kingfisher revoke --rule slack "$SLACK_TOKEN"
|
||||||
|
|
||||||
|
# Deactivate an AWS access key
|
||||||
|
kingfisher revoke --rule aws \
|
||||||
|
--arg "$AWS_ACCESS_KEY_ID" \
|
||||||
|
"$AWS_SECRET_ACCESS_KEY"
|
||||||
|
|
||||||
|
# Disable a GCP service account key
|
||||||
|
kingfisher revoke --rule gcp "$(cat service-account.json)"
|
||||||
|
```
|
||||||
|
|
||||||
|
The same Liquid templating that powers the validation request handles
|
||||||
|
revocation — including multi-step flows for providers that need a separate
|
||||||
|
key-id lookup before disabling. (See
|
||||||
|
[`docs/RULES.md`](https://github.com/mongodb/kingfisher/blob/main/docs/RULES.md#multi-step-revocation)
|
||||||
|
for the schema.)
|
||||||
|
|
||||||
|
This matters in two scenarios:
|
||||||
|
|
||||||
|
- **Mass revocation after a leak.** A laptop or a CI runner gets popped and
|
||||||
|
you have a list of fingerprints. `kingfisher revoke` walks the list, no
|
||||||
|
human pivoting between five provider consoles.
|
||||||
|
- **Automated response.** Wire `kingfisher revoke` into the same job that
|
||||||
|
scanned and validated, gated by an allow-list of rule IDs you've decided
|
||||||
|
are safe to auto-revoke (typically: short-lived CI tokens, dev-environment
|
||||||
|
secrets). The credential is dead before the on-call gets paged.
|
||||||
|
|
||||||
|
## The combined workflow
|
||||||
|
|
||||||
|
In practice these three primitives chain into a single pipeline:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Scan + validate + map blast radius in one call
|
||||||
|
kingfisher scan github --organization my-org \
|
||||||
|
--access-map \
|
||||||
|
--format json \
|
||||||
|
--output findings.json
|
||||||
|
|
||||||
|
# 2. Pull just the live, high-blast-radius findings
|
||||||
|
jq '[.[] | select(.validation.status == "Active")
|
||||||
|
| select(.access_map.permissions
|
||||||
|
| any(. == "*" or contains("Admin")))]' \
|
||||||
|
findings.json > urgent.json
|
||||||
|
|
||||||
|
# 3. Triage in the HTML viewer (or revoke programmatically)
|
||||||
|
kingfisher view findings.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Three commands, full incident workflow — find, prioritize, kill.
|
||||||
|
|
||||||
|
## Why this is the right shape
|
||||||
|
|
||||||
|
Most scanners stop at step one because going further is expensive: every
|
||||||
|
provider has its own auth flow, its own permission model, its own
|
||||||
|
revocation API. Kingfisher gets to a high-coverage version of all three by
|
||||||
|
keeping the logic in YAML rule files (the same place the detection regex
|
||||||
|
lives), reusing typed validators for the common families (AWS, GCP, JWT,
|
||||||
|
Postgres, MongoDB, MySQL, JDBC, Azure Storage, Coinbase), and letting rule
|
||||||
|
authors drop down to a `Raw` validator only for genuinely odd providers.
|
||||||
|
|
||||||
|
The upshot for users: when a new detector lands, you almost always get
|
||||||
|
validation, blast radius, and revocation along with it — not three
|
||||||
|
separate roadmaps.
|
||||||
|
|
||||||
|
## Next up
|
||||||
|
|
||||||
|
- **Catching secrets in pull requests with GitHub Actions** — pre-merge
|
||||||
|
scanning so leaked credentials never reach `main`.
|
||||||
|
- **Top leaked credential types we see in the wild** — what validation
|
||||||
|
telemetry says about the credential leak landscape.
|
||||||
|
- **Docker image scanning** — pulling and scanning every layer for
|
||||||
|
embedded secrets.
|
||||||
|
|
||||||
|
Got a provider you'd love to see validation or revocation support for?
|
||||||
|
Open an issue at
|
||||||
|
[mongodb/kingfisher](https://github.com/mongodb/kingfisher/issues).
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
---
|
||||||
|
date: 2026-04-26
|
||||||
|
title: "Scanning an Entire GitHub Organization for Leaked Secrets"
|
||||||
|
description: >
|
||||||
|
Step-by-step guide to scanning every repository in a GitHub organization
|
||||||
|
for leaked credentials with Kingfisher — including history, issues, wikis,
|
||||||
|
and gists — and validating which secrets are still live.
|
||||||
|
categories:
|
||||||
|
- Tutorials
|
||||||
|
tags:
|
||||||
|
- github
|
||||||
|
- secret-scanning
|
||||||
|
- validation
|
||||||
|
- tutorial
|
||||||
|
---
|
||||||
|
|
||||||
|
# Scanning an Entire GitHub Organization for Leaked Secrets
|
||||||
|
|
||||||
|
Most organizations have hundreds of repositories — some abandoned, some active,
|
||||||
|
plenty inherited from acquisitions. A leaked AWS key in a five-year-old archived
|
||||||
|
repo is just as dangerous as one in `main` today. Kingfisher can enumerate every
|
||||||
|
repo in a GitHub organization, scan the full git history, and then **validate
|
||||||
|
which credentials are still live** so you know what to rotate first.
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
## What you need
|
||||||
|
|
||||||
|
- Kingfisher installed (`brew install mongodb/brew/kingfisher`, or grab a
|
||||||
|
release from [GitHub](https://github.com/mongodb/kingfisher/releases)).
|
||||||
|
- A GitHub personal access token exported as `KF_GITHUB_TOKEN`. A classic
|
||||||
|
token with `repo` and `read:org` scopes is enough for private repos; for
|
||||||
|
public-only scans, even an unscoped token raises your rate limit and
|
||||||
|
is strongly recommended.
|
||||||
|
- About 5 GB of free disk for clones (varies by org size — use
|
||||||
|
`--git-clone-dir /path/to/big/disk` if your home volume is small).
|
||||||
|
|
||||||
|
## The one-liner
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export KF_GITHUB_TOKEN=ghp_yourTokenHere
|
||||||
|
kingfisher scan github --organization my-org
|
||||||
|
```
|
||||||
|
|
||||||
|
That's it — Kingfisher enumerates every repo, clones each one, scans the full
|
||||||
|
commit history, runs all 942 detection rules, and validates findings against
|
||||||
|
provider APIs.
|
||||||
|
|
||||||
|
## Tuning for real-world orgs
|
||||||
|
|
||||||
|
Real orgs have huge monorepos, archived junk, and forks you don't care about.
|
||||||
|
Three flags do most of the work:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kingfisher scan github --organization my-org \
|
||||||
|
--repo-clone-limit 500 \
|
||||||
|
--github-exclude 'my-org/*-archive' \
|
||||||
|
--github-exclude 'my-org/legacy-monorepo' \
|
||||||
|
--git-clone-dir /var/tmp/kf-clones \
|
||||||
|
--format sarif \
|
||||||
|
--output kf-findings.sarif
|
||||||
|
```
|
||||||
|
|
||||||
|
- **`--repo-clone-limit`** caps the number of clones per scan. Useful for
|
||||||
|
staged rollouts ("first 500 repos by stars") or to stay under disk budget.
|
||||||
|
- **`--github-exclude`** accepts exact `OWNER/REPO` strings or gitignore-style
|
||||||
|
globs (`my-org/*-archive`). Repeat the flag for each pattern. Matching is
|
||||||
|
case-insensitive.
|
||||||
|
- **`--git-clone-dir`** moves clones off your home volume. Combine with
|
||||||
|
`--keep-clones` if you want to re-scan later without re-cloning.
|
||||||
|
|
||||||
|
## Pulling in issues, wikis, and gists
|
||||||
|
|
||||||
|
Secrets don't only live in code. Issues and pull request descriptions are a
|
||||||
|
common leak source — someone pastes a stack trace with a JWT, or an
|
||||||
|
"oncall handoff" issue with a temporary token that never got rotated. Add
|
||||||
|
`--repo-artifacts` to fetch these:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kingfisher scan github --organization my-org --repo-artifacts
|
||||||
|
```
|
||||||
|
|
||||||
|
This pulls each repo's issues (including PRs), wiki, and any **public** gists
|
||||||
|
owned by the repo owner, and scans them all. It does cost API calls, so plan
|
||||||
|
accordingly if you're near a rate limit.
|
||||||
|
|
||||||
|
## Following the people, not just the org
|
||||||
|
|
||||||
|
This is the trick that catches what every other scanner misses. Developers
|
||||||
|
leak secrets in *personal* repositories — side projects, dotfiles, throwaway
|
||||||
|
forks. If a contributor to your org has a public personal repo with an active
|
||||||
|
token that grants access to org infrastructure, that's a real incident.
|
||||||
|
|
||||||
|
Pass a single repo URL with `--include-contributors` and Kingfisher will
|
||||||
|
enumerate the contributors, then clone and scan **every public repo they own**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kingfisher scan https://github.com/my-org/critical-service \
|
||||||
|
--include-contributors \
|
||||||
|
--repo-clone-limit 200
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a noisy operation — start with one or two critical repos rather than
|
||||||
|
the whole org. GitHub will rate-limit aggressive enumeration, so a token
|
||||||
|
(`KF_GITHUB_TOKEN`) is required in practice.
|
||||||
|
|
||||||
|
## Reading the output
|
||||||
|
|
||||||
|
The default `pretty` output is human-friendly for terminals. For automation,
|
||||||
|
pick the format that matches your downstream tool:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# JSON for custom tooling
|
||||||
|
kingfisher scan github --organization my-org --format json --output findings.json
|
||||||
|
|
||||||
|
# SARIF for GitHub code scanning, GitLab, or any SARIF-aware UI
|
||||||
|
kingfisher scan github --organization my-org --format sarif --output findings.sarif
|
||||||
|
|
||||||
|
# TOON for piping to an LLM or agent
|
||||||
|
kingfisher scan github --organization my-org --format toon
|
||||||
|
```
|
||||||
|
|
||||||
|
The interactive HTML report is often the fastest way to triage a large scan —
|
||||||
|
filter by rule, by validation status, or by repository, and click through to
|
||||||
|
the exact commit and line:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kingfisher scan github --organization my-org --format html --output kf-report.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## Triage by validation status
|
||||||
|
|
||||||
|
The single most important column in the output is **validation**. A live
|
||||||
|
credential is a fire — a never-was-valid one is noise. Filter to live findings
|
||||||
|
first:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
jq '.[] | select(.validation.status == "Active")' findings.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Then walk those credentials in order of blast radius. For AWS, GCP, GitHub,
|
||||||
|
GitLab, and Slack tokens, Kingfisher already maps what each one can access —
|
||||||
|
look at the `access_map` field in the JSON output, or the **Blast Radius**
|
||||||
|
panel in the HTML report.
|
||||||
|
|
||||||
|
## Revoke from the CLI
|
||||||
|
|
||||||
|
For supported providers, you don't need to log into a console — Kingfisher can
|
||||||
|
revoke directly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kingfisher revoke --rule kingfisher.aws.access_key.1 AKIAEXAMPLE...
|
||||||
|
```
|
||||||
|
|
||||||
|
Each rule that supports revocation declares the API call in its YAML. Today
|
||||||
|
this works for AWS, GitHub, GitLab, Slack, and a growing list of SaaS
|
||||||
|
providers — see [`docs/RULES.md`](https://github.com/mongodb/kingfisher/blob/main/docs/RULES.md)
|
||||||
|
for the current list and how to add revocation to a custom rule.
|
||||||
|
|
||||||
|
## Wiring it into a recurring job
|
||||||
|
|
||||||
|
A first scan is the one-shot baseline. The real value is recurring scans
|
||||||
|
catching new leaks within hours, not months. The simplest pattern is a nightly
|
||||||
|
GitHub Action or scheduled CI job that runs the org scan, diffs against
|
||||||
|
yesterday's findings, and pages on net-new live credentials. We'll cover that
|
||||||
|
end-to-end in the next post.
|
||||||
|
|
||||||
|
## What's next
|
||||||
|
|
||||||
|
- **Catching secrets in pull requests with GitHub Actions** — pre-merge
|
||||||
|
scanning so leaks never reach `main`.
|
||||||
|
- **The most common credential types we see leaked in the wild** — what
|
||||||
|
Kingfisher's validation telemetry says about the credential leak landscape.
|
||||||
|
- **Docker image scanning** — pulling images directly and scanning every
|
||||||
|
layer for embedded secrets.
|
||||||
|
|
||||||
|
If there's a workflow you'd like us to cover, open an issue at
|
||||||
|
[mongodb/kingfisher](https://github.com/mongodb/kingfisher/issues).
|
||||||
|
|
@ -7,6 +7,9 @@ description: "Kingfisher release history: new features, rules, bug fixes, and im
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [v1.98.0]
|
||||||
|
- Fixed [#359](https://github.com/mongodb/kingfisher/issues/359): added `kingfisher.github.9` to detect the new ~520-character stateless GitHub App installation token format (`ghs_<APP_ID>_<JWT>`). The legacy 36-character `ghs_` rule (`kingfisher.github.5`) is retained for older / GHES-issued tokens that are still in circulation. Bundled ruleset is now **943 rules** (821 standalone detectors + 122 dependent rules), with **485 standalone detectors** offering live validation.
|
||||||
|
|
||||||
## [v1.97.0]
|
## [v1.97.0]
|
||||||
- **Report viewer cross-tool triage:** when a Kingfisher report is loaded alongside a Gitleaks or TruffleHog report, matching imported findings are enriched with Kingfisher's validation verdict, validation response, validate command, and revoke command. Matching is keyed on `commit + file + line` with a `file + line` fallback, and enriched rows show an "Enriched by Kingfisher" callout in the detail panel plus an "Enriched" chip in the findings table. Added a **Source** column to the findings table; a new **Duplicates Removed by Tool** dashboard panel showing per-tool cards for Kingfisher / TruffleHog / Gitleaks; and an upload-time **Deduplicate findings** toggle (on by default) so users can inspect the raw rows before fingerprint dedup when needed.
|
- **Report viewer cross-tool triage:** when a Kingfisher report is loaded alongside a Gitleaks or TruffleHog report, matching imported findings are enriched with Kingfisher's validation verdict, validation response, validate command, and revoke command. Matching is keyed on `commit + file + line` with a `file + line` fallback, and enriched rows show an "Enriched by Kingfisher" callout in the detail panel plus an "Enriched" chip in the findings table. Added a **Source** column to the findings table; a new **Duplicates Removed by Tool** dashboard panel showing per-tool cards for Kingfisher / TruffleHog / Gitleaks; and an upload-time **Deduplicate findings** toggle (on by default) so users can inspect the raw rows before fingerprint dedup when needed.
|
||||||
- Fixed the HTML report 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.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
title: Kingfisher — Open Source Secret Scanner with Live Validation
|
title: Kingfisher — Open Source Secret Scanner with Live Validation
|
||||||
description: >-
|
description: >-
|
||||||
Kingfisher is an open source secret scanner with live validation, blast radius
|
Kingfisher is an open source secret scanner with live validation, blast radius
|
||||||
mapping, and credential revocation. 942 detection rules (484 with live validation),
|
mapping, and credential revocation. 943 detection rules (485 with live validation),
|
||||||
plus a browser-based report viewer that also triages Gitleaks and TruffleHog output.
|
plus a browser-based report viewer that also triages Gitleaks and TruffleHog output.
|
||||||
Built in Rust by MongoDB.
|
Built in Rust by MongoDB.
|
||||||
template: home.html
|
template: home.html
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
---
|
---
|
||||||
title: "Built-in Rules List"
|
title: "Built-in Rules List"
|
||||||
description: "Complete list of all 942 built-in secret detection rules in Kingfisher. Searchable and filterable by provider, confidence level, and validation support."
|
description: "Complete list of all 943 built-in secret detection rules in Kingfisher. Searchable and filterable by provider, confidence level, and validation support."
|
||||||
---
|
---
|
||||||
|
|
||||||
# Built-in Rules
|
# Built-in Rules
|
||||||
|
|
||||||
Kingfisher ships with **942 detection rules** across **580 providers**
|
Kingfisher ships with **943 detection rules** across **581 providers**
|
||||||
(820 detectors + 122 dependent rules).
|
(821 detectors + 122 dependent rules).
|
||||||
Of these, **605** include live validation and **57** support direct revocation.
|
Of these, **485** include live validation and **50** support direct revocation.
|
||||||
|
|
||||||
!!! tip "Search"
|
!!! tip "Search"
|
||||||
Use the search box below to filter rules by provider name, rule ID, or confidence level.
|
Use the search box below to filter rules by provider name, rule ID, or confidence level.
|
||||||
|
|
@ -127,7 +127,7 @@ Of these, **605** include live validation and **57** support direct revocation.
|
||||||
<td>Agora</td>
|
<td>Agora</td>
|
||||||
<td>Agora App ID</td>
|
<td>Agora App ID</td>
|
||||||
<td><code>kingfisher.agora.1</code></td>
|
<td><code>kingfisher.agora.1</code></td>
|
||||||
<td>Low</td>
|
<td>Medium</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -1572,6 +1572,22 @@ Of these, **605** include live validation and **57** support direct revocation.
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>Confluence</td>
|
||||||
|
<td>Confluence Data Center Personal Access Token</td>
|
||||||
|
<td><code>kingfisher.confluence.1</code></td>
|
||||||
|
<td>Medium</td>
|
||||||
|
<td>Yes</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Confluence</td>
|
||||||
|
<td>Confluence Data Center Domain</td>
|
||||||
|
<td><code>kingfisher.confluence.2</code></td>
|
||||||
|
<td>Medium</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
<td>Confluent</td>
|
<td>Confluent</td>
|
||||||
<td>Confluent Client ID</td>
|
<td>Confluent Client ID</td>
|
||||||
<td><code>kingfisher.confluent.1</code></td>
|
<td><code>kingfisher.confluent.1</code></td>
|
||||||
|
|
@ -2096,7 +2112,7 @@ Of these, **605** include live validation and **57** support direct revocation.
|
||||||
<td>DocuSign API Secret Key</td>
|
<td>DocuSign API Secret Key</td>
|
||||||
<td><code>kingfisher.docusign.1</code></td>
|
<td><code>kingfisher.docusign.1</code></td>
|
||||||
<td>Medium</td>
|
<td>Medium</td>
|
||||||
<td>Yes</td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -2940,6 +2956,14 @@ Of these, **605** include live validation and **57** support direct revocation.
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>Github</td>
|
||||||
|
<td>GitHub App Server-to-Server Token (stateless JWT format)</td>
|
||||||
|
<td><code>kingfisher.github.9</code></td>
|
||||||
|
<td>Medium</td>
|
||||||
|
<td>Yes</td>
|
||||||
|
<td>Yes</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
<td>Gitlab</td>
|
<td>Gitlab</td>
|
||||||
<td>GitLab Private Token</td>
|
<td>GitLab Private Token</td>
|
||||||
<td><code>kingfisher.gitlab.1</code></td>
|
<td><code>kingfisher.gitlab.1</code></td>
|
||||||
|
|
@ -3463,7 +3487,7 @@ Of these, **605** include live validation and **57** support direct revocation.
|
||||||
<td>Huawei</td>
|
<td>Huawei</td>
|
||||||
<td>Huawei Open Platform Client ID</td>
|
<td>Huawei Open Platform Client ID</td>
|
||||||
<td><code>kingfisher.huawei.1</code></td>
|
<td><code>kingfisher.huawei.1</code></td>
|
||||||
<td>Low</td>
|
<td>Medium</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -3700,6 +3724,22 @@ Of these, **605** include live validation and **57** support direct revocation.
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>Jira</td>
|
||||||
|
<td>Jira Data Center Personal Access Token</td>
|
||||||
|
<td><code>kingfisher.jira.3</code></td>
|
||||||
|
<td>Medium</td>
|
||||||
|
<td>Yes</td>
|
||||||
|
<td>Yes</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Jira</td>
|
||||||
|
<td>Jira Data Center Domain</td>
|
||||||
|
<td><code>kingfisher.jira.4</code></td>
|
||||||
|
<td>Medium</td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
<td>Jotform</td>
|
<td>Jotform</td>
|
||||||
<td>Jotform API Key</td>
|
<td>Jotform API Key</td>
|
||||||
<td><code>kingfisher.jotform.1</code></td>
|
<td><code>kingfisher.jotform.1</code></td>
|
||||||
|
|
@ -7215,7 +7255,7 @@ Of these, **605** include live validation and **57** support direct revocation.
|
||||||
<td>Webex</td>
|
<td>Webex</td>
|
||||||
<td>Webex Integration Client ID</td>
|
<td>Webex Integration Client ID</td>
|
||||||
<td><code>kingfisher.webex.1</code></td>
|
<td><code>kingfisher.webex.1</code></td>
|
||||||
<td>Low</td>
|
<td>Medium</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
site_name: Kingfisher
|
site_name: Kingfisher
|
||||||
site_url: https://mongodb.github.io/kingfisher
|
site_url: https://mongodb.github.io/kingfisher
|
||||||
site_description: >-
|
site_description: >-
|
||||||
Open source secret scanner with live validation. 942 detection rules,
|
Open source secret scanner with live validation. 943 detection rules,
|
||||||
blast radius mapping, credential revocation, and a browser-based
|
blast radius mapping, credential revocation, and a browser-based
|
||||||
report viewer that also imports Gitleaks and TruffleHog output.
|
report viewer that also imports Gitleaks and TruffleHog output.
|
||||||
Built in Rust by MongoDB.
|
Built in Rust by MongoDB.
|
||||||
|
|
@ -46,6 +46,22 @@ theme:
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- search
|
- search
|
||||||
|
- blog:
|
||||||
|
blog_dir: blog
|
||||||
|
post_date_format: long
|
||||||
|
post_url_format: "{date}/{slug}"
|
||||||
|
post_excerpt: required
|
||||||
|
archive: true
|
||||||
|
categories: true
|
||||||
|
pagination_per_page: 10
|
||||||
|
authors: false
|
||||||
|
- rss:
|
||||||
|
match_path: blog/posts/.*
|
||||||
|
date_from_meta:
|
||||||
|
as_creation: date
|
||||||
|
categories:
|
||||||
|
- categories
|
||||||
|
- tags
|
||||||
- minify:
|
- minify:
|
||||||
minify_html: true
|
minify_html: true
|
||||||
|
|
||||||
|
|
@ -99,6 +115,8 @@ nav:
|
||||||
- Python Bindings: reference/python-bindings.md
|
- Python Bindings: reference/python-bindings.md
|
||||||
- Benchmarks & Comparison: reference/comparison.md
|
- Benchmarks & Comparison: reference/comparison.md
|
||||||
- Report Viewer: https://mongodb.github.io/kingfisher/viewer/
|
- Report Viewer: https://mongodb.github.io/kingfisher/viewer/
|
||||||
|
- Blog:
|
||||||
|
- blog/index.md
|
||||||
- Changelog: changelog.md
|
- Changelog: changelog.md
|
||||||
|
|
||||||
extra:
|
extra:
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
<section class="kf-stats">
|
<section class="kf-stats">
|
||||||
<div class="kf-stats__inner md-grid">
|
<div class="kf-stats__inner md-grid">
|
||||||
<div class="kf-stats__item">
|
<div class="kf-stats__item">
|
||||||
<span class="kf-stats__number">942</span>
|
<span class="kf-stats__number">943</span>
|
||||||
<span class="kf-stats__label">Detection Rules</span>
|
<span class="kf-stats__label">Detection Rules</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="kf-stats__item">
|
<div class="kf-stats__item">
|
||||||
|
|
@ -48,8 +48,8 @@
|
||||||
<span class="kf-stats__label">Scan Targets</span>
|
<span class="kf-stats__label">Scan Targets</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="kf-stats__item">
|
<div class="kf-stats__item">
|
||||||
<span class="kf-stats__number">34</span>
|
<span class="kf-stats__number">49</span>
|
||||||
<span class="kf-stats__label">Revocation Providers</span>
|
<span class="kf-stats__label">Rules with Revocation</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -90,7 +90,7 @@
|
||||||
<div class="kf-feature">
|
<div class="kf-feature">
|
||||||
<h3>Direct Revocation</h3>
|
<h3>Direct Revocation</h3>
|
||||||
<p>
|
<p>
|
||||||
Revoke compromised credentials directly from the CLI for 34 provider families
|
Revoke compromised credentials directly from the CLI for 29 provider families
|
||||||
including GitHub, GitLab, Slack, AWS, GCP, Heroku, and Cloudflare.
|
including GitHub, GitLab, Slack, AWS, GCP, Heroku, and Cloudflare.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "SoftwareApplication",
|
"@type": "SoftwareApplication",
|
||||||
"name": "Kingfisher",
|
"name": "Kingfisher",
|
||||||
"description": "Open source secret scanner with live validation. 942 detection rules, blast radius mapping, and credential revocation.",
|
"description": "Open source secret scanner with live validation. 943 detection rules, blast radius mapping, and credential revocation.",
|
||||||
"applicationCategory": "DeveloperApplication",
|
"applicationCategory": "DeveloperApplication",
|
||||||
"operatingSystem": "Linux, macOS, Windows",
|
"operatingSystem": "Linux, macOS, Windows",
|
||||||
"license": "https://opensource.org/licenses/Apache-2.0",
|
"license": "https://opensource.org/licenses/Apache-2.0",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
mkdocs-material>=9.5
|
mkdocs-material>=9.5
|
||||||
mkdocs-minify-plugin>=0.8
|
mkdocs-minify-plugin>=0.8
|
||||||
|
mkdocs-rss-plugin>=1.6
|
||||||
pillow>=10.0
|
pillow>=10.0
|
||||||
cairosvg>=2.7
|
cairosvg>=2.7
|
||||||
pyyaml>=6.0
|
pyyaml>=6.0
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ def generate_markdown(rules):
|
||||||
total = len(rules)
|
total = len(rules)
|
||||||
detectors = sum(1 for r in rules if not r["dependent"])
|
detectors = sum(1 for r in rules if not r["dependent"])
|
||||||
dependent = total - detectors
|
dependent = total - detectors
|
||||||
validated = sum(1 for r in rules if r["validates"])
|
validated = sum(1 for r in rules if r["validates"] and not r["dependent"])
|
||||||
revocable = sum(1 for r in rules if r["revokes"])
|
revocable = sum(1 for r in rules if r["revokes"] and not r["dependent"])
|
||||||
providers = len(set(r["provider"] for r in rules))
|
providers = len(set(r["provider"] for r in rules))
|
||||||
|
|
||||||
lines = [
|
lines = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue