diff --git a/crates/kingfisher-rules/data/rules/vercel.yml b/crates/kingfisher-rules/data/rules/vercel.yml index 7538d47..49e6cad 100644 --- a/crates/kingfisher-rules/data/rules/vercel.yml +++ b/crates/kingfisher-rules/data/rules/vercel.yml @@ -268,24 +268,29 @@ rules: skip_if_missing: true confidence: medium min_entropy: 3.5 + # GET /v1/models returns the catalog without verifying the token (always 200). + # Use POST /v1/chat/completions with a minimal request instead; invalid/revoked + # keys return 401. validation: type: Http content: request: - method: GET - url: https://ai-gateway.vercel.sh/v1/models + method: POST + url: https://ai-gateway.vercel.sh/v1/chat/completions headers: Authorization: "Bearer {{TOKEN}}" Content-Type: application/json + body: '{"model":"openai/gpt-3.5-turbo","messages":[{"role":"user","content":"x"}],"max_tokens":1}' response_matcher: - report_response: true - type: StatusMatch - status: [200] + status: [200, 403] - type: JsonValid - type: WordMatch words: - - '"data"' - match_all_words: true + - '"choices"' + - 'valid credit card' + match_all_words: false references: - https://vercel.com/docs/ai-gateway/authentication-and-byok/authentication - https://vercel.com/docs/ai-gateway/openai-compat/rest-api diff --git a/src/reporter.rs b/src/reporter.rs index d91401a..79ddf99 100644 --- a/src/reporter.rs +++ b/src/reporter.rs @@ -48,9 +48,7 @@ fn extract_template_vars(text: &str) -> BTreeSet { // Match {{ VAR }} or {{ VAR | filter }} patterns; return VAR uppercased. let re = regex::Regex::new(r"\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*(?:\|[^}]*)?\}\}") .expect("template var regex should compile"); - re.captures_iter(text) - .filter_map(|cap| cap.get(1).map(|m| m.as_str().to_uppercase())) - .collect() + re.captures_iter(text).filter_map(|cap| cap.get(1).map(|m| m.as_str().to_uppercase())).collect() } fn required_vars_for_validation(validation: &crate::rules::Validation) -> BTreeSet {