Skip to content

Commit 3b737ac

Browse files
committed
feat: show vault information in results
1 parent 58fb5d1 commit 3b737ac

File tree

4 files changed

+84
-3
lines changed

4 files changed

+84
-3
lines changed

src/lib/api-types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ export interface Incident {
2525
incident_url: string;
2626
total_occurrences: number;
2727
secret_vaulted: boolean;
28+
vault_type: string;
29+
vault_name: string;
30+
vault_path: string;
31+
vault_path_count: number;
2832
}
2933

3034
export interface EntityWithIncidents {

src/lib/ggshield-results-parser.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ function filterUriOccurrences(occurrences: Occurrence[]): Occurrence[] {
4545
* @param results ggshield scan results
4646
* @returns incidents diagnostics
4747
*/
48+
49+
const pluralize = (num: number, word: string, plural = word + "s") =>
50+
[1, -1].includes(Number(num)) ? word : plural;
51+
4852
export function parseGGShieldResults(
4953
results: GGShieldScanResults,
5054
): Diagnostic[] {
@@ -63,6 +67,22 @@ export function parseGGShieldResults(
6367
new Position(occurrence.line_start - 1, occurrence.index_start),
6468
new Position(occurrence.line_end - 1, occurrence.index_end),
6569
);
70+
71+
let vaultInfo = "";
72+
73+
if (incident.secret_vaulted) {
74+
if (incident.vault_path_count !== null) {
75+
vaultInfo += `Secret found in vault: YES (${incident.vault_path_count} ${pluralize(incident.vault_path_count, "location")})
76+
├─ Vault Type: ${incident.vault_type}
77+
├─ Vault Name: ${incident.vault_name}
78+
└─ Secret Path: ${incident.vault_path}`;
79+
} else {
80+
vaultInfo += "Secret found in vault: YES";
81+
}
82+
} else {
83+
vaultInfo += "Secret found in vault: NO";
84+
}
85+
6686
let diagnostic = new Diagnostic(
6787
range,
6888
`ggshield: ${occurrence.type}
@@ -73,11 +93,11 @@ Known by GitGuardian dashboard: ${incident.known_secret ? "YES" : "NO"}
7393
Total occurrences: ${incident.total_occurrences}
7494
Incident URL: ${incident.incident_url || "N/A"}
7595
Secret SHA: ${incident.ignore_sha}
76-
Secret in Secrets Manager: ${incident.secret_vaulted ? "YES" : "NO"}`,
96+
${vaultInfo}`,
7797
DiagnosticSeverity.Warning,
7898
);
7999

80-
diagnostic.source = "gitguardian";
100+
diagnostic.source = "\ngitguardian";
81101
diagnostics.push(diagnostic);
82102
},
83103
);

src/test/constants.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,48 @@ export const scanResultsWithUriIncident = `{
8585
"total_occurrences": 1,
8686
"secrets_engine_version": "2.126.0"
8787
}`;
88+
89+
export const scanResultsVaulted = `{
90+
"id":"test.py",
91+
"type":"path_scan",
92+
"entities_with_incidents":[
93+
{
94+
"mode":"FILE",
95+
"filename":"test.py",
96+
"incidents":[
97+
{
98+
"policy":"Secrets detection",
99+
"occurrences":[
100+
{
101+
"match":"DDACC73DdB04********************************************057c78317C39",
102+
"type":"apikey",
103+
"line_start":4,
104+
"line_end":4,
105+
"index_start":11,
106+
"index_end":79,
107+
"pre_line_start":4,
108+
"pre_line_end":4
109+
}
110+
],
111+
"type":"Generic High Entropy Secret",
112+
"validity":"no_checker",
113+
"ignore_sha":"38353eb1a2aac5b24f39ed67912234d4b4a2e23976d504a88b28137ed2b9185e",
114+
"total_occurrences":2,
115+
"incident_url":"",
116+
"known_secret":false,
117+
"secret_vaulted": true,
118+
"vault_type": "AWS Secrets Manager",
119+
"vault_name": "463175827647/us-west-2",
120+
"vault_path": "arn:aws:secretsmanager:us-west-2:463175827647:secret:xav-test-svef2q:pwd",
121+
"vault_path_count": 2
122+
123+
}
124+
],
125+
"total_incidents":1,
126+
"total_occurrences":1
127+
}
128+
],
129+
"total_incidents":1,
130+
"total_occurrences":1,
131+
"secrets_engine_version":"2.96.0"
132+
}`;

src/test/suite/results-parser.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { parseGGShieldResults } from "../../lib/ggshield-results-parser";
44
import { DiagnosticSeverity } from "vscode";
55
import {
66
scanResultsNoIncident,
7+
scanResultsVaulted,
78
scanResultsWithIncident,
89
scanResultsWithUriIncident,
910
} from "../constants";
@@ -17,14 +18,25 @@ suite("parseGGShieldResults", () => {
1718
const diagnostic = diagnostics[0];
1819
assert.ok(diagnostic.message.includes("apikey"));
1920
assert.ok(diagnostic.message.includes("Generic High Entropy Secret"));
20-
assert.ok(diagnostic.message.includes("Secret in Secrets Manager: NO"));
21+
assert.ok(diagnostic.message.includes("Secret found in vault: NO"));
2122
assert.strictEqual(diagnostic.range.start.line, 3);
2223
assert.strictEqual(diagnostic.range.start.character, 11);
2324
assert.strictEqual(diagnostic.range.end.line, 3);
2425
assert.strictEqual(diagnostic.range.end.character, 79);
2526
assert.strictEqual(diagnostic.severity, DiagnosticSeverity.Warning);
2627
});
2728

29+
test("Should parse vault information", () => {
30+
const diagnostics = parseGGShieldResults(
31+
JSON.parse(scanResultsVaulted),
32+
);
33+
const diagnostic = diagnostics[0];
34+
assert.ok(diagnostic.message.includes("Secret found in vault: YES"));
35+
assert.ok(diagnostic.message.includes("├─ Vault Type: AWS Secrets Manager"));
36+
assert.ok(diagnostic.message.includes("├─ Vault Name: 463175827647/us-west-2"));
37+
assert.ok(diagnostic.message.includes("└─ Secret Path: arn:aws:secretsmanager:us-west-2:463175827647:secret:xav-test-svef2q:pwd"));
38+
});
39+
2840
test("Should return an empty array if there are no incidents", () => {
2941
const diagnostics = parseGGShieldResults(JSON.parse(scanResultsNoIncident));
3042
assert.strictEqual(diagnostics.length, 0);

0 commit comments

Comments
 (0)