added more rules + validators

This commit is contained in:
Mick Grove 2026-04-14 12:52:27 -07:00
commit c7f7adb223
58 changed files with 1773 additions and 10 deletions

View file

@ -2,11 +2,10 @@
All notable changes to this project will be documented in this file.
## [v1.97.0]
- Added live HTTP validation for 12 rules across 10 providers: Val Town, Polar, hCaptcha, Thunderstore, Elastic Cloud (2 rules), LlamaCloud, Gemfury (2 rules), Vonage, ThingsBoard, and Zapier.
- 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.
## [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.
- Added 59 new detection rules across 44 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, 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 28 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]

45
THREAT_MODEL_PROMPT.md Normal file
View file

@ -0,0 +1,45 @@
# Threat Model Prompt (STRIDE)
Perform a practical STRIDE threat model of this system.
**Principles:**
- Only realistic, relevant risks. No generic boilerplate.
- Depth over breadth. Be concrete and opinionated.
- Skip STRIDE categories that aren't meaningfully relevant — say so briefly and move on.
## Step 1: Architecture Summary
Summarize the system in short bullets:
- Purpose
- Main components
- Data flows
- Trust boundaries
- Sensitive assets
## Step 2: STRIDE Analysis
For each relevant threat:
- **STRIDE category**
- **Threat scenario** — specific, not generic
- **Impacted asset / component**
- **Why it matters** — not just "it's bad", but the concrete consequence
- **Severity:** Low / Medium / High / Critical
- **Recommended mitigations**
Focus especially on:
- Authn / authz failures
- Trust boundary crossings
- Secret handling
- Multi-tenant isolation
- Injection / unsafe input handling
- Data exfiltration paths
- Abuse / privilege escalation
- Logging / detection gaps
- Supply chain and execution risks
## Step 3: Prioritized Output
End with:
1. **Top 5 risks to fix first** — ordered by impact, with brief rationale
2. **Assumptions made** — what you assumed about the deployment, environment, or usage
3. **Open questions** — things that, if answered differently, would change the threat model

View file

@ -12,7 +12,7 @@ rules:
)
\b
min_entropy: 3.5
confidence: high
confidence: medium
examples:
- ADAFRUIT_AIO_KEY = "aio_giXk31KzM05IVxHRwJwtpNGClUE5"
validation:

View file

@ -0,0 +1,34 @@
rules:
- name: Aikido CI Token
id: kingfisher.aikido.1
pattern: |
(?x)
\b
(
AIK_CI_[a-zA-Z0-9]{20,44}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'AIKIDO_TOKEN=AIK_CI_a1B2c3D4e5F6g7H8i9J0k1L2'
references:
- https://help.aikido.dev/pr-and-release-gating/cli-for-pr-and-release-gating/aikido-ci-api
validation:
type: Http
content:
request:
method: POST
url: https://app.aikido.dev/api/integrations/ci/scan/start
headers:
X-AIK-API-SECRET: "{{ TOKEN }}"
Content-Type: application/json
body: '{}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [200, 400, 403]
- type: WordMatch
words:
- '"Unauthorized"'
negative: true

View file

@ -14,7 +14,7 @@ rules:
pattern_requirements:
min_digits: 2
min_entropy: 3.0
confidence: high
confidence: medium
visible: false
examples:
- "client-token=akab-sXedJBTOf0dHl27vVOd"

View file

@ -15,7 +15,7 @@ rules:
min_uppercase: 1
min_lowercase: 1
min_entropy: 3.3
confidence: high
confidence: medium
examples:
- sk-ant-api668-Clm512odot9WDD7itfUU9R880nefA1EtYZDbpE-C9b0XQEWpqFKf9DQUo03vOfXl16oSmyar1CLF1SzV3YzpZJ6bahcpLAA
references:

View file

@ -0,0 +1,19 @@
rules:
- name: Arcjet API Key
id: kingfisher.arcjet.1
pattern: |
(?x)
\b
(
ajkey_[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'ARCJET_KEY=ajkey_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'ARCJET_KEY="ajkey_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h"'
references:
- https://docs.arcjet.com/get-started

View file

@ -0,0 +1,61 @@
rules:
- name: Axiom API Token
id: kingfisher.axiom.1
pattern: |
(?x)
\b
(
xaat-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}
)
\b
confidence: medium
examples:
- 'AXIOM_TOKEN=xaat-a1b2c3d4-e5f6-7890-abcd-ef1234567890'
- 'Authorization: Bearer xaat-deadbeef-1234-5678-9abc-def012345678'
references:
- https://axiom.co/docs/reference/tokens
- https://axiom.co/docs/restapi/endpoints/getDatasets
validation:
type: Http
content:
request:
method: GET
url: https://api.axiom.co/v2/datasets
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- name: Axiom Personal Access Token
id: kingfisher.axiom.2
pattern: |
(?x)
\b
(
xapt-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}
)
\b
confidence: medium
examples:
- 'AXIOM_TOKEN=xapt-a1b2c3d4-e5f6-7890-abcd-ef1234567890'
- 'Authorization: Bearer xapt-deadbeef-1234-5678-9abc-def012345678'
references:
- https://axiom.co/docs/reference/tokens
validation:
type: Http
content:
request:
method: GET
url: https://api.axiom.co/v2/datasets
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,40 @@
rules:
- name: Browser Use API Key
id: kingfisher.browseruse.1
pattern: |
(?xi)
\b
(?:browser[-_\s]?use|BROWSER_USE_API_KEY)
(?:.|[\n\r]){0,48}?
\b
(
bu_[A-Za-z0-9_-]{32}(?:[A-Za-z0-9_-]{16}){0,4}
)
\b
pattern_requirements:
min_digits: 4
min_lowercase: 4
min_uppercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'BROWSER_USE_API_KEY="bu_w82Kp7LzR4QnV6tYp9CmX3aSb5DgHjK1"'
- 'browser-use apiKey: "bu_P7rT2mK9vL4qN8sX6cA3dF5gH1jZ0QaB"'
references:
- https://docs.browser-use.com/cloud/quickstart
- https://docs.browser-use.com/llms-full.txt
validation:
type: Http
content:
request:
method: GET
url: https://api.browser-use.com/api/v3/sessions
headers:
X-Browser-Use-API-Key: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
# Revocation is managed from Browser Use Cloud settings; no public key-revocation endpoint is documented.

View file

@ -0,0 +1,34 @@
rules:
- name: Cal.com API Key
id: kingfisher.calcom.1
pattern: |
(?x)
\b
(
cal_live_[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'CAL_API_KEY=cal_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'Authorization: Bearer cal_live_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
references:
- https://cal.com/docs/api-reference/v2/introduction
validation:
type: Http
content:
request:
method: GET
url: https://api.cal.com/v2/me
headers:
Authorization: "Bearer {{ TOKEN }}"
cal-api-version: "2024-08-13"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -11,7 +11,7 @@ rules:
pattern_requirements:
min_digits: 2
min_entropy: 3.5
confidence: high
confidence: medium
categories: [api, key]
examples:
- 'CANVA_CLIENT_SECRET=cnvcaAbCdEfGhIjKlMnOpQrStUvWxYz123456'

View file

@ -20,7 +20,7 @@ rules:
pattern_requirements:
min_digits: 8
min_entropy: 3.5
confidence: high
confidence: medium
examples:
- "new PouchDB(\"https://4f621480-c3c9-41c6-bb2e-38fd4cce291f-bluemix:9a1b75eae487515172acc27e1203bd19d094f359bebb0f20ff69bb173cee3d4a@4f621480-c3c9-41c6-bb2e-38fd4cce291f-bluemix.cloudantnosqldb.appdomain.cloud/mydb\")"
- "CLOUDANT_URL=https://a1b2c3d4-e5f6-7890-abcd-ef1234567890-bluemix:abc123def456789012345678901234567890123456789012345678901234abcd@a1b2c3d4-e5f6-7890-abcd-ef1234567890-bluemix.cloudantnosqldb.appdomain.cloud"

View file

@ -110,3 +110,33 @@ rules:
- 200
type: StatusMatch
url: https://api.cloudflare.com/client/v4/certificates?per_page=1
- name: Cloudflare User API Token (cfut_ prefix)
id: kingfisher.cloudflare.3
pattern: |
(?x)
\b
(
cfut_[a-zA-Z0-9_-]{36,44}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'CF_API_TOKEN=cfut_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9'
references:
- https://developers.cloudflare.com/fundamentals/api/get-started/token-formats/
validation:
type: Http
content:
request:
method: GET
url: https://api.cloudflare.com/client/v4/user/tokens/verify
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,48 @@
rules:
- name: Composio API Key
id: kingfisher.composio.1
pattern: |
(?xi)
\b
(?:composio|COMPOSIO_API_KEY)
(?:.|[\n\r]){0,48}?
\b
(
(?:
comp_[A-Za-z0-9_-]{32}(?:[A-Za-z0-9_-]{16}){0,3}
|
sk_(?:live|test)_[A-Za-z0-9_-]{16}(?:[A-Za-z0-9_-]{16}){0,3}
)
)
\b
pattern_requirements:
min_digits: 2
min_lowercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'COMPOSIO_API_KEY="comp_a7B2c9D4eF6gH8jK1mN3pQ5rS7tV9xY0"'
- 'composio x-api-key: sk_live_Qj7mN4vK8sL2xP6zT9aBcD3eF5gH1jK2'
references:
- https://docs.composio.dev/reference/api-reference/authentication/getAuthSessionInfo
- https://composio.dev/content/secure-ai-agent-infrastructure-guide
validation:
type: Http
content:
request:
method: GET
url: https://backend.composio.dev/api/v3/auth/session/info
headers:
x-api-key: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- type: WordMatch
words:
- '"project"'
- '"api_key"'
match_all_words: true
# Current Composio API docs expose session verification, but not a same-key revocation flow.

View file

@ -0,0 +1,16 @@
rules:
- name: Convex Deploy Key
id: kingfisher.convex.1
pattern: |
(?x)
\b
(
(?:prod|dev|preview):[a-z]+-[a-z]+-\d+\|eyJ[A-Za-z0-9_.-]{50,500}
)
(?:\b|$)
min_entropy: 3.5
confidence: medium
examples:
- 'CONVEX_DEPLOY_KEY=prod:qualified-jaguar-123|eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwMThmNmY5NThmNTI3NjkwYjE1M2NkNDMiLCJpYXQiOjE3MjQ3NzA4MTJ9.bQkJz3sXt'
references:
- https://docs.convex.dev/production/hosting/deploy-key

View file

@ -0,0 +1,33 @@
rules:
- name: Courier API Key
id: kingfisher.courier.1
pattern: |
(?x)
\b
(
(?:pk|dk)_(?:prod|test)_[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'COURIER_API_KEY=pk_prod_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'COURIER_AUTH_TOKEN="dk_test_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h"'
references:
- https://www.courier.com/docs/platform/workspaces/environments-api-keys
validation:
type: Http
content:
request:
method: GET
url: https://api.courier.com/profiles?limit=1
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,55 @@
rules:
- name: Crossmint Server API Key
id: kingfisher.crossmint.1
pattern: |
(?x)
\b
(
sk_(?:staging|production)_[A-Za-z0-9]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'CROSSMINT_SECRET_KEY=sk_production_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'x-api-key: sk_staging_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
references:
- https://docs.crossmint.com/introduction/platform/api-keys
validation:
type: Http
content:
request:
method: GET
url: https://www.crossmint.com/api/v1-alpha2/wallets
headers:
x-api-key: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200, 403]
- type: WordMatch
words:
- '"Unauthorized"'
negative: true
- name: Crossmint Client API Key
id: kingfisher.crossmint.2
pattern: |
(?x)
\b
(
ck_(?:staging|production)_[A-Za-z0-9]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'CROSSMINT_CLIENT_KEY=ck_production_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'ck_staging_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
references:
- https://docs.crossmint.com/introduction/platform/api-keys

View file

@ -0,0 +1,66 @@
rules:
- name: DeepL API Key (Free)
id: kingfisher.deepl.1
pattern: |
(?x)
\b
(
[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}:fx
)
\b
confidence: medium
examples:
- 'DEEPL_API_KEY=279a2e9d-83b3-c416-7e2d-f721593e42a0:fx'
- 'DeepL-Auth-Key 5ef4a0d1-7e1f-47b2-ac0a-1282002aa2a1:fx'
references:
- https://developers.deepl.com/docs/getting-started/auth
validation:
type: Http
content:
request:
method: GET
url: https://api-free.deepl.com/v2/usage
headers:
Authorization: "DeepL-Auth-Key {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- name: DeepL API Key (Pro)
id: kingfisher.deepl.2
pattern: |
(?xi)
deepl
(?:.|[\n\r]){0,32}?
(?:SECRET|AUTH|KEY|TOKEN|API)
(?:.|[\n\r]){0,16}?
\b
(
[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}
)
\b
confidence: medium
examples:
- 'DEEPL_AUTH_KEY=279a2e9d-83b3-c416-7e2d-f721593e42a0'
- 'deepl_api_key: "5ef4a0d1-7e1f-47b2-ac0a-1282002aa2a1"'
negative_examples:
- 'SOME_UUID=279a2e9d-83b3-c416-7e2d-f721593e42a0'
references:
- https://developers.deepl.com/docs/getting-started/auth
validation:
type: Http
content:
request:
method: GET
url: https://api.deepl.com/v2/usage
headers:
Authorization: "DeepL-Auth-Key {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,33 @@
rules:
- name: Dub.co API Key
id: kingfisher.dub.1
pattern: |
(?x)
\b
(
dub_[A-Za-z0-9]{24,36}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'DUB_API_KEY=dub_a1b2c3d4e5f6g7h8i9j0k1l2'
- 'Authorization: Bearer dub_xK8m2LpQr5nW0vYz3cJ7aB4d'
references:
- https://dub.co/docs/api-reference/tokens
validation:
type: Http
content:
request:
method: GET
url: https://api.dub.co/me
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,34 @@
rules:
- name: E2B API Key
id: kingfisher.e2b.1
pattern: |
(?x)
\b
(
e2b_[A-Za-z0-9]{32,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'E2B_API_KEY=e2b_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'X-API-Key: e2b_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8hI9'
references:
- https://e2b.dev/docs/getting-started/api-key
- https://e2b.dev/docs/api-reference/sandboxes/list-sandboxes
validation:
type: Http
content:
request:
method: GET
url: https://api.e2b.dev/sandboxes
headers:
X-API-Key: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -95,3 +95,16 @@ rules:
- 'FACEBOOK_ACCESS_TOKEN=EAACEdEose0cBAZAQW123456789abcdefghijklmnopqrstuvwxyzASDFGHJKL'
references:
- https://developers.facebook.com/docs/facebook-login/access-tokens/
validation:
type: Http
content:
request:
method: GET
url: "https://graph.facebook.com/me?access_token={{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words:
- '"id"'

View file

@ -0,0 +1,18 @@
rules:
- name: Fal.ai API Key
id: kingfisher.falai.1
pattern: |
(?x)
\b
(
fal_sk_[a-zA-Z0-9_-]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'FAL_KEY=fal_sk_a1B2c3D4e5F6g7H8i9J0k1L2m3N4'
references:
- https://docs.fal.ai/platform-apis/v1/keys/create

View file

@ -0,0 +1,35 @@
rules:
- name: Flagsmith Server-Side Environment Key
id: kingfisher.flagsmith.1
pattern: |
(?x)
\b
(
ser\.[A-Za-z0-9]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_uppercase: 1
min_lowercase: 1
min_entropy: 3.0
confidence: medium
examples:
- 'FLAGSMITH_SERVER_SIDE_ENVIRONMENT_KEY=ser.xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
- 'X-Environment-Key: ser.a1b2C3d4E5f6G7h8I9j0K1l2'
references:
- https://docs.flagsmith.com/clients/server-side
validation:
type: Http
content:
request:
method: GET
url: https://edge.api.flagsmith.com/api/v1/flags/
headers:
X-Environment-Key: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -254,6 +254,9 @@ rules:
- 'DEPLOY_TOKEN=gldt-3dEfGhIjK4MnOpQrStUv'
references:
- https://docs.gitlab.com/user/project/deploy_tokens/
# Validation not added: deploy tokens authenticate via HTTP basic auth
# (username + token as password) and require the deploy token username,
# which varies per token and is not captured by this rule.
- name: GitLab Feature Flag Client Token
id: kingfisher.gitlab.7
@ -473,3 +476,20 @@ rules:
- 'Cookie: _gitlab_session=0f1e2d3c4b5a69788796a5b4c3d2e1f0'
references:
- https://docs.gitlab.com/
validation:
type: Http
content:
request:
method: GET
url: https://gitlab.com/api/v4/user
headers:
Cookie: "_gitlab_session={{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words:
- '"id"'
- '"username"'
match_all_words: true

View file

@ -0,0 +1,16 @@
rules:
- name: GuardSquare AppSweep API Key
id: kingfisher.guardsquare.1
pattern: |
(?x)
\b
(
gs_appsweep_[a-zA-Z0-9_-]{24,48}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'APPSWEEP_API_KEY=gs_appsweep_a1B2c3D4e5F6g7H8i9J0k1L2'
references:
- https://www.guardsquare.com/appsweep

View file

@ -0,0 +1,16 @@
rules:
- name: Hack Club AI API Key
id: kingfisher.hackclub.1
pattern: |
(?x)
\b
(
sk-hc-v1-[a-f0-9]{64}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'HACKCLUB_API_KEY=sk-hc-v1-a1b2c3d4e5f60708a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f60708a9b0c1d2'
references:
- https://jams.hackclub.com/jam/ai-travel

View file

@ -0,0 +1,58 @@
rules:
- name: Hex.pm Personal Token
id: kingfisher.hexpm.1
pattern: |
(?x)
\b
(
hxtp_[a-f0-9]{64}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'HEX_API_KEY=hxtp_a1b2c3d4e5f60708a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f60708a9b0c1d2'
references:
- https://hex.pm/docs/faq
validation:
type: Http
content:
request:
method: GET
url: https://hex.pm/api/auth
headers:
Authorization: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- name: Hex.pm Workspace Token
id: kingfisher.hexpm.2
pattern: |
(?x)
\b
(
hxtw_[a-f0-9]{64}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'HEX_API_KEY=hxtw_a1b2c3d4e5f60708a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f60708a9b0c1d2'
references:
- https://hex.pm/docs/faq
validation:
type: Http
content:
request:
method: GET
url: https://hex.pm/api/auth
headers:
Authorization: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]

View file

@ -17,6 +17,20 @@ rules:
- 'HOP_TOKEN=ptk_AbCdEfGhIjKlMnOpQrStUvWxYz123456'
references:
- https://docs.hop.io/reference/rest-api
validation:
type: Http
content:
request:
method: GET
url: https://api.hop.io/v1/projects/@this
headers:
Authorization: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- name: HOP Personal Access Token
id: kingfisher.hop.2
@ -36,3 +50,17 @@ rules:
- 'HOP_PAT="hop_pat_AbCdEfGhIjKlMnOpQrStUvWxYz123456"'
references:
- https://docs.hop.io/reference/rest-api
validation:
type: Http
content:
request:
method: GET
url: https://api.hop.io/v1/users/@me
headers:
Authorization: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,16 @@
rules:
- name: Infisical Service Token
id: kingfisher.infisical.1
pattern: |
(?x)
\b
(
st\.[a-f0-9]{8,32}\.[a-f0-9]{8,32}\.[a-f0-9]{16,48}
)
(?:\b|$)
min_entropy: 3.5
confidence: medium
examples:
- 'INFISICAL_TOKEN=st.a1b2c3d4e5f6.7890abcdef12.f1e2d3c4b5a69788796a5b4c3d2e1f0'
references:
- https://infisical.com/docs/internals/service-tokens

View file

@ -0,0 +1,34 @@
rules:
- name: Inngest Signing Key
id: kingfisher.inngest.1
pattern: |
(?x)
\b
(
signkey-[A-Za-z0-9_]+-[a-f0-9]{32,68}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'INNGEST_SIGNING_KEY=signkey-prod-b2ed992186a5cb19f6668aade821f502c1d00970dfd0e35128d51bac4649916c'
- 'INNGEST_SIGNING_KEY="signkey-branch-12345678abcdef0123456789abcdef01"'
references:
- https://www.inngest.com/docs/platform/signing-keys
- name: Inngest Event Key
id: kingfisher.inngest.2
pattern: |
(?x)
\b
(
evtkey-(?:dev|prod|test|staging|branch)-[a-f0-9]{24,40}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'INNGEST_EVENT_KEY=evtkey-dev-a1b2c3d4e5f60708a9b0c1d2'
- 'INNGEST_EVENT_KEY="evtkey-prod-deadbeefcafebabe1234567890abcdef"'
references:
- https://www.inngest.com/docs/events/creating-an-event

View file

@ -0,0 +1,33 @@
rules:
- name: Liveblocks Secret Key
id: kingfisher.liveblocks.1
pattern: |
(?x)
\b
(
sk_(?:prod|dev)_[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'LIVEBLOCKS_SECRET_KEY=sk_prod_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'LIVEBLOCKS_SECRET_KEY="sk_dev_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h"'
references:
- https://liveblocks.io/docs/api-reference/rest-api-endpoints
validation:
type: Http
content:
request:
method: GET
url: https://api.liveblocks.io/v2/rooms?limit=1
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,32 @@
rules:
- name: Mappedin API Key
id: kingfisher.mappedin.1
pattern: |
(?x)
\b
(
mik_[a-zA-Z0-9]{26}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'MAPPEDIN_KEY=mik_a1B2c3D4e5F6g7H8i9J0k1L2m3'
references:
- https://developer.mappedin.com/docs/mvf/v2/getting-started
- name: Mappedin API Secret
id: kingfisher.mappedin.2
pattern: |
(?x)
\b
(
mis_[a-zA-Z0-9]{52}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'MAPPEDIN_SECRET=mis_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V2w3X4y5Z6'
references:
- https://developer.mappedin.com/docs/mvf/v2/getting-started

View file

@ -0,0 +1,37 @@
rules:
- name: Mastra Memory Gateway API Key
id: kingfisher.mastra.1
pattern: |
(?x)
\b
(
msk_[A-Za-z0-9]{32}(?:[A-Za-z0-9]{16}){0,2}
)
\b
pattern_requirements:
min_digits: 4
min_lowercase: 4
min_uppercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'MASTRA_API_KEY="msk_7fKp2Rz9Qa4Vn8Lm3Tx6Yc5Bg1Hd0JsW"'
- 'Authorization: Bearer msk_P7rT2mK9vL4qN8sX6cA3dF5gH1jZ0QaB'
references:
- https://gateway.mastra.ai/docs
- https://gateway.mastra.ai/docs/models
validation:
type: Http
content:
request:
method: GET
url: https://gateway-api.mastra.ai/v1/models
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
# Mastra Memory Gateway docs do not document a public API-key revocation endpoint.

View file

@ -0,0 +1,33 @@
rules:
- name: Mem0 API Key
id: kingfisher.mem0.1
pattern: |
(?x)
\b
(
m0-[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'MEM0_API_KEY=m0-a1b2c3d4e5f6g7h8i9j0k1l2m3n4'
- 'Authorization: Token m0-xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
references:
- https://docs.mem0.ai/api-reference
validation:
type: Http
content:
request:
method: GET
url: https://api.mem0.ai/v1/memories/?limit=1
headers:
Authorization: "Token {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,30 @@
rules:
- name: MiniMax API Key
id: kingfisher.minimax.1
pattern: |
(?x)
\b
(
MINIMAX-[A-Z0-9]{8}-[A-Z0-9]{8}-[A-Z0-9]{8}-[A-Z0-9]{8}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'MINIMAX_API_KEY=MINIMAX-A1B2C3D4-E5F6G7H8-I9J0K1L2-M3N4O5P6'
references:
- https://platform.minimax.io/docs/token-plan/quickstart
validation:
type: Http
content:
request:
method: GET
url: https://api.minimax.io/v1/models
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,19 @@
rules:
- name: Mintlify API Key
id: kingfisher.mintlify.1
pattern: |
(?x)
\b
(
mint_(?:dsc_)?[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'MINTLIFY_API_KEY=mint_a1b2c3d4e5f6g7h8i9j0k1l2'
- 'MINTLIFY_KEY="mint_dsc_xK8m2LpQr5nW0vYz3cJ7aB4d"'
references:
- https://mintlify.com/docs/api/introduction

View file

@ -124,3 +124,33 @@ rules:
- report_response: true
- type: StatusMatch
status: [204]
- name: Netlify Personal Access Token (nfp_ prefix)
id: kingfisher.netlify.3
pattern: |
(?x)
\b
(
nfp_[a-zA-Z0-9]{40,48}
)
\b
pattern_requirements:
min_digits: 2
min_entropy: 3.3
confidence: medium
examples:
- 'NETLIFY_AUTH_TOKEN=nfp_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0'
references:
- https://docs.netlify.com/api/get-started/#authentication
validation:
type: Http
content:
request:
method: GET
url: https://api.netlify.com/api/v1/user
headers:
Authorization: "Bearer {{ TOKEN }}"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]

View file

@ -0,0 +1,31 @@
rules:
- name: Nightfall AI API Key
id: kingfisher.nightfall.1
pattern: |
(?x)
\b
(
NF-[a-zA-Z0-9]{32}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'NIGHTFALL_API_KEY=NF-a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6'
- 'Authorization: Bearer NF-xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h0i'
references:
- https://docs.nightfall.ai/docs/creating-an-api-key
validation:
type: Http
content:
request:
method: POST
url: https://api.nightfall.ai/v3/upload
headers:
Authorization: "Bearer {{ TOKEN }}"
Content-Type: application/json
body: '{"fileSizeBytes":256}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [200, 201]

View file

@ -0,0 +1,74 @@
rules:
- name: Ory API Key
id: kingfisher.ory.1
pattern: |
(?x)
\b
(
ory_(?:pat|apikey|wak)_[A-Za-z0-9_-]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'ORY_API_KEY=ory_pat_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
- 'ORY_ACCESS_KEY="ory_wak_a1b2c3d4e5f6g7h8i9j0k1l2"'
- 'Authorization: Bearer ory_apikey_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
references:
- https://www.ory.sh/docs/security-compliance/token-formats
validation:
type: Http
content:
request:
method: GET
url: https://api.console.ory.sh/projects
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200, 403]
- type: WordMatch
words:
- '"Unauthorized"'
negative: true
- name: Ory Session Token
id: kingfisher.ory.2
pattern: |
(?x)
\b
(
ory_st_[A-Za-z0-9_-]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'ory_session_token=ory_st_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
references:
- https://www.ory.sh/docs/security-compliance/token-formats
- name: Ory OAuth2 Token
id: kingfisher.ory.3
pattern: |
(?x)
\b
(
ory_(?:at|rt|ac)_[A-Za-z0-9_-]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'access_token=ory_at_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
- 'refresh_token="ory_rt_a1b2c3d4e5f6g7h8i9j0k1l2"'
references:
- https://www.ory.sh/docs/security-compliance/token-formats

View file

@ -0,0 +1,23 @@
rules:
- name: Pirsch Analytics Access Key
id: kingfisher.pirsch.1
pattern: |
(?xi)
pirsch
(?:.|[\n\r]){0,32}?
(?:SECRET|ACCESS|KEY|TOKEN|CLIENT)
(?:.|[\n\r]){0,16}?
\b
(
pa_[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'PIRSCH_ACCESS_KEY=pa_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'pirsch_client_secret = "pa_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8hI0"'
references:
- https://docs.pirsch.io/api-sdks/api-guide

View file

@ -0,0 +1,36 @@
rules:
- name: Pollinations Secret Key
id: kingfisher.pollinations.1
pattern: |
(?x)
\b
(
plln_sk_[a-zA-Z0-9]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'POLLINATIONS_KEY=plln_sk_a1B2c3D4e5F6g7H8i9J0k1L2'
references:
- https://pollinations.ai/pricing
- name: Pollinations Publishable Key
id: kingfisher.pollinations.2
pattern: |
(?x)
\b
(
plln_pk_[a-zA-Z0-9]{24,48}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'POLLINATIONS_PUBLIC_KEY=plln_pk_a1B2c3D4e5F6g7H8i9J0k1L2'
references:
- https://pollinations.ai/pricing

View file

@ -41,6 +41,20 @@ rules:
examples:
- "phs_8BamSCGAJL4J0hBl2WmkcswecSArJAXO20xzcpYhdiPto9B"
- "phs_FsG1YzDpCu64PFUcbW1CiEEfiFg1IIBRsME3qqehpZ5GpoT"
validation:
type: Http
content:
request:
method: GET
url: https://app.posthog.com/api/users/@me/
headers:
Authorization: "Bearer {{ TOKEN }}"
Content-Type: "application/json"
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
references:
- https://posthog.com/docs/api
- https://github.com/PostHog/posthog/blob/e408aac5debe02b39a6a67cfd028f16a2ca7bc90/posthog/models/utils.py#L260-L290

View file

@ -0,0 +1,32 @@
rules:
- name: Ramp Client ID
id: kingfisher.ramp.1
pattern: |
(?x)
\b
(
ramp_id_[a-zA-Z0-9]{40}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'RAMP_CLIENT_ID=ramp_id_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0'
references:
- https://docs.ramp.com/reference/authentication
- name: Ramp Client Secret
id: kingfisher.ramp.2
pattern: |
(?x)
\b
(
ramp_sec_[a-zA-Z0-9]{48}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'RAMP_CLIENT_SECRET=ramp_sec_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V2w3X4'
references:
- https://docs.ramp.com/reference/authentication

View file

@ -0,0 +1,37 @@
rules:
- name: redirect.pizza API Token
id: kingfisher.redirectpizza.1
pattern: |
(?x)
\b
(
rpa_[A-Za-z0-9]{30}
)
\b
pattern_requirements:
min_digits: 4
min_lowercase: 4
min_uppercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'REDIRECT_PIZZA_TOKEN="rpa_Qj7mN4vK8sL2xP6zT9aBcD3eF5gH1j"'
- 'Authorization: Bearer rpa_P7rT2mK9vL4qN8sX6cA3dF5gH1jZ0Q'
references:
- https://docs.github.com/en/code-security/reference/secret-security/supported-secret-scanning-patterns
- https://redirect.pizza/api/v1/domains
validation:
type: Http
content:
request:
method: GET
url: https://redirect.pizza/api/v1/domains
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
# API-token deletion is dashboard-managed; the public redirect.pizza API does not document self-revocation.

View file

@ -0,0 +1,31 @@
rules:
- name: Seam API Key
id: kingfisher.seam.1
pattern: |
(?x)
\b
(
seam_(?:test2|live)[a-zA-Z0-9]{1,8}_[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{20,32}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'SEAM_API_KEY=seam_test2bMS_94SrGUXuNR2JmJkjtvBQDg5c'
- 'SEAM_API_KEY="seam_liveK3_7Zum8CdnFeJi2CysRnTBh3"'
references:
- https://docs.seam.co/latest/core-concepts/authentication/api-keys
validation:
type: Http
content:
request:
method: GET
url: https://connect.getseam.com/workspaces/get
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -80,3 +80,19 @@ rules:
- https://supabase.com/docs/guides/api
examples:
- "https://ejcvydfyxzmbtfbfstnq.supabase.co"
- name: Supabase Publishable Key
id: kingfisher.supabase.4
pattern: |
(?x)
\b
(
sb_publishable_[a-zA-Z0-9_-]{24,40}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'NEXT_PUBLIC_SUPABASE_ANON_KEY=sb_publishable_a1B2c3D4e5F6g7H8i9J0k1L2'
references:
- https://supabase.com/docs/guides/api

View file

@ -0,0 +1,17 @@
rules:
- name: Svix Webhook Signing Secret
id: kingfisher.svix.1
pattern: |
(?x)
\b
(
whsec_(?:[A-Za-z0-9+/]{32}|[A-Za-z0-9+/]{43}=|[A-Za-z0-9+/]{42}==)
)
(?:\b|$)
min_entropy: 3.0
confidence: medium
examples:
- 'WEBHOOK_SECRET=whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw'
- 'SVIX_WEBHOOK_SECRET="whsec_C2FVsBQIhrscChlQIMV+b5sSYspob7oD"'
references:
- https://docs.svix.com/receiving/verifying-payloads/how-manual

View file

@ -0,0 +1,39 @@
rules:
- name: Tinybird Admin Token
id: kingfisher.tinybird.1
pattern: |
(?x)
\b
(?i:tinybird)
(?:.|[\n\r]){0,32}?
(?:ADMIN|SECRET|TOKEN|KEY)
(?:.|[\n\r]){0,16}?
\b
(
p\.[A-Za-z0-9]{40,100}
)
(?:\b|$)
pattern_requirements:
min_digits: 1
min_uppercase: 1
min_lowercase: 1
min_entropy: 3.5
confidence: medium
examples:
- 'TINYBIRD_TOKEN=p.eyJ1IjogIjczMjA3MzYwLWVmMDAtNGIxOS1hZjQ3LWRlMmU3OTI2ZTdmOCJ9'
references:
- https://www.tinybird.co/docs/api-reference/token-api
validation:
type: Http
content:
request:
method: GET
url: https://api.tinybird.co/v0/datasources
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,61 @@
rules:
- name: Tolgee Project API Key
id: kingfisher.tolgee.1
pattern: |
(?x)
\b
(
tgpak_[a-z2-7]{40,64}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'TOLGEE_API_KEY=tgpak_ha3tkxzton2wm4twmrsgkmtgmnsgw4bqgvttemttnrwwoyld'
- 'X-API-Key: tgpak_gm2tgnrqgi3tsnrvheytomrvme4dgmrtgntdgntfmu3to'
references:
- https://tolgee.io/platform/account_settings/api_keys_and_pat_tokens
validation:
type: Http
content:
request:
method: GET
url: https://app.tolgee.io/v2/projects
headers:
X-API-Key: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- name: Tolgee Personal Access Token
id: kingfisher.tolgee.2
pattern: |
(?x)
\b
(
tgpat_[a-z2-7]{40,64}
)
\b
min_entropy: 3.0
confidence: medium
examples:
- 'TOLGEE_PAT=tgpat_gm2tgnrqgi3tsnrvheytomrvme4dgmrtgntdgntfmu3to'
references:
- https://tolgee.io/platform/account_settings/api_keys_and_pat_tokens
validation:
type: Http
content:
request:
method: GET
url: https://app.tolgee.io/v2/projects
headers:
X-API-Key: "{{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,71 @@
rules:
- name: Trigger.dev Secret Key
id: kingfisher.triggerdev.1
pattern: |
(?x)
\b
(
tr_(?:dev|prod|stg)_[A-Za-z0-9]{20,40}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'TRIGGER_SECRET_KEY=tr_dev_1a2b3c4d5e6f7g8h9i0j'
- 'TRIGGER_SECRET_KEY=tr_prod_xK8m2LpQr5nW0vYz3cJ7'
references:
- https://trigger.dev/docs/management/authentication
validation:
type: Http
content:
request:
method: GET
url: https://api.trigger.dev/api/v1/tasks
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200, 401]
- type: WordMatch
words:
- '"Unauthorized"'
negative: true
- name: Trigger.dev Personal Access Token
id: kingfisher.triggerdev.2
pattern: |
(?x)
\b
(
tr_pat_[A-Za-z0-9]{20,40}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'TRIGGER_ACCESS_TOKEN=tr_pat_xK8m2LpQr5nW0vYz3cJ7aB4d'
references:
- https://trigger.dev/docs/management/authentication
validation:
type: Http
content:
request:
method: GET
url: https://api.trigger.dev/api/v1/tasks
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200, 401]
- type: WordMatch
words:
- '"Unauthorized"'
negative: true

View file

@ -78,6 +78,22 @@ rules:
- report_response: true
- type: StatusMatch
status: [200]
validation:
type: Http
content:
request:
method: POST
url: https://api.unkey.com/v2/keys.verifyKey
headers:
Content-Type: application/json
body: '{"key":"{{ TOKEN }}"}'
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: WordMatch
words:
- '"valid"'
references:
- https://www.unkey.com/docs/api-reference/v2/keys/create-api-key
- https://www.unkey.com/docs/api-reference/v2/keys/verify-api-key

View file

@ -0,0 +1,76 @@
rules:
- name: Upstash Redis REST Token
id: kingfisher.upstash.1
pattern: |
(?x)
\b
(?:
UPSTASH_REDIS_REST_TOKEN
|
(?i:upstash)
(?:.|[\n\r]){0,40}?
(?i:(?:redis|rest))
(?:.|[\n\r]){0,40}?
(?i:token)
)
(?:.|[\n\r]){0,24}?
(
(?:
[A-Za-z0-9]{32,48}
|
AYNgAS[A-Za-z0-9+/_-]{26,90}={0,2}
)
)
\b
pattern_requirements:
min_digits: 4
min_lowercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'UPSTASH_REDIS_REST_TOKEN="2553feg6a2d9842h2a0gcdb5f8efe9934"'
- 'upstash redis token: "AYNgAS2553feg6a2d9842h2a0gcdb5f8efe9934DQ="'
references:
- https://upstash.com/docs/redis/features/restapi
- https://upstash.com/docs/redis/howto/connectwithupstashredis
depends_on_rule:
- rule_id: kingfisher.upstash.2
variable: UPSTASH_REDIS_REST_URL
validation:
type: Http
content:
request:
method: POST
url: "{{ UPSTASH_REDIS_REST_URL }}/ping"
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- type: WordMatch
words:
- PONG
# Upstash Redis REST tokens are database credentials; revocation is done by rotating/resetting the database token.
- name: Upstash Redis REST URL
id: kingfisher.upstash.2
pattern: |
(?xi)
\b
(?:UPSTASH_REDIS_REST_URL|upstash)
(?:.|[\n\r]){0,48}?
(
https://[a-z0-9][a-z0-9-]{2,63}\.upstash\.io
)
\b
min_entropy: 3.0
confidence: medium
visible: false
examples:
- 'UPSTASH_REDIS_REST_URL="https://steady-cobra-12345.upstash.io"'
- 'upstash_url=https://sharp-raven-67890.upstash.io'
references:
- https://upstash.com/docs/redis/features/restapi

View file

@ -0,0 +1,32 @@
rules:
- name: WarpStream API Key Secret
id: kingfisher.warpstream.1
pattern: |
(?x)
\b
(
aks_[a-f0-9]{64}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'WARPSTREAM_API_KEY=aks_a51b1fb20ac4a3af549503bb08cd309672fcada1030c5a494850e87ce5d4c613'
references:
- https://docs.warpstream.com/warpstream/reference/api-reference/api-keys
- https://docs.warpstream.com/warpstream/reference/api-reference/api-keys/list
validation:
type: Http
content:
request:
method: GET
url: https://api.warpstream.com/api/v1/list_api_keys
headers:
warpstream-api-key: "{{ TOKEN }}"
Content-Type: application/json
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,33 @@
rules:
- name: WooCommerce Consumer Secret
id: kingfisher.woocommerce.1
pattern: |
(?x)
\b
(
cs_[a-f0-9]{40}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'WC_CONSUMER_SECRET=cs_a1b2c3d4e5f60708a9b0c1d2e3f4a5b6c7d8e9f0'
- 'consumer_secret: "cs_deadbeefcafebabe1234567890abcdef01234567"'
references:
- https://woocommerce.github.io/woocommerce-rest-api-docs/#authentication
- name: WooCommerce Consumer Key
id: kingfisher.woocommerce.2
pattern: |
(?x)
\b
(
ck_[a-f0-9]{40}
)
\b
min_entropy: 3.5
confidence: medium
examples:
- 'WC_CONSUMER_KEY=ck_a1b2c3d4e5f60708a9b0c1d2e3f4a5b6c7d8e9f0'
references:
- https://woocommerce.github.io/woocommerce-rest-api-docs/#authentication

View file

@ -0,0 +1,45 @@
rules:
- name: WorkOS API Key
id: kingfisher.workos.1
pattern: |
(?xi)
\b
(?:workos|WORKOS_API_KEY|WORKOS_SECRET_KEY)
(?:.|[\n\r]){0,48}?
\b
(
sk_(?:live|test|staging|example)_[A-Za-z0-9_-]{16}(?:[A-Za-z0-9_-]{16}){0,3}
)
\b
pattern_requirements:
min_digits: 4
min_lowercase: 4
min_entropy: 3.5
confidence: medium
examples:
- 'WORKOS_API_KEY="sk_live_Qj7mN4vK8sL2xP6zT9aBcD3eF5gH1jK2"'
- 'workos apiKey: "sk_test_P7rT2mK9vL4qN8sX6cA3dF5gH1jZ0QaB"'
references:
- https://workos.com/docs/reference/organization
- https://workos.com/docs/reference/authkit/user
- https://docs.github.com/en/code-security/reference/secret-security/supported-secret-scanning-patterns
validation:
type: Http
content:
request:
method: GET
url: https://api.workos.com/organizations
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid
- type: WordMatch
words:
- '"object"'
- '"data"'
match_all_words: true
# WorkOS account API keys are managed from the WorkOS dashboard; no self-revocation endpoint is documented.

View file

@ -0,0 +1,33 @@
rules:
- name: Xata API Key
id: kingfisher.xata.1
pattern: |
(?x)
\b
(
xau_[A-Za-z0-9]{24,44}
)
\b
pattern_requirements:
min_digits: 1
min_entropy: 3.0
confidence: medium
examples:
- 'XATA_API_KEY=xau_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
- 'Authorization: Bearer xau_xK8m2LpQr5nW0vYz3cJ7aB4dE6fG8h'
references:
- https://xata.io/docs/concepts/api-keys
validation:
type: Http
content:
request:
method: GET
url: https://api.xata.io/user
headers:
Authorization: "Bearer {{ TOKEN }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -0,0 +1,31 @@
rules:
- name: Xendit API Key
id: kingfisher.xendit.1
pattern: |
(?x)
\b
(
xnd_(?:production|development)_[A-Za-z0-9_-]{32,52}
)
(?:\b|$)
min_entropy: 3.0
confidence: medium
examples:
- 'XENDIT_SECRET_KEY=xnd_development_P4qDfOss0OCpl8RtKrROHjaQYNCk9dN5lSfk'
- 'XENDIT_API_KEY="xnd_production_aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4y"'
references:
- https://docs.xendit.co/api-integration/api-keys
validation:
type: Http
content:
request:
method: GET
url: https://api.xendit.co/balance
headers:
Authorization: "Basic {{ TOKEN | append: ':' | b64enc }}"
Accept: application/json
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: JsonValid

View file

@ -8,7 +8,7 @@ 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]
- Added live HTTP validation for 12 rules across 10 providers: Val Town, Polar, hCaptcha, Thunderstore, Elastic Cloud (2 rules), LlamaCloud, Gemfury (2 rules), Vonage, ThingsBoard, and Zapier.
- 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.
## [v1.95.0]