Skip to content

Commit 3bc69e0

Browse files
committed
feat(policies): add fixed_version field to vulnerability finding schema
Add an optional fixed_version string field to PolicyVulnerabilityFinding, allowing policies to report which version fixes a given vulnerability. The field is optional and can be set via object.union in Rego policies, consistent with other optional fields like recommendation and cvss_v3_score. Signed-off-by: Miguel Martinez Trivino <miguel@chainloop.dev>
1 parent 62867c0 commit 3bc69e0

7 files changed

Lines changed: 95 additions & 5 deletions

File tree

app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/api/gen/jsonschema/attestation.v1.PolicyVulnerabilityFinding.jsonschema.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/api/gen/jsonschema/attestation.v1.PolicyVulnerabilityFinding.schema.json

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go

Lines changed: 14 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/attestation/crafter/api/attestation/v1/crafting_state.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ message PolicyVulnerabilityFinding {
332332
repeated string cwes = 6;
333333
// Suggested fix or upgrade path
334334
string recommendation = 7;
335+
// Version that fixes the vulnerability (e.g., "2.0.1", "1.3.4-patch1")
336+
string fixed_version = 8;
335337
}
336338

337339
// Output schema for SAST findings from policy evaluation.

pkg/policies/engine/rego/builtins/vulnerability_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,23 @@ result := object.union(
6060
"recommendation": "upgrade to v2.0.0",
6161
},
6262
},
63+
{
64+
name: "combined with object.union for fixed_version",
65+
policy: `package test
66+
import rego.v1
67+
68+
result := object.union(
69+
chainloop.vulnerability("CVE found", "CVE-2024-5678", "pkg:npm/foo@1.0", "HIGH"),
70+
{"fixed_version": "1.0.1"},
71+
)`,
72+
expected: map[string]any{
73+
"message": "CVE found",
74+
"external_id": "CVE-2024-5678",
75+
"package_purl": "pkg:npm/foo@1.0",
76+
"severity": "HIGH",
77+
"fixed_version": "1.0.1",
78+
},
79+
},
6380
{
6481
name: "with sprintf interpolation",
6582
policy: `package test

pkg/policies/findings/registry_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,27 @@ func TestValidateFinding(t *testing.T) {
7474
assert.InDelta(t, 9.8, f.GetCvssV3Score(), 0.01)
7575
},
7676
},
77+
{
78+
name: "valid vulnerability finding with fixed_version",
79+
findingType: "VULNERABILITY",
80+
raw: map[string]any{
81+
"message": "Found CVE-2024-5678",
82+
"external_id": "CVE-2024-5678",
83+
"package_purl": "pkg:golang/example.com/lib@v1.0.0",
84+
"severity": "HIGH",
85+
"fixed_version": "1.0.1",
86+
},
87+
checkFn: func(t *testing.T, msg interface{}) {
88+
t.Helper()
89+
f, ok := msg.(*v1.PolicyVulnerabilityFinding)
90+
require.True(t, ok)
91+
assert.Equal(t, "Found CVE-2024-5678", f.GetMessage())
92+
assert.Equal(t, "CVE-2024-5678", f.GetExternalId())
93+
assert.Equal(t, "pkg:golang/example.com/lib@v1.0.0", f.GetPackagePurl())
94+
assert.Equal(t, "HIGH", f.GetSeverity())
95+
assert.Equal(t, "1.0.1", f.GetFixedVersion())
96+
},
97+
},
7798
{
7899
name: "vulnerability finding missing required field",
79100
findingType: "VULNERABILITY",

0 commit comments

Comments
 (0)