diff --git a/review-enrichment/src/analyzers/secret-scan.ts b/review-enrichment/src/analyzers/secret-scan.ts index 7209461f92..6205d10b39 100644 --- a/review-enrichment/src/analyzers/secret-scan.ts +++ b/review-enrichment/src/analyzers/secret-scan.ts @@ -271,6 +271,18 @@ const RULES: Rule[] = [ re: /\bwandb_v1_[A-Za-z0-9_]{77}(?![A-Za-z0-9_-])/, confidence: "high", }, + { + // xAI API key: `xai-` + base62 body (reject hyphen-continued identifiers). + kind: "xai_api_key", + re: /\bxai-[A-Za-z0-9]{16,}(?![A-Za-z0-9_-])/, + confidence: "high", + }, + { + // Deepgram API key: `dg.` + base62 body (reject dot/hyphen-continued identifiers). + kind: "deepgram_api_key", + re: /\bdg\.[A-Za-z0-9]{20,}(?![A-Za-z0-9_.-])/, + confidence: "high", + }, { // Google OAuth 2.0 client secret: `GOCSPX-` + 28 base64url chars. kind: "google_oauth_client_secret", diff --git a/review-enrichment/test/secret-scan.test.ts b/review-enrichment/test/secret-scan.test.ts index f26b16f56b..37ce152e2c 100644 --- a/review-enrichment/test/secret-scan.test.ts +++ b/review-enrichment/test/secret-scan.test.ts @@ -719,6 +719,46 @@ test("scanPatch does not flag truncated fal/W&B keys or identifier continuation" ); }); +test("scanPatch flags xAI and Deepgram API keys with high confidence", () => { + const fakeXaiKey = "xai-" + "a".repeat(16); + const xaiFindings = scanPatch("src/config.ts", hunk([`const xai = "${fakeXaiKey}";`])); + assert.equal(xaiFindings.length, 1); + assert.equal(xaiFindings[0].kind, "xai_api_key"); + assert.equal(xaiFindings[0].confidence, "high"); + + const fakeDeepgramKey = ["dg.", "b".repeat(20)].join(""); + const deepgramFindings = scanPatch("src/config.ts", hunk([`const deepgram = "${fakeDeepgramKey}";`])); + assert.equal(deepgramFindings.length, 1); + assert.equal(deepgramFindings[0].kind, "deepgram_api_key"); + assert.equal(deepgramFindings[0].confidence, "high"); +}); + +test("scanPatch does not flag truncated xAI/Deepgram keys or identifier continuation", () => { + assert.equal(scanPatch("src/config.ts", hunk([`const xai = "xai-${"a".repeat(15)}";`])).length, 0); + assert.equal( + scanPatch("src/config.ts", hunk([`const xai = "xai-${"a".repeat(16)}_suffix";`])).some((f) => f.kind === "xai_api_key"), + false, + ); + assert.equal( + scanPatch("src/config.ts", hunk([`const xai = "xai-${"a".repeat(16)}-suffix";`])).some((f) => f.kind === "xai_api_key"), + false, + ); + + assert.equal(scanPatch("src/config.ts", hunk([`const deepgram = "dg.${"b".repeat(19)}";`])).length, 0); + assert.equal( + scanPatch("src/config.ts", hunk([`const deepgram = "dg.${"b".repeat(20)}_suffix";`])).some((f) => f.kind === "deepgram_api_key"), + false, + ); + assert.equal( + scanPatch("src/config.ts", hunk([`const deepgram = "dg.${"b".repeat(20)}-suffix";`])).some((f) => f.kind === "deepgram_api_key"), + false, + ); + assert.equal( + scanPatch("src/config.ts", hunk([`const deepgram = "dg.${"b".repeat(20)}.suffix";`])).some((f) => f.kind === "deepgram_api_key"), + false, + ); +}); + test("scanPatch flags additional high-confidence SaaS/cloud/CI credential formats", () => { const cases = [ ["google_oauth_client_secret", "GOCSPX-" + b62(28)],