diff --git a/README.md b/README.md
index 1a0bde6..decb35a 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
-
+
diff --git a/crates/kingfisher-rules/data/rules/box.yml b/crates/kingfisher-rules/data/rules/box.yml
new file mode 100644
index 0000000..aa2aebf
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/box.yml
@@ -0,0 +1,44 @@
+rules:
+ - name: Box API Access Token
+ id: kingfisher.box.1
+ pattern: |
+ (?x)
+ \b
+ (?i:box)
+ (?:.|[\n\r]){0,32}?
+ (?i:ACCESS|TOKEN|DEVELOPER)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [A-Za-z0-9]{32}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 2
+ min_uppercase: 1
+ min_lowercase: 1
+ min_entropy: 3.5
+ confidence: medium
+ examples:
+ - 'BOX_DEVELOPER_TOKEN="DkXZmsjUKizvL2z0WiaLvMBeQ756XCGG"'
+ - |
+ box_access_token = 'A4bC5dE6fG7hI8jK9lM0nO1pQ2rS3tU4'
+ negative_examples:
+ - 'BOX_DOC_URL="https://developer.box.com"'
+ - 'sandbox_mode = true'
+ references:
+ - https://developer.box.com/reference/
+ - https://developer.box.com/guides/authentication/tokens/developer-tokens/
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.box.com/2.0/users/me
+ headers:
+ Authorization: 'Bearer {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/braintree.yml b/crates/kingfisher-rules/data/rules/braintree.yml
new file mode 100644
index 0000000..57f87ef
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/braintree.yml
@@ -0,0 +1,33 @@
+rules:
+ - name: Braintree Tokenization Key
+ id: kingfisher.braintree.1
+ pattern: |
+ (?x)
+ \b
+ (?i:braintree)
+ (?:.|[\n\r]){0,32}?
+ (?i:KEY|TOKEN|TOKENIZATION)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ (?:sandbox|production)
+ _
+ [a-z0-9]{6,10}
+ _
+ [a-z0-9]{14,20}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 2
+ min_lowercase: 6
+ min_entropy: 3.0
+ confidence: medium
+ examples:
+ - 'BRAINTREE_TOKENIZATION_KEY="sandbox_f252zhq7_hh4cpc39zq4rgjcg"'
+ - 'braintree_token = production_abc12def_ghij34klmnop5678'
+ negative_examples:
+ - sandbox_f252zhq7_hh4cpc39zq4rgjcg
+ - 'BRAINTREE_URL="https://api.braintreegateway.com"'
+ references:
+ - https://developer.paypal.com/braintree/docs/guides/authorization/tokenization-key
+ - https://developer.paypal.com/braintree/docs/start/overview
diff --git a/crates/kingfisher-rules/data/rules/couchbase.yml b/crates/kingfisher-rules/data/rules/couchbase.yml
new file mode 100644
index 0000000..407a177
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/couchbase.yml
@@ -0,0 +1,51 @@
+rules:
+ - name: Couchbase Capella API Key
+ id: kingfisher.couchbase.1
+ pattern: |
+ (?xi)
+ \b
+ (?:couchbase|capella)
+ (?:.|[\n\r]){0,32}?
+ (?:
+ api
+ (?:.|[\n\r]){0,12}?
+ (?:key|secret)
+ |
+ key
+ (?:.|[\n\r]){0,12}?
+ secret
+ )
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [A-Za-z0-9+/]{60,120}={0,2}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 4
+ min_uppercase: 4
+ min_lowercase: 4
+ min_entropy: 4.0
+ confidence: medium
+ examples:
+ - 'COUCHBASE_API_KEY_SECRET="QktxVUtFU1dKV1FlJBYXdnTVlRemFZdmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDJBQ0RF"'
+ - |
+ capella_api_secret = 'aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3aA4bB5cC6dD7eE8fF9gG0hH1iJ2kL3m=='
+ negative_examples:
+ - 'COUCHBASE_URL="https://cloud.couchbase.com"'
+ references:
+ - https://docs.couchbase.com/cloud/management-api-reference/index.html
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://cloudapi.cloud.couchbase.com/v4/organizations
+ headers:
+ Accept: application/json
+ Authorization: 'Bearer {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/gitguardian.yml b/crates/kingfisher-rules/data/rules/gitguardian.yml
deleted file mode 100644
index 548248e..0000000
--- a/crates/kingfisher-rules/data/rules/gitguardian.yml
+++ /dev/null
@@ -1,165 +0,0 @@
-rules:
- - name: GitGuardian Public Monitoring API Key
- id: kingfisher.gitguardian.1
- pattern: |
- (?xi)
- (?:
- \benterprise\.gitguardian\.com\b
- (?:.|[\n\r]){0,160}?
- |
- \bgitguardian\b
- (?:.|[\n\r]){0,64}?
- \b(?:public|monitoring|github|incident|authorization|token|api)\b
- (?:.|[\n\r]){0,64}?
- )
- \b
- (
- [a-f0-9]{71}
- )
- \b
- pattern_requirements:
- min_digits: 8
- min_entropy: 3.5
- confidence: medium
- examples:
- - 'host: enterprise.gitguardian.com\nAuthorization: Token 4283fefc63f0cd0e873a0000c6d07ef7b77e90d3593ad699fc1f7cd5bb2e35cbf0f19c5'
- - 'gitguardian public monitoring key = "122b598615dcbe810beacd557705a54b5edbbbe5ce7f8fbeebef7a58f99d96fb2a06311"'
- references:
- - https://enterprise.gitguardian.com/api/docs
- - https://enterprise.gitguardian.com/docs
- validation:
- type: Http
- content:
- request:
- method: GET
- url: https://enterprise.gitguardian.com/api/v1/is_alive
- headers:
- Authorization: Token {{ TOKEN }}
- Accept: application/json
- response_matcher:
- - report_response: true
- - type: StatusMatch
- status: [200]
-
- - name: GitGuardian Internal Monitoring Key
- id: kingfisher.gitguardian.2
- pattern: |
- (?xi)
- (?:
- \b(?:api(?:\.eu1)?\.gitguardian\.com|ggshield|gitguardian)\b
- (?:.|[\n\r]){0,96}?
- \b(?:api|internal|monitoring|token|key|authorization)\b
- (?:.|[\n\r]){0,64}?
- )
- \b
- (
- [a-f0-9]{8}
- [a-d]
- [a-f0-9]{7}
- [c-e]
- [a-f0-9]{15}
- [c-f]
- [a-f0-9]{31}
- [5-8]
- [a-f0-9]{6}
- )
- \b
- pattern_requirements:
- min_digits: 8
- min_entropy: 3.5
- confidence: medium
- examples:
- - 'GG_API_URL=https://api.gitguardian.com/v1 authorization = "ae075528a220e087d35b92558589eaffc09cad68386d070c415ed7e70cad19465922995"'
- - 'ggshield auth login --method token --token 74bf20f8b6ffc474ec0251908fcdce4bc14f68d9dcbd7a085a368932ff2b2d407dd311c'
- references:
- - https://api.gitguardian.com/docs
- validation:
- type: Http
- content:
- request:
- method: GET
- url: https://api.gitguardian.com/v1/health
- headers:
- Authorization: Token {{ TOKEN }}
- Accept: application/json
- response_matcher:
- - report_response: true
- - type: StatusMatch
- status: [200]
-
- - name: GitGuardian Incident Token
- id: kingfisher.gitguardian.3
- pattern: |
- (?xi)
- (?:
- (?:https?://)?dashboard\.gitguardian\.com
- |
- (?:https?://)?[a-z0-9.-]+/gitguardian
- )
- /share/incidents/
- (
- [a-f0-9]{8}-
- [a-f0-9]{4}-
- [a-f0-9]{4}-
- [a-f0-9]{4}-
- [a-f0-9]{12}
- )
- \b
- pattern_requirements:
- min_digits: 6
- min_entropy: 3.1
- confidence: medium
- examples:
- - incident_share=dashboard.gitguardian.com/share/incidents/6f3a2c19-8b4e-4d7a-9c10-2e5f6a7b8c9d
- - 'external_review_url: https://onprem.example.com/gitguardian/share/incidents/1d4c7b82-5a90-4471-8f63-0a9b2c3d4e5f'
- references:
- - https://docs.gitguardian.com/internal-repositories-monitoring/incidents/collaborate
-
- - name: GitGuardian Onboarding Token
- id: kingfisher.gitguardian.4
- pattern: |
- (?xi)
- \bdashboard\.gitguardian\.com/core-alerting/incident-resolution/
- (
- [a-f0-9]{8}-
- [a-f0-9]{4}-
- [a-f0-9]{4}-
- [a-f0-9]{4}-
- [a-f0-9]{12}
- )
- \b
- pattern_requirements:
- min_digits: 6
- min_entropy: 3.1
- confidence: medium
- examples:
- - review_link=dashboard.gitguardian.com/core-alerting/incident-resolution/f2c48010-2231-11ef-9a7b-0242ac120002
- - 'gg_onboarding_url: "dashboard.gitguardian.com/core-alerting/incident-resolution/c17e9a40-1250-11ee-88d4-0242ac14000a"'
- references:
- - https://docs.gitguardian.com/
-
- - name: GitGuardian Platform Magic Link
- id: kingfisher.gitguardian.5
- pattern: |
- (?xi)
- \b
- (
- https://
- dashboard(?:\.preprod)?\.gitguardian\.com
- /api/v1/auth/magic-link/
- [a-f0-9]{8}-
- [a-f0-9]{4}-
- [a-f0-9]{4}-
- [a-f0-9]{4}-
- [a-f0-9]{12}
- )
- \b
- pattern_requirements:
- min_digits: 8
- min_entropy: 3.2
- confidence: medium
- examples:
- - https://dashboard.preprod.gitguardian.com/api/v1/auth/magic-link/2b7d3f10-6e44-413a-a8b1-5c9d0e2f4a6b
- - https://dashboard.gitguardian.com/api/v1/auth/magic-link/9a0c1d22-7f58-46be-b321-4d6e8f0a1b2c
- references:
- - https://docs.gitguardian.com/
diff --git a/crates/kingfisher-rules/data/rules/godaddy.yml b/crates/kingfisher-rules/data/rules/godaddy.yml
new file mode 100644
index 0000000..a71f7e8
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/godaddy.yml
@@ -0,0 +1,42 @@
+rules:
+ - name: GoDaddy API Credentials
+ id: kingfisher.godaddy.1
+ pattern: |
+ (?xi)
+ \b
+ sso-key
+ \s+
+ (
+ (?:[A-Za-z0-9_]{35}|[A-Za-z0-9_]{37})
+ :
+ [A-Za-z0-9]{22}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 2
+ min_uppercase: 1
+ min_lowercase: 1
+ min_entropy: 3.0
+ confidence: medium
+ examples:
+ - 'Authorization: sso-key Abc123XYZ789Def456GhI789Jkl012MnOpQ:pQ7rS2tUvW5xY8zAaBcDeF'
+ - 'headers = {"Authorization": "sso-key Abc123XYZ789Def456GhI789Jkl012MnOpQrs:3bKm9wPqRz2nLhFvJ8yG5x"}'
+ negative_examples:
+ - 'sso-key test:test'
+ - 'sso-key a:b'
+ references:
+ - https://developer.godaddy.com/doc/endpoint/domains
+ - https://developer.godaddy.com/getstarted
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.godaddy.com/v1/domains/available?domain=example.com
+ headers:
+ Authorization: 'sso-key {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200, 403]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/langfuse.yml b/crates/kingfisher-rules/data/rules/langfuse.yml
new file mode 100644
index 0000000..3a010d8
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/langfuse.yml
@@ -0,0 +1,65 @@
+rules:
+ - name: Langfuse Secret Key
+ id: kingfisher.langfuse.1
+ pattern: |
+ (?xi)
+ \b
+ (
+ sk-lf-[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: 1
+ min_lowercase: 1
+ min_entropy: 3.0
+ confidence: medium
+ examples:
+ - sk-lf-a1b2c3d4-e5f6-7890-abcd-ef1234567890
+ - 'LANGFUSE_SECRET_KEY="sk-lf-9f8e7d6c-5b4a-3210-fedc-ba0987654321"'
+ negative_examples:
+ - sk-lf-test
+ - sk-lf-
+ references:
+ - https://langfuse.com/docs/sdk/typescript
+ - https://langfuse.com/docs/get-started
+ depends_on_rule:
+ - rule_id: kingfisher.langfuse.2
+ variable: PUBLIC_KEY
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://cloud.langfuse.com/api/public/projects
+ headers:
+ Authorization: 'Basic {{ PUBLIC_KEY | append: ":" | append: TOKEN | b64enc }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
+
+ - name: Langfuse Public Key
+ id: kingfisher.langfuse.2
+ pattern: |
+ (?xi)
+ \b
+ (
+ pk-lf-[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: 1
+ min_lowercase: 1
+ min_entropy: 3.0
+ confidence: medium
+ visible: false
+ examples:
+ - pk-lf-a1b2c3d4-e5f6-7890-abcd-ef1234567890
+ - 'LANGFUSE_PUBLIC_KEY="pk-lf-9f8e7d6c-5b4a-3210-fedc-ba0987654321"'
+ negative_examples:
+ - pk-lf-test
+ - pk-lf-
+ references:
+ - https://langfuse.com/docs/sdk/typescript
+ - https://langfuse.com/docs/get-started
diff --git a/crates/kingfisher-rules/data/rules/lemonsqueezy.yml b/crates/kingfisher-rules/data/rules/lemonsqueezy.yml
new file mode 100644
index 0000000..9ce3e62
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/lemonsqueezy.yml
@@ -0,0 +1,39 @@
+rules:
+ - name: LemonSqueezy API Key
+ id: kingfisher.lemonsqueezy.1
+ pattern: |
+ (?x)
+ \b
+ (?i:lemon.?squeezy|lemonsqueezy)
+ (?:.|[\n\r]){0,32}?
+ (?i:KEY|TOKEN|API)
+ (?:.|[\n\r]){0,32}?
+ (
+ eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9
+ \.
+ [A-Za-z0-9_-]{100,500}
+ \.
+ [A-Za-z0-9_-]{200,700}
+ )
+ min_entropy: 4.0
+ confidence: medium
+ examples:
+ - 'LEMONSQUEEZY_API_KEY="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJodHRwczovL2FwaS5sZW1vbnNxdWVlenkuY29tIiwiaXNzIjoiaHR0cHM6Ly9sZW1vbnNxdWVlenkuY29tIiwic3ViIjoiMTIzNCIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoxNzMwMDAwMDAwLCJzY29wZXMiOltdfQ.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"'
+ negative_examples:
+ - 'LEMONSQUEEZY_URL="https://api.lemonsqueezy.com"'
+ references:
+ - https://docs.lemonsqueezy.com/api
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.lemonsqueezy.com/v1/users/me
+ headers:
+ Authorization: 'Bearer {{ TOKEN }}'
+ Accept: application/vnd.api+json
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/miro.yml b/crates/kingfisher-rules/data/rules/miro.yml
new file mode 100644
index 0000000..dbc7f30
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/miro.yml
@@ -0,0 +1,42 @@
+rules:
+ - name: Miro Access Token
+ id: kingfisher.miro.1
+ pattern: |
+ (?x)
+ \b
+ (
+ eyJtaXJv
+ [A-Za-z0-9_=-]{10,}
+ _
+ [A-Za-z0-9_-]{20,}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 1
+ min_uppercase: 1
+ min_lowercase: 1
+ min_entropy: 3.5
+ confidence: medium
+ examples:
+ - eyJtaXJvLm9yaWdpbiI6ImV1MDEifQ_o-P91OccaII0A63CDSK--x21xiI
+ - 'MIRO_TOKEN="eyJtaXJvLm9yaWdpbiI6InVzMDEifQ_kL8m2Nq7RpWxYz3AbCdEfGhI"'
+ negative_examples:
+ - eyJtaXJv
+ - eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9
+ references:
+ - https://developers.miro.com/docs/rest-api-authorization
+ - https://developers.miro.com/reference/get-token-info
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.miro.com/v1/oauth-token
+ headers:
+ Accept: application/json
+ Authorization: 'Bearer {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/mixpanel.yml b/crates/kingfisher-rules/data/rules/mixpanel.yml
new file mode 100644
index 0000000..f49378c
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/mixpanel.yml
@@ -0,0 +1,44 @@
+rules:
+ - name: Mixpanel API Secret
+ id: kingfisher.mixpanel.1
+ pattern: |
+ (?x)
+ \b
+ (?i:mixpanel)
+ (?:.|[\n\r]){0,32}?
+ (?i:SECRET|API.?SECRET|PROJECT.?SECRET)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [a-zA-Z0-9]{32}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 2
+ min_lowercase: 2
+ min_entropy: 3.5
+ confidence: medium
+ examples:
+ - 'MIXPANEL_API_SECRET="a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"'
+ - |
+ mixpanel_secret: 'Ab1Cd2Ef3Gh4Ij5Kl6Mn7Op8Qr9St0Uv'
+ negative_examples:
+ - 'MIXPANEL_URL="https://api.mixpanel.com"'
+ - 'mixpanel_project_id=12345'
+ - 'MIXPANEL_TOKEN="a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"'
+ references:
+ - https://developer.mixpanel.com/reference/authentication
+ - https://developer.mixpanel.com/reference/overview
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://mixpanel.com/api/app/me
+ headers:
+ Authorization: 'Basic {{ TOKEN | append: ":" | b64enc }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/ringcentral.yml b/crates/kingfisher-rules/data/rules/ringcentral.yml
new file mode 100644
index 0000000..170089f
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/ringcentral.yml
@@ -0,0 +1,55 @@
+rules:
+ - name: RingCentral Client ID
+ id: kingfisher.ringcentral.1
+ pattern: |
+ (?x)
+ \b
+ (?i:ringcentral|ring.?central)
+ (?:.|[\n\r]){0,32}?
+ (?i:CLIENT.?ID|APP.?KEY|APP.?ID)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [A-Za-z0-9_-]{22}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 2
+ min_uppercase: 1
+ min_lowercase: 1
+ min_entropy: 3.5
+ confidence: medium
+ visible: false
+ examples:
+ - 'RINGCENTRAL_CLIENT_ID="aB1cD2eF3gH4iJ5kL6mN7o"'
+ negative_examples:
+ - 'RINGCENTRAL_URL="https://platform.ringcentral.com"'
+ references:
+ - https://developers.ringcentral.com/api-reference/
+
+ - name: RingCentral Client Secret
+ id: kingfisher.ringcentral.2
+ pattern: |
+ (?x)
+ \b
+ (?i:ringcentral|ring.?central)
+ (?:.|[\n\r]){0,32}?
+ (?i:CLIENT.?SECRET|APP.?SECRET)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [A-Za-z0-9_-]{22}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 2
+ min_uppercase: 1
+ min_lowercase: 1
+ min_entropy: 3.5
+ confidence: medium
+ examples:
+ - 'RINGCENTRAL_CLIENT_SECRET="xY9zW8vU7tS6rQ5pO4nM3l"'
+ negative_examples:
+ - 'RINGCENTRAL_URL="https://platform.ringcentral.com"'
+ references:
+ - https://developers.ringcentral.com/api-reference/
diff --git a/crates/kingfisher-rules/data/rules/shortcut.yml b/crates/kingfisher-rules/data/rules/shortcut.yml
new file mode 100644
index 0000000..6e84fa5
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/shortcut.yml
@@ -0,0 +1,49 @@
+rules:
+ - name: Shortcut API Token
+ id: kingfisher.shortcut.1
+ pattern: |
+ (?x)
+ \b
+ (?i:shortcut|clubhouse)
+ (?:.|[\n\r]){0,32}?
+ (?i:TOKEN|API)
+ (?:.|[\n\r]){0,32}?
+ \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.0
+ confidence: medium
+ examples:
+ - 'SHORTCUT_API_TOKEN="62dc7d80-a1b2-4c3d-8e5f-6a7b8c9d0e1f"'
+ - |
+ clubhouse_token = '0a1b2c3d-4e5f-6789-abcd-ef0123456789'
+ negative_examples:
+ - 'SHORTCUT_URL="https://app.shortcut.com"'
+ references:
+ - https://developer.shortcut.com/api/rest/v3
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.app.shortcut.com/api/v3/member
+ headers:
+ Shortcut-Token: '{{ TOKEN }}'
+ Content-Type: application/json
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/shutterstock.yml b/crates/kingfisher-rules/data/rules/shutterstock.yml
new file mode 100644
index 0000000..f7df056
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/shutterstock.yml
@@ -0,0 +1,42 @@
+rules:
+ - name: Shutterstock OAuth Token
+ id: kingfisher.shutterstock.1
+ pattern: |
+ (?xi)
+ \b
+ shutterstock
+ (?:.|[\n\r]){0,48}?
+ (?:ACCESS|TOKEN|BEARER)
+ (?:.|[\n\r]){0,32}?
+ (
+ v2/[A-Za-z0-9+/]{40,}={0,2}
+ )
+ pattern_requirements:
+ min_digits: 2
+ min_uppercase: 1
+ min_lowercase: 1
+ min_entropy: 3.0
+ confidence: medium
+ examples:
+ - 'SHUTTERSTOCK_TOKEN="v2/ODYwYmRlNzBiYjMzNTE2M2UyZTQvYTc0NjI3NjEvNjBiMQ"'
+ - |
+ shutterstock_access_token: 'v2/ZDk4YWUxMGQtZGYyYy00ZGQwLWJiOWMtOTM3Y2E1NTA1YjYx'
+ negative_examples:
+ - v2/short
+ - 'SHUTTERSTOCK_DOC_URL=https://api.shutterstock.com/v2/images'
+ references:
+ - https://api-reference.shutterstock.com/
+ - https://www.shutterstock.com/developers/documentation/authentication
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.shutterstock.com/v2/user
+ headers:
+ Authorization: 'Bearer {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/squarespace.yml b/crates/kingfisher-rules/data/rules/squarespace.yml
new file mode 100644
index 0000000..f66e010
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/squarespace.yml
@@ -0,0 +1,50 @@
+rules:
+ - name: Squarespace API Key
+ id: kingfisher.squarespace.1
+ pattern: |
+ (?x)
+ \b
+ (?i:squarespace)
+ (?:.|[\n\r]){0,32}?
+ (?i:KEY|TOKEN|API)
+ (?:.|[\n\r]){0,32}?
+ \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.0
+ confidence: medium
+ examples:
+ - 'SQUARESPACE_API_KEY="a1b2c3d4-e5f6-7890-abcd-ef1234567890"'
+ - |
+ squarespace_token: '62dc7d80-9a1b-4c3d-8e5f-6a7b8c9d0e1f'
+ negative_examples:
+ - 'SQUARESPACE_URL="https://www.squarespace.com"'
+ references:
+ - https://developers.squarespace.com/commerce-apis/overview
+ - https://developers.squarespace.com/commerce-apis/authentication-and-permissions
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.squarespace.com/1.0/authorization/website
+ headers:
+ Authorization: 'Bearer {{ TOKEN }}'
+ User-Agent: kingfisher
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/strava.yml b/crates/kingfisher-rules/data/rules/strava.yml
new file mode 100644
index 0000000..a69de3c
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/strava.yml
@@ -0,0 +1,44 @@
+rules:
+ - name: Strava Access Token
+ id: kingfisher.strava.1
+ pattern: |
+ (?x)
+ \b
+ (?i:strava)
+ (?:.|[\n\r]){0,32}?
+ (?i:ACCESS|AUTH)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [0-9a-f]{40}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 4
+ min_lowercase: 4
+ min_entropy: 3.5
+ confidence: medium
+ examples:
+ - 'STRAVA_ACCESS_TOKEN="83ebeabdec09f6670863766f792ead24d61fe3f9"'
+ - |
+ strava_auth_token: '1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b'
+ negative_examples:
+ - 'STRAVA_URL="https://www.strava.com/api/v3"'
+ - 'strava_client_id=12345'
+ - 'strava_refresh_token: "83ebeabdec09f6670863766f792ead24d61fe3f9"'
+ references:
+ - https://developers.strava.com/docs/authentication/
+ - https://developers.strava.com/docs/reference/#api-Athletes-getLoggedInAthlete
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://www.strava.com/api/v3/athlete
+ headers:
+ Authorization: 'Bearer {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/todoist.yml b/crates/kingfisher-rules/data/rules/todoist.yml
new file mode 100644
index 0000000..863edaa
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/todoist.yml
@@ -0,0 +1,41 @@
+rules:
+ - name: Todoist API Token
+ id: kingfisher.todoist.1
+ pattern: |
+ (?x)
+ \b
+ (?i:todoist)
+ (?:.|[\n\r]){0,32}?
+ (?i:TOKEN|API)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [0-9a-f]{40}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 4
+ min_entropy: 3.5
+ confidence: medium
+ examples:
+ - 'TODOIST_API_TOKEN="0123456789abcdef0123456789abcdef01234567"'
+ - |
+ todoist_token = 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0'
+ negative_examples:
+ - 'TODOIST_URL="https://api.todoist.com"'
+ references:
+ - https://developer.todoist.com/rest/v2/#overview
+ - https://developer.todoist.com/guides/#developing-with-todoist
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.todoist.com/rest/v2/projects
+ headers:
+ Authorization: 'Bearer {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/unsplash.yml b/crates/kingfisher-rules/data/rules/unsplash.yml
new file mode 100644
index 0000000..dcce896
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/unsplash.yml
@@ -0,0 +1,51 @@
+rules:
+ - name: Unsplash Access Key
+ id: kingfisher.unsplash.1
+ pattern: |
+ (?xi)
+ \b
+ unsplash
+ (?:.|[\n\r]){0,32}?
+ (?:
+ access
+ (?:.|[\n\r]){0,12}?
+ key
+ |
+ client
+ (?:.|[\n\r]){0,12}?
+ id
+ )
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [A-Za-z0-9_]{43}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 2
+ min_uppercase: 1
+ min_lowercase: 1
+ min_entropy: 3.5
+ confidence: medium
+ examples:
+ - 'UNSPLASH_ACCESS_KEY="Ab1Cd2Ef3Gh4Ij5Kl6Mn7Op8Qr9St0UvWxYz1234567"'
+ - |
+ unsplash_client_id = 'a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V'
+ negative_examples:
+ - 'UNSPLASH_URL="https://api.unsplash.com"'
+ references:
+ - https://unsplash.com/documentation
+ validation:
+ type: Http
+ content:
+ request:
+ method: GET
+ url: https://api.unsplash.com/photos?page=1&per_page=1
+ headers:
+ Accept-Version: v1
+ Authorization: 'Client-ID {{ TOKEN }}'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid
diff --git a/crates/kingfisher-rules/data/rules/wiz.yml b/crates/kingfisher-rules/data/rules/wiz.yml
new file mode 100644
index 0000000..4593f3f
--- /dev/null
+++ b/crates/kingfisher-rules/data/rules/wiz.yml
@@ -0,0 +1,72 @@
+rules:
+ - name: Wiz Client ID
+ id: kingfisher.wiz.1
+ pattern: |
+ (?x)
+ \b
+ (?i:wiz)
+ (?:.|[\n\r]){0,32}?
+ (?i:CLIENT.?ID)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [a-zA-Z0-9]{53}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 3
+ min_uppercase: 3
+ min_lowercase: 3
+ min_entropy: 4.0
+ confidence: medium
+ visible: false
+ examples:
+ - 'WIZ_CLIENT_ID="aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3aA4bB5cC6dD7eF"'
+ negative_examples:
+ - 'WIZ_URL="https://app.wiz.io"'
+ references:
+ - https://docs.wiz.io/wiz-docs/docs/using-the-wiz-api
+
+ - name: Wiz Client Secret
+ id: kingfisher.wiz.2
+ pattern: |
+ (?x)
+ \b
+ (?i:wiz)
+ (?:.|[\n\r]){0,32}?
+ (?i:CLIENT.?SECRET|SECRET)
+ (?:.|[\n\r]){0,32}?
+ \b
+ (
+ [a-zA-Z0-9]{64}
+ )
+ \b
+ pattern_requirements:
+ min_digits: 4
+ min_uppercase: 4
+ min_lowercase: 4
+ min_entropy: 4.0
+ confidence: medium
+ depends_on_rule:
+ - rule_id: kingfisher.wiz.1
+ variable: CLIENT_ID
+ examples:
+ - 'WIZ_CLIENT_SECRET="aB1cD2eF3gH4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3aA4bB5cC6dD7eE8fF9gG0hH1i"'
+ negative_examples:
+ - 'WIZ_URL="https://app.wiz.io"'
+ references:
+ - https://docs.wiz.io/wiz-docs/docs/using-the-wiz-api
+ validation:
+ type: Http
+ content:
+ request:
+ method: POST
+ url: https://auth.app.wiz.io/oauth/token
+ headers:
+ Content-Type: application/x-www-form-urlencoded
+ body: 'grant_type=client_credentials&client_id={{ CLIENT_ID }}&client_secret={{ TOKEN }}&audience=wiz-api'
+ response_matcher:
+ - report_response: true
+ - type: StatusMatch
+ status: [200]
+ - type: JsonValid