Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions review-enrichment/src/analyzers/secret-scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,18 @@ const RULES: Rule[] = [
re: /\b(?:fw|fpk)_[A-Za-z0-9]{20,}(?![A-Za-z0-9_])/,
confidence: "high",
},
{
// Pinecone API key: `pcsk_{5-6 char label}_{63 char secret}`.
kind: "pinecone_api_key",
re: /\bpcsk_[A-Za-z0-9]{5,6}_[A-Za-z0-9]{63}(?![A-Za-z0-9_])/,
confidence: "high",
},
{
// Tavily API key: `tvly-` + base62 body (alnum only; reject hyphen-continued identifiers).
kind: "tavily_api_key",
re: /\btvly-[A-Za-z0-9]{16,}(?![A-Za-z0-9_-])/,
confidence: "high",
},
{
// Google OAuth 2.0 client secret: `GOCSPX-` + 28 base64url chars.
kind: "google_oauth_client_secret",
Expand Down
36 changes: 36 additions & 0 deletions review-enrichment/test/secret-scan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,42 @@ test("scanPatch does not flag truncated Together/Fireworks keys or identifier co
assert.equal(scanPatch("src/config.ts", hunk([`const firepass = "fpk_${"b".repeat(19)}";`])).length, 0);
});

test("scanPatch flags Pinecone and Tavily API keys with high confidence", () => {
const fakePineconeKey = ["pcsk_", "T5Afk6", "_", "a".repeat(63)].join("");
const pineconeFindings = scanPatch("src/config.ts", hunk([`const pinecone = "${fakePineconeKey}";`]));
assert.equal(pineconeFindings.length, 1);
assert.equal(pineconeFindings[0].kind, "pinecone_api_key");
assert.equal(pineconeFindings[0].confidence, "high");

const fakeTavilyKey = "tvly-" + "a".repeat(16);
const tavilyFindings = scanPatch("src/config.ts", hunk([`const tavily = "${fakeTavilyKey}";`]));
assert.equal(tavilyFindings.length, 1);
assert.equal(tavilyFindings[0].kind, "tavily_api_key");
assert.equal(tavilyFindings[0].confidence, "high");
});

test("scanPatch does not flag malformed Pinecone/Tavily keys or identifier continuation", () => {
const shortLabel = ["pcsk_", "abcd", "_", "a".repeat(63)].join("");
assert.equal(scanPatch("src/config.ts", hunk([`const pinecone = "${shortLabel}";`])).length, 0);
const shortSecret = ["pcsk_", "T5Afk6", "_", "a".repeat(62)].join("");
assert.equal(scanPatch("src/config.ts", hunk([`const pinecone = "${shortSecret}";`])).length, 0);
const pineconeEmbedded = ["pcsk_", "T5Afk6", "_", "a".repeat(63), "X"].join("");
assert.equal(
scanPatch("src/config.ts", hunk([`const pinecone = "${pineconeEmbedded}";`])).some((f) => f.kind === "pinecone_api_key"),
false,
);

assert.equal(scanPatch("src/config.ts", hunk([`const tavily = "tvly-${"a".repeat(15)}";`])).length, 0);
assert.equal(
scanPatch("src/config.ts", hunk([`const tavily = "tvly-${"a".repeat(16)}_suffix";`])).some((f) => f.kind === "tavily_api_key"),
false,
);
assert.equal(
scanPatch("src/config.ts", hunk([`const tavily = "tvly-${"a".repeat(16)}-suffix";`])).some((f) => f.kind === "tavily_api_key"),
false,
);
});

test("scanPatch flags additional high-confidence SaaS/cloud/CI credential formats", () => {
const cases = [
["google_oauth_client_secret", "GOCSPX-" + b62(28)],
Expand Down
Loading