updated docs

This commit is contained in:
Mick Grove 2026-04-14 22:56:19 -07:00
commit 6100eeb6b5
42 changed files with 2253 additions and 68 deletions

View file

@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file.
## [v1.96.0]
- Added live HTTP validation for 18 rules across 15 providers: Val Town, Polar, hCaptcha, Thunderstore, Elastic Cloud (2 rules), LlamaCloud, Gemfury (2 rules), Vonage, ThingsBoard, Zapier, Facebook Access Token, GitLab Session Cookie, PostHog Feature Flags, Unkey API Key, and Hop.io (2 rules).
- Added revocation support for 7 rules across 6 providers: Discord webhooks (single-step DELETE), DigitalOcean PATs (self-revoke via OAuth), and multi-step HttpMultiStep revocation for LaunchDarkly, Resend, Linode, and Netlify (2 rules). Built-in revocation coverage is now 34 provider families with 53 revocation-enabled rules.
- Expanded Alibaba Cloud coverage with STS temporary credential detection for STS access key IDs, STS security tokens, and STS access key secrets. Built-in rule coverage is now 921 rules total.
- 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`.
## [v1.95.0]

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-825-2ea043.svg" alt="Detection Rules" style="height: 24px;" />
<img src="https://img.shields.io/badge/Detection%20Rules-921-2ea043.svg" alt="Detection Rules" style="height: 24px;" />
</a>
<br>
<a href="https://github.com/mongodb/kingfisher/pkgs/container/kingfisher">
@ -17,7 +17,7 @@
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 800+ 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 921 built-in rules** to detect, **validate**, and triage leaked API keys, tokens, and credentials before they ever reach production.
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,9 +49,9 @@ Kingfisher is a high-performance, open source secret detection tool for source c
</div>
### Performance, Accuracy, and 800+ Rules
### Performance, Accuracy, and 921 Rules
- **Performance**: multithreaded, Hyperscanpowered scanning built for huge codebases
- **Extensible rules**: 800+ built-in rules plus YAML-defined custom rules ([docs/RULES.md](/docs/RULES.md))
- **Extensible rules**: 921 built-in rules 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).
@ -345,7 +345,7 @@ gh attestation verify kingfisher-linux-x64.tgz --repo mongodb/kingfisher
# Detection Rules
Kingfisher ships with [800+ 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 [921 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 |
|----------|---------------|
@ -362,7 +362,7 @@ Kingfisher ships with [800+ built-in rules](crates/kingfisher-rules/data/rules/)
## Write Custom Rules
Kingfisher ships with 800+ rules with HTTP and servicespecific validation checks (AWS, Azure, GCP, etc.) to confirm if a detected string is a live credential.
Kingfisher ships with 921 rules with HTTP and servicespecific 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.

View file

@ -3,8 +3,9 @@ rules:
id: kingfisher.alibabacloud.1
pattern: |
(?x)
\b
(
LTAI([a-zA-Z0-9]{12,20})
LTAI[A-Za-z0-9]{17,21}
)
\b
pattern_requirements:
@ -25,8 +26,12 @@ rules:
pattern: |
(?x)
\b
(?i:alibaba|alibaba[\s_-]*cloud|aliyun)
(?:.|[\n\r]){0,40}?
(?:
(?i:alibaba|alibaba[\s_-]*cloud|aliyun)
|
LTAI[A-Za-z0-9]{17,21}
)
(?:.|[\n\r]){0,80}?
(?i:access[\s_-]*key[\s_-]*secret|access[\s_-]*secret|secret|token|key)
(?:.|[\n\r]){0,16}?
(?:
@ -46,6 +51,7 @@ rules:
examples:
- alibaba_secret = 7jkWdTjKLnSlGddwPR5gBn65PHcZG6
- alibaba-token = aJHKLnSlGddwPR5g7jkWdTBn65PHc5
- AccessKeyId=LTAI8x2NiGqfyJGx7eLDhp12 AccessKeySecret=7jkWdTjKLnSlGddwPR5gBn65PHcZG6
validation:
type: Http
content:
@ -81,4 +87,119 @@ rules:
- https://www.alibabacloud.com/help/en/ram/latest/create-an-accesskey-pair
depends_on_rule:
- rule_id: kingfisher.alibabacloud.1
variable: AKID
variable: AKID
- name: Alibaba STS Access Key ID
id: kingfisher.alibabacloud.3
pattern: |
(?x)
\b
(
STS\.[A-Za-z0-9]{16,64}
)
\b
min_entropy: 3.0
confidence: medium
visible: false
examples:
- STS.NTKaenSkmLhG4HpM576UV
- STS.FJ6EMcS1JLZgAcBJSTDG1Z4CE
references:
- https://www.alibabacloud.com/help/en/openapi/credentials
- https://www.alibabacloud.com/help/en/ram/developer-reference/api-sts-2015-04-01-assumerole
- name: Alibaba STS Security Token
id: kingfisher.alibabacloud.4
pattern: |
(?xi)
\b
(?:security[\s_-]*token|sts[\s_-]*token|x[\s_-]*oss[\s_-]*security[\s_-]*token|alibaba[\s_-]*cloud[\s_-]*security[\s_-]*token|aliyun[\s_-]*security[\s_-]*token)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
CAIS[A-Za-z0-9+/_=-]{20,1024}
)
(?:["'\s,;}&\]]|$)
min_entropy: 4.0
confidence: medium
visible: false
examples:
- securityToken = "CAISuwJ1q6Ft5B2yu9Kiaa5E0VnVJ8q2o3P4r5S6t7U8v9W0xYz"
- ALIBABA_CLOUD_SECURITY_TOKEN=CAIS/gF1q6Ft5B2yfSjIr5eDA9xjJCcl57eKC7A3ThnJA
references:
- https://www.alibabacloud.com/help/en/openapi/credentials
- https://www.alibabacloud.com/help/en/ram/developer-reference/api-sts-2015-04-01-assumerole
- name: Alibaba STS Access Key Secret
id: kingfisher.alibabacloud.5
pattern: |
(?x)
\b
(?:
(?i:alibaba|alibaba[\s_-]*cloud|aliyun|sts)
|
STS\.[A-Za-z0-9]{16,64}
)
(?:.|[\n\r]){0,120}?
(?i:access[\s_-]*key[\s_-]*secret|access[\s_-]*secret)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
[A-Za-z0-9]{30,64}
)
\b
["']?
min_entropy: 4.2
confidence: medium
examples:
- STS.NTKaenSkmLhG4HpM576UV AccessKeySecret=wyLTSmsyPGP1ohvvw8xYgB29dlGI8KMiH2pK
- "aliyun sts access_key_secret: 6itECZnhbG2RU6ktTSBSd6JxeLHKPWyBtSS62"
validation:
type: Http
content:
request:
method: GET
url: >
{%- assign nonce = "" | uuid | upcase -%}
{%- assign raw_timestamp = "" | iso_timestamp_no_frac -%}
{%- assign timestamp = raw_timestamp | replace: ":", "%3A" -%}
{%- capture params -%}
AccessKeyId={{ STS_AKID | url_encode }}&Action=GetCallerIdentity&Format=JSON&SecurityToken={{ SECURITY_TOKEN | url_encode }}&SignatureMethod=HMAC-SHA1&SignatureNonce={{ nonce }}&SignatureVersion=1.0&Timestamp={{ timestamp }}&Version=2015-04-01
{%- endcapture -%}
{%- assign encoded_params = params | replace: "+", "%20" | replace: "*", "%2A" | replace: "%7E", "~" -%}
{%- assign query_string = encoded_params | url_encode | replace: "%2D", "-" | replace: "%2E", "." -%}
{%- assign signature_base_string = "GET&%2F&" | append: query_string -%}
{%- assign token_amp = TOKEN | append: "&" -%}
{%- assign hmacsignature = signature_base_string | hmac_sha1: token_amp | url_encode -%}
https://sts.aliyuncs.com/?{{ params }}&Signature={{ hmacsignature }}
headers:
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words: ['"Arn"']
references:
- https://www.alibabacloud.com/help/en/openapi/credentials
- https://www.alibabacloud.com/help/en/nas/request-signatures
- https://www.alibabacloud.com/help/en/ram/developer-reference/api-sts-2015-04-01-getcalleridentity
- https://www.alibabacloud.com/help/en/ram/developer-reference/api-sts-2015-04-01-assumerole
depends_on_rule:
- rule_id: kingfisher.alibabacloud.3
variable: STS_AKID
- rule_id: kingfisher.alibabacloud.4
variable: SECURITY_TOKEN

View file

@ -0,0 +1,23 @@
rules:
- name: Builder.io Private API Key
id: kingfisher.builderio.1
pattern: |
(?x)
\b
(
bpk-[a-f0-9]{32}
)
\b
pattern_requirements:
min_digits: 2
min_lowercase: 2
min_entropy: 3.5
confidence: medium
examples:
- 'BUILDER_PRIVATE_KEY=bpk-326204939cb941afb1431bf19bdc007d'
- 'builder_key: "bpk-7e3094a4265949f69b98a02b80e82cb8"'
- 'bpk-3d990a73da74423ca9ac00b9a2cf0f08'
references:
- https://www.builder.io/c/docs/using-your-api-key
- https://www.builder.io/c/docs/write-api
# No validation: documented Private API Key endpoints are mutating Write API calls.

View file

@ -0,0 +1,35 @@
rules:
- name: ButterCMS API Key
id: kingfisher.buttercms.1
pattern: |
(?xi)
\b(?:butter(?:cms|_cms))
(?:.|[\n\r]){0,32}?
(?:API[_-]?(?:KEY|TOKEN)|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[a-z0-9]{40}
)
\b
pattern_requirements:
min_digits: 3
min_entropy: 3.5
confidence: medium
examples:
- 'BUTTERCMS_API_TOKEN=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0'
references:
- https://buttercms.com/docs/api/
validation:
type: Http
content:
request:
method: GET
url: "https://api.buttercms.com/v2/posts/?auth_token={{ TOKEN }}&page_size=1"
headers:
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,62 @@
rules:
- name: Censys API ID
id: kingfisher.censys.1
visible: false
pattern: |
(?xi)
\b
censys
(?:.|[\n\r]){0,32}?
(?:API[_-]?ID|APP[_-]?ID|ID)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'CENSYS_API_ID=a1b2c3d4-e5f6-7890-abcd-ef1234567890'
- name: Censys API Secret
id: kingfisher.censys.2
pattern: |
(?xi)
\b
censys
(?:.|[\n\r]){0,32}?
(?:SECRET|API[_-]?SECRET|KEY|TOKEN)
(?:.|[\n\r]){0,16}?
\b
(
[A-Za-z0-9]{32}
)
\b
pattern_requirements:
min_digits: 3
min_uppercase: 3
min_lowercase: 3
min_entropy: 3.5
confidence: medium
examples:
- 'CENSYS_API_SECRET=aBcDeFgHiJkLmNoPqRsTuVwXyZ012345'
references:
- https://search.censys.io/api
depends_on_rule:
- rule_id: kingfisher.censys.1
variable: CENSYS_API_ID
validation:
type: Http
content:
request:
method: GET
url: https://search.censys.io/api/v1/account
headers:
Accept: application/json
Authorization: "Basic {{ CENSYS_API_ID | append: ':' | append: TOKEN | b64enc }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,40 @@
rules:
- name: ChartMogul API Key
id: kingfisher.chartmogul.1
pattern: |
(?xi)
\b
chartmogul
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[a-z0-9]{32}
)
\b
pattern_requirements:
min_digits: 3
min_entropy: 3.5
confidence: medium
examples:
- 'CHARTMOGUL_API_KEY=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
references:
- https://dev.chartmogul.com/reference/authentication
validation:
type: Http
content:
request:
method: GET
url: https://api.chartmogul.com/v1/ping
headers:
Accept: application/json
Authorization: "Basic {{ TOKEN | append: ':' | b64enc }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- type: WordMatch
words:
- '"pong"'

View file

@ -0,0 +1,39 @@
rules:
- name: ClickUp Personal API Token
id: kingfisher.clickup.1
pattern: |
(?xi)
\b
clickup
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
pk_[0-9]{7,9}_[0-9A-Z]{32}
)
\b
pattern_requirements:
min_digits: 8
min_uppercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'CLICKUP_API_TOKEN=pk_4753994_EXP7MPOJ7XQM5UJDV2M45MPF0YHH5YHO'
- 'clickup_token: "pk_12345678_A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6"'
references:
- https://clickup.com/api/
validation:
type: Http
content:
request:
method: GET
url: https://api.clickup.com/api/v2/user
headers:
Accept: application/json
Authorization: "{{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,35 @@
rules:
- name: Close CRM API Key
id: kingfisher.closecrm.1
pattern: |
(?xi)
\b
(
api_[A-Za-z0-9]{18,26}\.[A-Za-z0-9]{18,26}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 2
min_lowercase: 2
min_entropy: 3.5
confidence: medium
examples:
- 'CLOSE_API_KEY=api_7b8KOSMa0OevK9qJvT6F9s.2H3Bt8ktGaQ9kVK45P7j7p'
- 'close_key: "api_aBcDeFgHiJkLmNoPqRsT.uVwXyZ0123456789abcD"'
references:
- https://developer.close.com/
validation:
type: Http
content:
request:
method: GET
url: https://api.close.com/api/v1/me/
headers:
Accept: application/json
Authorization: "Basic {{ TOKEN | append: ':' | b64enc }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,69 @@
rules:
- name: ConfigCat SDK Key
id: kingfisher.configcat.1
pattern: |
(?xi)
\b
configcat
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|SECRET|TOKEN|KEY)
[\s:=}"']{1,16}
(
[A-Za-z0-9_-]{22}/[A-Za-z0-9_-]{22}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 2
min_lowercase: 2
min_entropy: 3.5
confidence: medium
examples:
- 'CONFIGCAT_SDK_KEY=PKDVCLf-Hq-h-kCzMp-L7Q/psuH7BGHoUmdONrzzUOY7A'
- 'configcat_key: "PKDVCLf-Hq-h-kCzMp-L7Q/psuH7BGHoUmdONrzzUOY7A"'
references:
- https://configcat.com/docs/sdk-reference/overview/
validation:
type: Http
content:
request:
method: GET
url: "https://cdn-global.configcat.com/configuration-files/{{ TOKEN }}/config_v6.json"
headers:
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- name: ConfigCat SDK Key (Extended)
id: kingfisher.configcat.2
pattern: |
(?xi)
\b
(
configcat-sdk-1/[A-Za-z0-9_-]{22}/[A-Za-z0-9_-]{22}
)
\b
pattern_requirements:
min_digits: 2
min_entropy: 3.5
confidence: medium
examples:
- 'CONFIGCAT_SDK_KEY=configcat-sdk-1/PKDVCLf-Hq-h-kCzMp-L7Q/psuH7BGHoUmdONrzzUOY7A'
references:
- https://configcat.com/docs/sdk-reference/overview/
validation:
type: Http
content:
request:
method: GET
url: "https://cdn-global.configcat.com/configuration-files/{{ TOKEN }}/config_v6.json"
headers:
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,37 @@
rules:
- name: Detectify API Key
id: kingfisher.detectify.1
pattern: |
(?xi)
\b
detectify
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
)
\b
pattern_requirements:
min_digits: 4
min_entropy: 3.5
confidence: medium
examples:
- 'DETECTIFY_API_KEY=2230dbea-051a-47f1-bc1d-c1b73b609420'
references:
- https://developer.detectify.com/
validation:
type: Http
content:
request:
method: GET
url: https://api.detectify.com/rest/v3/ips?limit=1
headers:
Accept: application/json
Authorization: "{{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,50 @@
rules:
- name: Ghost CMS Admin API Key
id: kingfisher.ghost.1
pattern: |
(?xi)
\b
ghost
(?:.|[\n\r]){0,32}?
(?:ADMIN|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-f]{24}:[0-9a-f]{64}
)
\b
pattern_requirements:
min_digits: 4
min_lowercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'GHOST_ADMIN_API_KEY=1efedd9db174adee2d23d982:4b74dca0219bad629852191af326a45037346c2231240e0f7aec1f9371cc14e8'
- 'ghost_key = "6101c750c9d0ab0e34567890:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"'
references:
- https://ghost.org/docs/admin-api/
- https://ghost.org/docs/admin-api/#token-authentication
- name: Ghost CMS Content API Key
id: kingfisher.ghost.2
pattern: |
(?xi)
\b(?:ghost|content[_-]?api)
(?:.|[\n\r]){0,48}?
(?:KEY|TOKEN|SECRET|API)
(?:.|[\n\r]){0,24}?
\b
(
[0-9a-f]{26}
)
\b
pattern_requirements:
min_digits: 3
min_entropy: 3.0
confidence: medium
examples:
- 'GHOST_CONTENT_API_KEY=22444f78447824223cefc48062'
- 'ghost_api_key: "a1b2c3d4e5f6a7b8c9d0e1f2a3"'
references:
- https://ghost.org/docs/content-api/
# No validation: Ghost Content API keys are site-specific and require the Ghost site URL.

View file

@ -0,0 +1,39 @@
rules:
- name: Hetzner Cloud API Token
id: kingfisher.hetzner.1
pattern: |
(?xi)
\b(?:hetzner|hcloud)
(?:.|[\n\r]){0,48}?
(?:API[_-]?TOKEN|TOKEN|SECRET|KEY)
(?:.|[\n\r]){0,24}?
\b
(
[A-Za-z0-9]{64}
)
\b
pattern_requirements:
min_digits: 3
min_uppercase: 3
min_lowercase: 3
min_entropy: 4.0
confidence: medium
examples:
- 'HETZNER_API_TOKEN=CqM049yakVZO8EndHyyawia3EjIboWMVeoEeMW0UVN0SpTXryKh0zrtnGpeyAjTs'
- 'HCLOUD_TOKEN=aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789aBcDeFgHiJkLmNoPqRsTuVwXy012'
references:
- https://docs.hetzner.cloud/
validation:
type: Http
content:
request:
method: GET
url: https://api.hetzner.cloud/v1/servers?per_page=1
headers:
Accept: application/json
Authorization: "Bearer {{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,52 @@
rules:
- name: LiveKit API Key
id: kingfisher.livekit.1
visible: false
pattern: |
(?xi)
\b(?:livekit|LIVEKIT)
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|KEY|ACCESS)
(?:.|[\n\r]){0,16}?
\b
(
API[A-Za-z0-9]{12}
)
\b
pattern_requirements:
min_digits: 1
min_uppercase: 3
min_entropy: 2.5
confidence: medium
examples:
- 'LIVEKIT_API_KEY=APIa3B4c5D6e7F8'
- 'livekit_key: "API2K4m6N8p3R5s"'
references:
- https://docs.livekit.io/home/get-started/authentication/
- name: LiveKit API Secret
id: kingfisher.livekit.2
pattern: |
(?xi)
\b(?:livekit|LIVEKIT)
(?:.|[\n\r]){0,32}?
(?:SECRET|PRIVATE|ACCESS)
(?:.|[\n\r]){0,16}?
\b
(
[A-Za-z0-9]{40,48}
)
\b
pattern_requirements:
min_digits: 3
min_uppercase: 3
min_lowercase: 3
min_entropy: 4.0
confidence: medium
examples:
- 'LIVEKIT_API_SECRET=aBcDeFgHiJkLmNoPqRsTuVwXyZ01234567890abcde'
references:
- https://docs.livekit.io/home/get-started/authentication/
depends_on_rule:
- rule_id: kingfisher.livekit.1
variable: LIVEKIT_API_KEY

View file

@ -0,0 +1,41 @@
rules:
- name: Loops Email API Key
id: kingfisher.loops.1
pattern: |
(?xi)
\b
loops
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-f]{32}
)
\b
pattern_requirements:
min_digits: 3
min_entropy: 3.5
confidence: medium
examples:
- 'LOOPS_API_KEY=d2d561f5ff80136f69b4b5a31b9fb3c9'
references:
- https://loops.so/docs/api-reference/intro
validation:
type: Http
content:
request:
method: GET
url: https://app.loops.so/api/v1/api-key
headers:
Accept: application/json
Authorization: "Bearer {{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words:
- '"success"'
- 'true'
match_all_words: true

View file

@ -0,0 +1,39 @@
rules:
- name: Moralis API Key
id: kingfisher.moralis.1
pattern: |
(?xi)
\b
moralis
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|SECRET|TOKEN|KEY|WEB3)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-zA-Z]{64}
)
\b
pattern_requirements:
min_digits: 3
min_uppercase: 3
min_lowercase: 3
min_entropy: 4.0
confidence: medium
examples:
- 'MORALIS_API_KEY=aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789aBcDeFgHiJkLmNoPqRsTuVwXy012'
references:
- https://docs.moralis.io/web3-data-api/evm/reference
validation:
type: Http
content:
request:
method: GET
url: https://deep-index.moralis.io/api/v2.2/web3/version
headers:
Accept: application/json
X-API-Key: "{{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,38 @@
rules:
- name: PandaDoc API Key
id: kingfisher.pandadoc.1
pattern: |
(?xi)
\b(?:pandadoc)
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[a-zA-Z0-9]{40}
)
\b
pattern_requirements:
min_digits: 3
min_uppercase: 3
min_lowercase: 3
min_entropy: 3.5
confidence: medium
examples:
- 'PANDADOC_API_KEY=aBcDeFgHiJkLmNoPqRsTuVwXyZ01234567890abc'
references:
- https://developers.pandadoc.com/reference/about
validation:
type: Http
content:
request:
method: GET
url: https://api.pandadoc.com/public/v1/documents?count=1
headers:
Accept: application/json
Authorization: "API-Key {{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,35 @@
rules:
- name: Permit.io API Key
id: kingfisher.permitio.1
pattern: |
(?x)
\b
(
permit_key_[0-9A-Za-z]{85,86}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 2
min_lowercase: 2
min_entropy: 3.5
confidence: medium
examples:
- 'PERMIT_API_KEY=permit_key_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVW'
- 'permit_key: "permit_key_9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA9876543210zyxwvutsrqponm"'
references:
- https://docs.permit.io/overview/get-api-key/
validation:
type: Http
content:
request:
method: GET
url: https://api.permit.io/v2/api-key/scope
headers:
Accept: application/json
Authorization: "Bearer {{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,66 @@
rules:
- name: Pinata API Key
id: kingfisher.pinata.1
visible: false
pattern: |
(?xi)
\b
pinata
(?:.|[\n\r]){0,32}?
(?:API[_-]?KEY|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-f]{64}
)
\b
pattern_requirements:
min_digits: 4
min_entropy: 3.5
confidence: medium
examples:
- 'PINATA_API_KEY=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2'
- name: Pinata API Secret
id: kingfisher.pinata.2
pattern: |
(?xi)
\b
pinata
(?:.|[\n\r]){0,32}?
(?:API[_-]?SECRET|SECRET[_-]?KEY|SECRET)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-f]{64}
)
\b
pattern_requirements:
min_digits: 4
min_entropy: 3.5
confidence: medium
examples:
- 'PINATA_API_SECRET=f0e1d2c3b4a5f6e7d8c9b0a1f2e3d4c5b6a7f8e9d0c1b2a3f4e5d6c7b8a9f0e1'
references:
- https://docs.pinata.cloud/api-reference/introduction
depends_on_rule:
- rule_id: kingfisher.pinata.1
variable: PINATA_API_KEY
validation:
type: Http
content:
request:
method: GET
url: https://api.pinata.cloud/data/testAuthentication
headers:
Accept: application/json
pinata_api_key: "{{ PINATA_API_KEY }}"
pinata_secret_api_key: "{{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words:
- '"message"'
- 'Congratulations'

View file

@ -0,0 +1,22 @@
rules:
- name: Portainer API Token
id: kingfisher.portainer.1
pattern: |
(?x)
\b
(
ptr_[A-Za-z0-9/+_=-]{32,52}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 2
min_lowercase: 2
min_entropy: 3.5
confidence: medium
examples:
- 'PORTAINER_API_KEY=ptr_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345678901'
- 'portainer_token: "ptr_xY9zW8vU7tS6rQ5pN4mL3kJ2iH1gF0eD9cB8aZ7"'
references:
- https://docs.portainer.io/api/access
# No validation: Portainer API tokens require the user's Portainer server URL.

View file

@ -0,0 +1,21 @@
rules:
- name: Robinhood Crypto API Key
id: kingfisher.robinhood.1
pattern: |
(?x)
\b
(
rh-api-
[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}
)
\b
pattern_requirements:
min_digits: 4
min_entropy: 3.0
confidence: medium
examples:
- 'ROBINHOOD_API_KEY=rh-api-a1b2c3d4-e5f6-7890-abcd-ef1234567890'
- 'rh_api_key: "rh-api-12345678-abcd-ef01-2345-6789abcdef01"'
references:
- https://docs.robinhood.com/crypto/trading/
# No validation: Robinhood Crypto requests require an API key plus Ed25519 request signing.

View file

@ -0,0 +1,34 @@
rules:
- name: SaladCloud API Key
id: kingfisher.saladcloud.1
pattern: |
(?x)
\b
(
salad_cloud_[0-9A-Za-z]{1,7}_[0-9A-Za-z]{7,40}
)
\b
pattern_requirements:
min_digits: 2
min_lowercase: 4
min_entropy: 3.0
confidence: medium
examples:
- 'SALAD_API_KEY=salad_cloud_abc1234_xY9zW8vU7tS6rQ5pN4mL3kJ2iH1gF0e'
- 'salad_key: "salad_cloud_org42_a1B2c3D4e5F6g7H8i9J0"'
references:
- https://docs.salad.com/reference/api-reference
validation:
type: Http
content:
request:
method: GET
url: https://api.salad.com/api/public/organizations
headers:
Accept: application/json
Salad-Api-Key: "{{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,45 @@
rules:
- name: Tigris Access Key ID
id: kingfisher.tigris.1
visible: false
pattern: |
(?x)
\b
(
tid_[A-Za-z0-9_]{43,55}
)
\b
pattern_requirements:
min_uppercase: 4
min_lowercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'TIGRIS_ACCESS_KEY=tid_zkrUeBLpqV_TOdaZzjYefcGEZJrZJqQHvmidyMx_VJtknmcWhC'
- 'AWS_ACCESS_KEY_ID=tid_sIYWNboOecJPzFPmgbOmxsfSqjwbmYmSoGAlrylliULbhiysCJ'
references:
- https://www.tigrisdata.com/docs/concepts/authnz/
- name: Tigris Secret Access Key
id: kingfisher.tigris.2
pattern: |
(?xi)
\b
(
tsec_[A-Za-z0-9_]{43,55}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 4
min_lowercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'TIGRIS_SECRET_KEY=tsec_pQrStUvWxYzAbCdEfGhIjKlMnOpQrStUvWxYz_012345678aB'
- 'AWS_SECRET_ACCESS_KEY=tsec_mNbVcXzAsWqErTyUiOpLkJhGfDsAzXcVbNmQwErTyUi_9876'
references:
- https://www.tigrisdata.com/docs/concepts/authnz/
depends_on_rule:
- rule_id: kingfisher.tigris.1
variable: TIGRIS_ACCESS_KEY

View file

@ -0,0 +1,52 @@
rules:
- name: Unleash Client/Admin API Token
id: kingfisher.unleash.1
pattern: |
(?xi)
\b
unleash
(?:.|[\n\r]){0,32}?
(?:API[_-]?TOKEN|CLIENT[_-]?KEY|ADMIN[_-]?TOKEN|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
(
(?:\*|\[\]|[a-z][a-z0-9-]*)
:
[a-z][a-z0-9-]*
\.
[0-9a-f]{56}
)
\b
pattern_requirements:
min_digits: 4
min_lowercase: 10
min_entropy: 3.0
confidence: medium
examples:
- 'UNLEASH_API_TOKEN=default:development.be44368985f7fb3237c584ef86f3d6bdada42ddbd63a019d26955178'
- 'unleash_token: "*:production.a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8"'
references:
- https://docs.getunleash.io/reference/api-tokens-and-client-keys
- name: Unleash Personal Access Token
id: kingfisher.unleash.2
pattern: |
(?xi)
\b
unleash
(?:.|[\n\r]){0,32}?
(?:PAT|PERSONAL[_-]?ACCESS[_-]?TOKEN|API[_-]?TOKEN|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
user:[0-9a-f]{56}
)
\b
pattern_requirements:
min_digits: 4
min_entropy: 3.5
confidence: medium
examples:
- 'UNLEASH_PAT=user:be7536c3a160ff15e3a92da45de531dd54bc1ae15d8455c0476f086b'
- 'unleash_pat: "user:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8"'
references:
- https://docs.getunleash.io/reference/api-tokens-and-client-keys

View file

@ -0,0 +1,35 @@
rules:
- name: UpCloud API Token
id: kingfisher.upcloud.1
pattern: |
(?xi)
\b
(
ucat_[0-9A-HJKMNP-TV-Z]{26}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'UPCLOUD_API_TOKEN=ucat_01DQE3AJDEBFEKECFM558TGH2F'
- 'upcloud_token: "ucat_01J9K4BNZM3RGXW7VDQFTHY5PC"'
references:
- https://upcloud.com/docs/guides/managing-api-tokens/
- https://developers.upcloud.com/1.3/24-api-tokens/
validation:
type: Http
content:
request:
method: GET
url: https://api.upcloud.com/1.3/account
headers:
Accept: application/json
Authorization: "Bearer {{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,43 @@
rules:
- name: Voiceflow API Key
id: kingfisher.voiceflow.1
pattern: |
(?xi)
\b
(
VF\.(?:(?:DM|WS)\.)
[0-9a-f]{24}
\.
[0-9a-zA-Z]{16}
)
\b
pattern_requirements:
min_digits: 3
min_lowercase: 4
min_entropy: 3.0
confidence: medium
examples:
- 'VOICEFLOW_API_KEY=VF.DM.6421e3d5b1e4a9001d2b7c8f.a1B2c3D4e5F6g7H8'
- 'voiceflow_key: "VF.WS.53a1b2c3d4e5f6001a2b3c4d.xY9zW8vU7tS6rQ5p"'
references:
- https://developer.voiceflow.com/reference/overview
validation:
type: Http
content:
request:
method: POST
url: https://general-runtime.voiceflow.com/knowledge-base/query
headers:
Accept: application/json
Authorization: "{{ TOKEN }}"
Content-Type: application/json
body: |
{"question": "test"}
response_matcher:
- report_response: true
- type: StatusMatch
status: [200, 400, 404]
- type: WordMatch
negative: true
words:
- '"Unauthorized"'

View file

@ -0,0 +1,36 @@
rules:
- name: Wistia API Token
id: kingfisher.wistia.1
pattern: |
(?xi)
\b
wistia
(?:.|[\n\r]){0,32}?
(?:API[_-]?(?:KEY|TOKEN|PASSWORD)|TOKEN|SECRET|KEY)
(?:.|[\n\r]){0,16}?
\b
(
[0-9a-f]{64}
)
\b
pattern_requirements:
min_digits: 4
min_entropy: 3.5
confidence: medium
examples:
- 'WISTIA_API_TOKEN=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2'
references:
- https://wistia.com/support/developers/data-api
validation:
type: Http
content:
request:
method: GET
url: "https://api.wistia.com/v1/account.json?api_password={{ TOKEN }}"
headers:
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,40 @@
rules:
- name: ZeroTier API Token
id: kingfisher.zerotier.1
pattern: |
(?xi)
\b
(?:zerotier|zt)
(?:.|[\n\r]){0,32}?
(?:API[_-]?(?:TOKEN|KEY)|TOKEN|SECRET|KEY|ACCESS)
(?:.|[\n\r]){0,16}?
\b
(
[A-Za-z0-9]{32}
)
\b
pattern_requirements:
min_digits: 3
min_uppercase: 3
min_lowercase: 3
min_entropy: 3.5
confidence: medium
examples:
- 'ZEROTIER_API_TOKEN=aBcDeFgHiJkLmNoPqRsTuVwXyZ012345'
- 'ZT_TOKEN=xY9zW8vU7tS6rQ5pN4mL3kJ2iH1gF0eD'
references:
- https://docs.zerotier.com/api/tokens/
validation:
type: Http
content:
request:
method: GET
url: https://api.zerotier.com/api/v1/status
headers:
Accept: application/json
Authorization: "token {{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -7,9 +7,13 @@ 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]
## [v1.96.0]
- Added live HTTP validation for 18 rules across 15 providers: Val Town, Polar, hCaptcha, Thunderstore, Elastic Cloud (2 rules), LlamaCloud, Gemfury (2 rules), Vonage, ThingsBoard, Zapier, Facebook Access Token, GitLab Session Cookie, PostHog Feature Flags, Unkey API Key, and Hop.io (2 rules).
- Added revocation support for 7 rules across 6 providers: Discord webhooks (single-step DELETE), DigitalOcean PATs (self-revoke via OAuth), and multi-step HttpMultiStep revocation for LaunchDarkly, Resend, Linode, and Netlify (2 rules). Built-in revocation coverage is now 34 provider families with 53 revocation-enabled rules.
- Expanded Alibaba Cloud coverage with STS temporary credential detection for STS access key IDs, STS security tokens, and STS access key secrets. Built-in rule coverage is now 921 rules total.
- 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`.
## [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

@ -2,7 +2,7 @@
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. 825 detection rules. Built in Rust by MongoDB.
mapping, and credential revocation. 921 detection rules. 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 825 built-in rules for common secret types:
Kingfisher currently ships with 921 built-in rules for common secret types:
```rust
use kingfisher_rules::{get_builtin_rules, Confidence};

File diff suppressed because it is too large Load diff

View file

@ -880,19 +880,23 @@ rules:
## Advanced Example
This advanced example uses the liquid-rs filters included with Kingfisher to sign a request to validate Alibaba Cloud credential pairs:
This advanced example uses the liquid-rs filters included with Kingfisher to sign requests that validate Alibaba Cloud long-lived and STS temporary credential pairs:
```yaml
rules:
- name: Alibaba Access Key ID
id: kingfisher.alibabacloud.1
pattern: |
(?xi)
(?x)
\b
(
LTAI[a-z0-9]{17,21}
LTAI[A-Za-z0-9]{17,21}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 1
min_lowercase: 1
min_entropy: 4.0
confidence: medium
visible: false
@ -902,20 +906,34 @@ rules:
- name: Alibaba Access Key Secret
id: kingfisher.alibabacloud.2
pattern: |
(?xi)
\b
alibaba
(?:.|[\n\r]){0,32}?
(?x)
\b
(?:
(?i:alibaba|alibaba[\s_-]*cloud|aliyun)
|
LTAI[A-Za-z0-9]{17,21}
)
(?:.|[\n\r]){0,80}?
(?i:access[\s_-]*key[\s_-]*secret|access[\s_-]*secret|secret|token|key)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
[a-z0-9]{30}
[A-Za-z0-9]{30}
)
\b
["']?
min_entropy: 4.2
confidence: medium
examples:
- alibaba_secret = 7jkWdTjKLnSlGddwPR5gBn65PHcZG6
- alibaba-token = aJHKLnSlGddwPR5g7jkWdTBn65PHc5
- AccessKeyId=LTAI8x2NiGqfyJGx7eLDhp12 AccessKeySecret=7jkWdTjKLnSlGddwPR5gBn65PHcZG6
validation:
type: Http
content:
@ -949,4 +967,108 @@ rules:
depends_on_rule:
- rule_id: kingfisher.alibabacloud.1
variable: AKID
- name: Alibaba STS Access Key ID
id: kingfisher.alibabacloud.3
pattern: |
(?x)
\b
(
STS\.[A-Za-z0-9]{16,64}
)
\b
min_entropy: 3.0
confidence: medium
visible: false
examples:
- STS.NTKaenSkmLhG4HpM576UV
- STS.FJ6EMcS1JLZgAcBJSTDG1Z4CE
- name: Alibaba STS Security Token
id: kingfisher.alibabacloud.4
pattern: |
(?xi)
\b
(?:security[\s_-]*token|sts[\s_-]*token|x[\s_-]*oss[\s_-]*security[\s_-]*token|alibaba[\s_-]*cloud[\s_-]*security[\s_-]*token|aliyun[\s_-]*security[\s_-]*token)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
CAIS[A-Za-z0-9+/_=-]{20,1024}
)
(?:["'\s,;}&\]]|$)
min_entropy: 4.0
confidence: medium
visible: false
examples:
- securityToken = "CAISuwJ1q6Ft5B2yu9Kiaa5E0VnVJ8q2o3P4r5S6t7U8v9W0xYz"
- ALIBABA_CLOUD_SECURITY_TOKEN=CAIS/gF1q6Ft5B2yfSjIr5eDA9xjJCcl57eKC7A3ThnJA
- name: Alibaba STS Access Key Secret
id: kingfisher.alibabacloud.5
pattern: |
(?x)
\b
(?:
(?i:alibaba|alibaba[\s_-]*cloud|aliyun|sts)
|
STS\.[A-Za-z0-9]{16,64}
)
(?:.|[\n\r]){0,120}?
(?i:access[\s_-]*key[\s_-]*secret|access[\s_-]*secret)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
[A-Za-z0-9]{30,64}
)
\b
["']?
min_entropy: 4.2
confidence: medium
examples:
- STS.NTKaenSkmLhG4HpM576UV AccessKeySecret=wyLTSmsyPGP1ohvvw8xYgB29dlGI8KMiH2pK
- "aliyun sts access_key_secret: 6itECZnhbG2RU6ktTSBSd6JxeLHKPWyBtSS62"
validation:
type: Http
content:
request:
method: GET
url: >
{%- assign nonce = "" | uuid | upcase -%}
{%- assign raw_timestamp = "" | iso_timestamp_no_frac -%}
{%- assign timestamp = raw_timestamp | replace: ":", "%3A" -%}
{%- capture params -%}
AccessKeyId={{ STS_AKID | url_encode }}&Action=GetCallerIdentity&Format=JSON&SecurityToken={{ SECURITY_TOKEN | url_encode }}&SignatureMethod=HMAC-SHA1&SignatureNonce={{ nonce }}&SignatureVersion=1.0&Timestamp={{ timestamp }}&Version=2015-04-01
{%- endcapture -%}
{%- assign encoded_params = params | replace: "+", "%20" | replace: "*", "%2A" | replace: "%7E", "~" -%}
{%- assign query_string = encoded_params | url_encode | replace: "%2D", "-" | replace: "%2E", "." -%}
{%- assign signature_base_string = "GET&%2F&" | append: query_string -%}
{%- assign token_amp = TOKEN | append: "&" -%}
{%- assign hmacsignature = signature_base_string | hmac_sha1: token_amp | url_encode -%}
https://sts.aliyuncs.com/?{{ params }}&Signature={{ hmacsignature }}
headers:
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words: ['"Arn"']
depends_on_rule:
- rule_id: kingfisher.alibabacloud.3
variable: STS_AKID
- rule_id: kingfisher.alibabacloud.4
variable: SECURITY_TOKEN
```

View file

@ -300,7 +300,7 @@ kingfisher scan ./my-project \
## Custom Rules
Kingfisher currently ships with 825 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 921 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

@ -1,7 +1,7 @@
site_name: Kingfisher
site_url: https://mongodb.github.io/kingfisher
site_description: >-
Open source secret scanner with live validation. 825 detection rules,
Open source secret scanner with live validation. 921 detection rules,
blast radius mapping, and credential revocation. Built in Rust by MongoDB.
site_author: MongoDB
repo_url: https://github.com/mongodb/kingfisher

View file

@ -36,7 +36,7 @@
<section class="kf-stats">
<div class="kf-stats__inner md-grid">
<div class="kf-stats__item">
<span class="kf-stats__number">825</span>
<span class="kf-stats__number">921</span>
<span class="kf-stats__label">Detection Rules</span>
</div>
<div class="kf-stats__item">
@ -48,7 +48,7 @@
<span class="kf-stats__label">Scan Targets</span>
</div>
<div class="kf-stats__item">
<span class="kf-stats__number">28</span>
<span class="kf-stats__number">34</span>
<span class="kf-stats__label">Revocation Providers</span>
</div>
</div>

View file

@ -7,7 +7,7 @@
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Kingfisher",
"description": "Open source secret scanner with live validation. 825 detection rules, blast radius mapping, and credential revocation.",
"description": "Open source secret scanner with live validation. 921 detection rules, blast radius mapping, and credential revocation.",
"applicationCategory": "DeveloperApplication",
"operatingSystem": "Linux, macOS, Windows",
"license": "https://opensource.org/licenses/Apache-2.0",

View file

@ -297,7 +297,7 @@ kingfisher scan ./my-project \
## Custom Rules
Kingfisher currently ships with 825 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 921 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 825 built-in rules for common secret types:
Kingfisher currently ships with 921 built-in rules for common secret types:
```rust
use kingfisher_rules::{get_builtin_rules, Confidence};

View file

@ -3,8 +3,8 @@
Kingfisher supports direct secret revocation through rule-level `revocation:` blocks.
Current coverage in built-in rules:
- `28` provider families
- `46` revocation-enabled rules
- `34` provider families
- `53` revocation-enabled rules
Use `kingfisher revoke --rule <rule-id> <secret>` to invoke these flows. See [USAGE.md](USAGE.md#direct-secret-revocation-with-kingfisher-revoke) for command details.
@ -19,6 +19,8 @@ Use `kingfisher revoke --rule <rule-id> <secret>` to invoke these flows. See [US
| `confluent` | 2 | `kingfisher.confluent.2`, `kingfisher.confluent.3` |
| `cratesio` | 1 | `kingfisher.cratesio.1` |
| `deviantart` | 1 | `kingfisher.deviantart.1` |
| `digitalocean` | 1 | `kingfisher.digitalocean.1` |
| `discord` | 1 | `kingfisher.discord.1` |
| `doppler` | 6 | `kingfisher.doppler.1`, `kingfisher.doppler.2`, `kingfisher.doppler.3`, `kingfisher.doppler.4`, `kingfisher.doppler.5`, `kingfisher.doppler.6` |
| `gcp` | 1 | `kingfisher.gcp.1` |
| `github` | 3 | `kingfisher.github.1`, `kingfisher.github.2`, `kingfisher.github.5` |
@ -26,10 +28,14 @@ Use `kingfisher revoke --rule <rule-id> <secret>` to invoke these flows. See [US
| `google` | 2 | `kingfisher.google.4`, `kingfisher.google.oauth2.1` |
| `harness` | 1 | `kingfisher.harness.pat.1` |
| `heroku` | 2 | `kingfisher.heroku.1`, `kingfisher.heroku.2` |
| `launchdarkly` | 1 | `kingfisher.launchdarkly.1` |
| `linode` | 1 | `kingfisher.linode.1` |
| `mapbox` | 1 | `kingfisher.mapbox.2` |
| `mongodb` | 1 | `kingfisher.mongodb.1` |
| `netlify` | 2 | `kingfisher.netlify.1`, `kingfisher.netlify.2` |
| `npm` | 2 | `kingfisher.npm.1`, `kingfisher.npm.2` |
| `particle.io` | 2 | `kingfisher.particleio.1`, `kingfisher.particleio.2` |
| `resend` | 1 | `kingfisher.resend.api_key.1` |
| `sendgrid` | 1 | `kingfisher.sendgrid.1` |
| `slack` | 2 | `kingfisher.slack.1`, `kingfisher.slack.2` |
| `sumologic` | 1 | `kingfisher.sumologic.2` |

View file

@ -875,19 +875,23 @@ rules:
## Advanced Example
This advanced example uses the liquid-rs filters included with Kingfisher to sign a request to validate Alibaba Cloud credential pairs:
This advanced example uses the liquid-rs filters included with Kingfisher to sign requests that validate Alibaba Cloud long-lived and STS temporary credential pairs:
```yaml
rules:
- name: Alibaba Access Key ID
id: kingfisher.alibabacloud.1
pattern: |
(?xi)
(?x)
\b
(
LTAI[a-z0-9]{17,21}
LTAI[A-Za-z0-9]{17,21}
)
\b
pattern_requirements:
min_digits: 2
min_uppercase: 1
min_lowercase: 1
min_entropy: 4.0
confidence: medium
visible: false
@ -897,20 +901,34 @@ rules:
- name: Alibaba Access Key Secret
id: kingfisher.alibabacloud.2
pattern: |
(?xi)
\b
alibaba
(?:.|[\n\r]){0,32}?
(?x)
\b
(?:
(?i:alibaba|alibaba[\s_-]*cloud|aliyun)
|
LTAI[A-Za-z0-9]{17,21}
)
(?:.|[\n\r]){0,80}?
(?i:access[\s_-]*key[\s_-]*secret|access[\s_-]*secret|secret|token|key)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
[a-z0-9]{30}
[A-Za-z0-9]{30}
)
\b
["']?
min_entropy: 4.2
confidence: medium
examples:
- alibaba_secret = 7jkWdTjKLnSlGddwPR5gBn65PHcZG6
- alibaba-token = aJHKLnSlGddwPR5g7jkWdTBn65PHc5
- AccessKeyId=LTAI8x2NiGqfyJGx7eLDhp12 AccessKeySecret=7jkWdTjKLnSlGddwPR5gBn65PHcZG6
validation:
type: Http
content:
@ -944,4 +962,108 @@ rules:
depends_on_rule:
- rule_id: kingfisher.alibabacloud.1
variable: AKID
- name: Alibaba STS Access Key ID
id: kingfisher.alibabacloud.3
pattern: |
(?x)
\b
(
STS\.[A-Za-z0-9]{16,64}
)
\b
min_entropy: 3.0
confidence: medium
visible: false
examples:
- STS.NTKaenSkmLhG4HpM576UV
- STS.FJ6EMcS1JLZgAcBJSTDG1Z4CE
- name: Alibaba STS Security Token
id: kingfisher.alibabacloud.4
pattern: |
(?xi)
\b
(?:security[\s_-]*token|sts[\s_-]*token|x[\s_-]*oss[\s_-]*security[\s_-]*token|alibaba[\s_-]*cloud[\s_-]*security[\s_-]*token|aliyun[\s_-]*security[\s_-]*token)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
CAIS[A-Za-z0-9+/_=-]{20,1024}
)
(?:["'\s,;}&\]]|$)
min_entropy: 4.0
confidence: medium
visible: false
examples:
- securityToken = "CAISuwJ1q6Ft5B2yu9Kiaa5E0VnVJ8q2o3P4r5S6t7U8v9W0xYz"
- ALIBABA_CLOUD_SECURITY_TOKEN=CAIS/gF1q6Ft5B2yfSjIr5eDA9xjJCcl57eKC7A3ThnJA
- name: Alibaba STS Access Key Secret
id: kingfisher.alibabacloud.5
pattern: |
(?x)
\b
(?:
(?i:alibaba|alibaba[\s_-]*cloud|aliyun|sts)
|
STS\.[A-Za-z0-9]{16,64}
)
(?:.|[\n\r]){0,120}?
(?i:access[\s_-]*key[\s_-]*secret|access[\s_-]*secret)
(?:.|[\n\r]){0,16}?
(?:
[=:]
|
["']\s*:\s*["']
)
\s*
["']?
(
[A-Za-z0-9]{30,64}
)
\b
["']?
min_entropy: 4.2
confidence: medium
examples:
- STS.NTKaenSkmLhG4HpM576UV AccessKeySecret=wyLTSmsyPGP1ohvvw8xYgB29dlGI8KMiH2pK
- "aliyun sts access_key_secret: 6itECZnhbG2RU6ktTSBSd6JxeLHKPWyBtSS62"
validation:
type: Http
content:
request:
method: GET
url: >
{%- assign nonce = "" | uuid | upcase -%}
{%- assign raw_timestamp = "" | iso_timestamp_no_frac -%}
{%- assign timestamp = raw_timestamp | replace: ":", "%3A" -%}
{%- capture params -%}
AccessKeyId={{ STS_AKID | url_encode }}&Action=GetCallerIdentity&Format=JSON&SecurityToken={{ SECURITY_TOKEN | url_encode }}&SignatureMethod=HMAC-SHA1&SignatureNonce={{ nonce }}&SignatureVersion=1.0&Timestamp={{ timestamp }}&Version=2015-04-01
{%- endcapture -%}
{%- assign encoded_params = params | replace: "+", "%20" | replace: "*", "%2A" | replace: "%7E", "~" -%}
{%- assign query_string = encoded_params | url_encode | replace: "%2D", "-" | replace: "%2E", "." -%}
{%- assign signature_base_string = "GET&%2F&" | append: query_string -%}
{%- assign token_amp = TOKEN | append: "&" -%}
{%- assign hmacsignature = signature_base_string | hmac_sha1: token_amp | url_encode -%}
https://sts.aliyuncs.com/?{{ params }}&Signature={{ hmacsignature }}
headers:
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words: ['"Arn"']
depends_on_rule:
- rule_id: kingfisher.alibabacloud.3
variable: STS_AKID
- rule_id: kingfisher.alibabacloud.4
variable: SECURITY_TOKEN
```

12
json Normal file
View file

@ -0,0 +1,12 @@
DEEPSEEK API KEY => [KINGFISHER.DEEPSEEK.1]
|Finding.......: sk-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
|Fingerprint...: 2802934700551494254
|Confidence....: medium
|Entropy.......: 4.13
|Validation....: Inactive Credential
|__Response....: {"error":{"message":"Authentication Fails, Your api key: ****c5d6 is invalid","type":"authentication_error","param":null,"code":"invalid_request_error"}}
|Validate Cmd..: kingfisher validate --rule kingfisher.deepseek.1 'sk-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6'
|Language......: Plain Text
|Line Num......: 4
|Path..........: /tmp/test_alibaba.txt