rules: - name: Plaid Client ID (helper) id: kingfisher.plaid.1 visible: false pattern: | (?xi) \b (?:plaid[\w-]{0,32})? (?:client[_-]?id|plaid[_-]?client[_-]?id) \b (?:\s*[:=]\s*|["']\s*:\s*["']|=\s*["']) \s* \b ( [a-z0-9]{24} ) \b min_entropy: 2.8 confidence: medium examples: - 'plaid_client_id="sd479fjropblyr5b4m2dutha"' references: - https://plaid.com/docs/api/institutions/ # ------------------------- - name: Plaid Secret (Production) id: kingfisher.plaid.2 pattern: | (?xi) \b plaid (?:.|[\n\r]){0,32}? (?:SECRET|PRIVATE|ACCESS|KEY|TOKEN|ACCESS_KEY) (?:.|[\n\r]){0,32}? \b ( [a-z0-9]{30} ) \b min_entropy: 3.2 confidence: medium pattern_requirements: min_digits: 2 min_lowercase: 6 ignore_if_contains: - changeme - example - test examples: - 'plaid_secret_key="wuxd6sw7ma4lv10xremyhz7ulf9owc"' references: - https://plaid.com/docs/api/institutions/ - https://plaid.com/docs/quickstart/glossary/ - https://plaid.com/docs/errors/invalid-input/ depends_on_rule: - rule_id: kingfisher.plaid.1 variable: CLIENT_ID validation: type: Http content: request: method: POST url: https://production.plaid.com/institutions/get headers: Accept: application/json Content-Type: application/json body: | { "client_id": "{{ CLIENT_ID | json_escape }}", "secret": "{{ TOKEN | json_escape }}", "count": 1, "offset": 0, "country_codes": ["US"] } response_matcher: - report_response: true - type: StatusMatch status: [200] - type: JsonValid # If keys are invalid, Plaid returns INVALID_API_KEYS (HTTP 400). - type: WordMatch negative: true words: - '"INVALID_API_KEYS"' - name: Plaid Secret (Sandbox) id: kingfisher.plaid.3 pattern: | (?xi) \b plaid (?:.|[\n\r]){0,32}? (?:SECRET|PRIVATE|ACCESS|KEY|TOKEN|ACCESS_KEY) (?:.|[\n\r]){0,32}? \b ( [a-z0-9]{30} ) \b min_entropy: 3.2 confidence: medium pattern_requirements: min_digits: 2 min_lowercase: 6 ignore_if_contains: - changeme - example - test examples: - 'PLAID_SECRET="wuxd6sw7ma4lv10xremyhz7ulf9owc"' references: - https://plaid.com/docs/api/institutions/ - https://plaid.com/docs/quickstart/glossary/ - https://plaid.com/docs/errors/invalid-input/ depends_on_rule: - rule_id: kingfisher.plaid.1 variable: CLIENT_ID validation: type: Http content: request: method: POST url: https://sandbox.plaid.com/institutions/get headers: Accept: application/json Content-Type: application/json body: | { "client_id": "{{ CLIENT_ID | json_escape }}", "secret": "{{ TOKEN | json_escape }}", "count": 1, "offset": 0, "country_codes": ["US"] } response_matcher: - report_response: true - type: StatusMatch status: [200] - type: JsonValid # If keys are invalid, Plaid returns INVALID_API_KEYS (HTTP 400). - type: WordMatch negative: true words: - '"INVALID_API_KEYS"' # ------------------------- # Plaid access tokens (env-specific) # Validate using /accounts/get (requires client_id + secret + access_token) # ------------------------- - name: Plaid Access Token (Production) id: kingfisher.plaid.4 pattern: | (?xi) \b ( access-production- [0-9a-f]{8}- [0-9a-f]{4}- [0-9a-f]{4}- [0-9a-f]{4}- [0-9a-f]{12} ) \b min_entropy: 3.4 confidence: medium examples: - 'plaid_api_token="access-production-822f6ce0-ee1a-221e-3cd8-f3ce5094b3e2"' references: - https://plaid.com/docs/quickstart/glossary/ - https://plaid.com/docs/api/accounts/ - https://plaid.com/docs/errors/invalid-input/ depends_on_rule: - rule_id: kingfisher.plaid.1 variable: CLIENT_ID - rule_id: kingfisher.plaid.2 variable: PLAID_SECRET validation: type: Http content: request: method: POST url: https://production.plaid.com/accounts/get headers: Accept: application/json Content-Type: application/json body: | { "client_id": "{{ CLIENT_ID | json_escape }}", "secret": "{{ PLAID_SECRET | json_escape }}", "access_token": "{{ TOKEN | json_escape }}" } response_matcher: - report_response: true - type: StatusMatch status: [200] - type: JsonValid - type: WordMatch match_all_words: true words: - '"accounts"' - type: WordMatch negative: true match_all_words: false words: - '"INVALID_ACCESS_TOKEN"' - '"INVALID_API_KEYS"' - name: Plaid Access Token (Sandbox) id: kingfisher.plaid.5 pattern: | (?xi) \b ( access-sandbox- [0-9a-f]{8}- [0-9a-f]{4}- [0-9a-f]{4}- [0-9a-f]{4}- [0-9a-f]{12} ) \b min_entropy: 3.4 confidence: medium examples: - 'PLAID_ACCESS_TOKEN="access-sandbox-822f6ce0-ee1a-221e-3cd8-f3ce5094b3e2"' references: - https://plaid.com/docs/quickstart/glossary/ - https://plaid.com/docs/api/accounts/ - https://plaid.com/docs/errors/invalid-input/ depends_on_rule: - rule_id: kingfisher.plaid.1 variable: CLIENT_ID - rule_id: kingfisher.plaid.3 variable: PLAID_SECRET validation: type: Http content: request: method: POST url: https://sandbox.plaid.com/accounts/get headers: Accept: application/json Content-Type: application/json body: | { "client_id": "{{ CLIENT_ID | json_escape }}", "secret": "{{ PLAID_SECRET | json_escape }}", "access_token": "{{ TOKEN | json_escape }}" } response_matcher: - report_response: true - type: StatusMatch status: [200] - type: JsonValid - type: WordMatch match_all_words: true words: - '"accounts"' - type: WordMatch negative: true match_all_words: false words: - '"INVALID_ACCESS_TOKEN"' - '"INVALID_API_KEYS"'