Skip to content

Commit 73ce97c

Browse files
committed
feat: Adds experimental support for package provenance in test/sbom
1 parent bba54d0 commit 73ce97c

File tree

10 files changed

+96
-11
lines changed

10 files changed

+96
-11
lines changed

cliv2/go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ require (
1111
github.com/pkg/errors v0.9.1
1212
github.com/rs/zerolog v1.34.0
1313
github.com/snyk/cli-extension-ai-bom v0.0.0-20251017132403-1df5f92a72ae
14-
github.com/snyk/cli-extension-dep-graph v0.0.0-20250321153619-9390ab5e348e
14+
github.com/snyk/cli-extension-dep-graph v0.0.0-20251015130327-019666738659
1515
github.com/snyk/cli-extension-iac v0.0.0-20250829110702-b41ac109dab0
1616
github.com/snyk/cli-extension-iac-rules v0.0.0-20250829110455-1260348bc188
1717
github.com/snyk/cli-extension-os-flows v0.0.0-20250915102829-6a59c2ef7e88
18-
github.com/snyk/cli-extension-sbom v0.0.0-20250801142135-ae472dafa4cd
18+
github.com/snyk/cli-extension-sbom v0.0.0-20251015130320-94416bf727b1
1919
github.com/snyk/container-cli v0.0.0-20250321132345-1e2e01681dd7
2020
github.com/snyk/error-catalog-golang-public v0.0.0-20251008132755-b542bb643649
2121
github.com/snyk/go-application-framework v0.0.0-20251016104433-d98d8780ade2

cliv2/go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,8 @@ github.com/snyk/cli-extension-ai-bom v0.0.0-20251017132403-1df5f92a72ae h1:GVXq0
12661266
github.com/snyk/cli-extension-ai-bom v0.0.0-20251017132403-1df5f92a72ae/go.mod h1:YvlGYA6i/aXDY68ps/X/XvkN8JGZ8T6eKFNdPE2y3oI=
12671267
github.com/snyk/cli-extension-dep-graph v0.0.0-20250321153619-9390ab5e348e h1:lYBeDqyAmb7NPfcLZJb1rcc+BrWhX5Ct9isQO1O4mSc=
12681268
github.com/snyk/cli-extension-dep-graph v0.0.0-20250321153619-9390ab5e348e/go.mod h1:9Zpe+B8SCkWFjpDR3ckFJl1XuMyxysWebKhyAIj7EyI=
1269+
github.com/snyk/cli-extension-dep-graph v0.0.0-20251015130327-019666738659 h1:8dOsSZ2t56CXJCTQCf/r8CQ2+SwmIFa1YNq1pZ/Sqks=
1270+
github.com/snyk/cli-extension-dep-graph v0.0.0-20251015130327-019666738659/go.mod h1:9Zpe+B8SCkWFjpDR3ckFJl1XuMyxysWebKhyAIj7EyI=
12691271
github.com/snyk/cli-extension-iac v0.0.0-20250829110702-b41ac109dab0 h1:ecGoMisVTnz5xRnt9yXW2hlRrIyYM123yMt1NeNEo6s=
12701272
github.com/snyk/cli-extension-iac v0.0.0-20250829110702-b41ac109dab0/go.mod h1:tLxyhtrRiEvbSLQ6PbCsl29ZXK6s2aunRuL6cSe/8cE=
12711273
github.com/snyk/cli-extension-iac-rules v0.0.0-20250829110455-1260348bc188 h1:UoyD7cB9XZVHPTRugsmCt6rBvAw5IoiBjI8go2qj1pk=
@@ -1274,6 +1276,8 @@ github.com/snyk/cli-extension-os-flows v0.0.0-20250915102829-6a59c2ef7e88 h1:m6k
12741276
github.com/snyk/cli-extension-os-flows v0.0.0-20250915102829-6a59c2ef7e88/go.mod h1:dFrXORRzFNF+tJ/Z51MPEeWi3IU5MuLWkt1L3dxDMG4=
12751277
github.com/snyk/cli-extension-sbom v0.0.0-20250801142135-ae472dafa4cd h1:bZg7Zkctm2tvaznI8A4/0fFOZMgglNAIFmIIlRz16W0=
12761278
github.com/snyk/cli-extension-sbom v0.0.0-20250801142135-ae472dafa4cd/go.mod h1:zyKDBaETfZyI7BfIjPnezH3QX2seQrR/d7NM5W6LV9s=
1279+
github.com/snyk/cli-extension-sbom v0.0.0-20251015130320-94416bf727b1 h1:PgO1Cz/VSFN2RIHz/MDQU25wjf8rSrwTW6lX6D+j8HI=
1280+
github.com/snyk/cli-extension-sbom v0.0.0-20251015130320-94416bf727b1/go.mod h1:zyKDBaETfZyI7BfIjPnezH3QX2seQrR/d7NM5W6LV9s=
12771281
github.com/snyk/code-client-go v1.24.1 h1:FTCVxRq8kNryq0xKOW8vqEU6s1iWwyaq7zvEN7q0Gn0=
12781282
github.com/snyk/code-client-go v1.24.1/go.mod h1:uMlmMToe4uuNhNLs+yxjM3WFbytna+ytDWhpbnNwTSk=
12791283
github.com/snyk/container-cli v0.0.0-20250321132345-1e2e01681dd7 h1:/2+2piwQtB9fEJCkXEOjboZjY+77lQfnvqBZ/60xNHk=

help/cli-commands/sbom.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The `snyk sbom` feature requires an internet connection.
1010

1111
## Usage
1212

13-
`$ snyk sbom --format=<cyclonedx1.4+json|cyclonedx1.4+xml|cyclonedx1.5+json|cyclonedx1.5+xml|cyclonedx1.6+json|cyclonedx1.6+xml|spdx2.3+json> [--org=<ORG_ID>] [--file=<FILE>] [--unmanaged] [--dev] [--all-projects] [--name=<NAME>] [--version=<VERSION>] [--exclude=<NAME>[,<NAME>...]] [--detection-depth=<DEPTH>] [--prune-repeated-subdependencies|-p] [--maven-aggregate-project] [--scan-unmanaged] [--scan-all-unmanaged] [--sub-project=<NAME>] [--gradle-sub-project=<NAME>] [--all-sub-projects] [--configuration-matching=<CONFIGURATION_REGEX>] [--configuration-attributes=<ATTRIBUTE>[,<ATTRIBUTE>]] [--init-script=<FILE>] [--json-file-output=<OUTPUT_FILE_PATH>] [<TARGET_DIRECTORY>]`
13+
`$ snyk sbom --format=<cyclonedx1.4+json|cyclonedx1.4+xml|cyclonedx1.5+json|cyclonedx1.5+xml|cyclonedx1.6+json|cyclonedx1.6+xml|spdx2.3+json> [--org=<ORG_ID>] [--file=<FILE>] [--unmanaged] [--dev] [--all-projects] [--name=<NAME>] [--version=<VERSION>] [--exclude=<NAME>[,<NAME>...]] [--detection-depth=<DEPTH>] [--prune-repeated-subdependencies|-p] [--maven-aggregate-project] [--scan-unmanaged] [--scan-all-unmanaged] [--sub-project=<NAME>] [--gradle-sub-project=<NAME>] [--all-sub-projects] [--configuration-matching=<CONFIGURATION_REGEX>] [--configuration-attributes=<ATTRIBUTE>[,<ATTRIBUTE>]] [--init-script=<FILE>] [--json-file-output=<OUTPUT_FILE_PATH>] [--include-provenance] [<TARGET_DIRECTORY>]`
1414

1515
## Description
1616

@@ -146,6 +146,14 @@ Auto-detect Maven, JAR, WAR, and AAR files recursively from the current folder.
146146

147147
**Note**: Custom-built JAR files, even with open-source dependencies, are not supported.
148148

149+
### `--include-provenance`
150+
151+
**Experimental:** Enable provenance generation for Maven artifacts during analysis. This generates cryptographic fingerprints for scanned artifacts to help with vulnerability matching and supply chain security.
152+
153+
**Note:** This requires the dependency artifacts to be present in your local Maven repository, via `mvn clean install` or similar commands.
154+
155+
Default: false
156+
149157
## Options for Gradle projects
150158

151159
### `--sub-project=<NAME>`, `--gradle-sub-project=<NAME>`

help/cli-commands/test.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ Auto-detect Maven, JAR, WAR, and AAR files recursively from the current folder.
250250

251251
**Note**: Custom-built JAR files, even with open-source dependencies, are not supported.
252252

253+
### `--include-provenance`
254+
255+
**Experimental:** Enable provenance generation for Maven artifacts during analysis. This generates cryptographic fingerprints for scanned artifacts to help with vulnerability matching and supply chain security.
256+
257+
**Note:** This requires the dependency artifacts to be present in your local Maven repository, via `mvn clean install` or similar commands.
258+
259+
Default: false
260+
253261
## Options for Gradle projects
254262

255263
**Note:** If you see the invalid string length error, refer to [Invalid string length error when scanning projects](https://docs.snyk.io/snyk-cli/scan-and-maintain-projects-using-the-cli/invalid-string-length-error-when-scanning-projects)

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
"snyk-go-plugin": "1.23.0",
122122
"snyk-gradle-plugin": "5.1.0",
123123
"snyk-module": "3.1.0",
124-
"snyk-mvn-plugin": "4.3.1",
124+
"snyk-mvn-plugin": "4.3.2",
125125
"snyk-nodejs-lockfile-parser": "2.3.1",
126126
"snyk-nodejs-plugin": "1.4.4",
127127
"snyk-nuget-plugin": "2.11.3",

src/cli/args.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ export function args(rawArgv: string[]): Args {
213213
'all-projects',
214214
'yarn-workspaces',
215215
'maven-aggregate-project',
216+
'include-provenance',
217+
'fingerprint-algorithm',
216218
'detection-depth',
217219
'init-script',
218220
'integration-name',

src/lib/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export interface Options {
5555
allSubProjects?: boolean;
5656
mavenAggregateProject?: boolean;
5757
mavenVerboseIncludeAllVersions?: boolean;
58+
includeProvenance?: boolean;
59+
fingerprintAlgorithm?: string;
5860
'project-name'?: string;
5961
'show-vulnerable-paths'?: string;
6062
packageManager?: SupportedPackageManagers;
@@ -273,6 +275,8 @@ export type SupportedUserReachableFacingCliArgs =
273275
| 'trust-policies'
274276
| 'yarn-workspaces'
275277
| 'maven-aggregate-project'
278+
| 'include-provenance'
279+
| 'fingerprint-algorithm'
276280
| 'gradle-normalize-deps';
277281

278282
export enum SupportedCliCommands {

test/jest/acceptance/snyk-sbom/maven-options.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,29 @@ describe('snyk sbom: maven options (mocked server only)', () => {
8989
);
9090
});
9191

92+
// This is only testing that the flag is accepted and passed through,
93+
// provenance data requires artifacts to be present in the local repository.
94+
test('`sbom --include-provenance` flag is accepted and passed through', async () => {
95+
server.setFeatureFlag('enableMavenDverboseExhaustiveDeps', false);
96+
const sbom = await runSnykSbomCliCycloneDxJsonForFixture(
97+
'maven-print-graph',
98+
'--file=pom.xml',
99+
env,
100+
);
101+
102+
expect(sbom.metadata.component.name).toEqual(
103+
'io.snyk.example:test-project',
104+
);
105+
expect(sbom.dependencies.length).toBeGreaterThanOrEqual(7);
106+
expect(sbom.dependencies[2].ref).toEqual(
107+
'commons-discovery:[email protected]',
108+
);
109+
expect(sbom.dependencies[2].dependsOn.length).toEqual(1);
110+
expect(sbom.dependencies[2].dependsOn[0]).toEqual(
111+
'commons-logging:[email protected]',
112+
);
113+
});
114+
92115
test('`sbom --scan-unmanaged --file=<NAME>` fails to generate an SBOM for user defined JAR file', async () => {
93116
const sbom = await runSnykSbomCliCycloneDxJsonForFixture(
94117
'maven-jars',

test/jest/acceptance/snyk-test/print-graph.spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,42 @@ describe('print graph', () => {
7878
expect(depGraph.pkgs.length).toBeGreaterThanOrEqual(3);
7979
});
8080

81+
test('`snyk test --print-graph --include-provenance` includes purl in package info for Maven projects', async () => {
82+
// Note: --include-provenance triggers purl generation for Maven artifacts.
83+
// If artifacts are present in the local Maven repository, checksums would be
84+
// included in the purl (e.g., pkg:maven/group/artifact@version?checksum=sha256:...).
85+
// This test verifies purl generation without requiring artifacts to be installed,
86+
// so we only check for the presence of purls, not checksum qualifiers.
87+
const project = await createProjectFromFixture('maven-print-graph');
88+
89+
const { code, stdout } = await runSnykCLI(
90+
'test --print-graph --include-provenance',
91+
{
92+
cwd: project.path(),
93+
},
94+
);
95+
96+
expect(code).toEqual(0);
97+
98+
const depGraph = JSON.parse(
99+
stdout.split('DepGraph data:')[1]?.split('DepGraph target:')[0],
100+
);
101+
102+
// Verify all packages have a purl
103+
for (const pkg of depGraph.pkgs) {
104+
expect(pkg.info.purl).toBeDefined();
105+
expect(pkg.info.purl).toMatch(/^pkg:maven\//);
106+
}
107+
108+
// Find packages with known dependencies from maven-print-graph fixture
109+
const axisPackage = depGraph.pkgs.find((pkg) => pkg.id === 'axis:[email protected]');
110+
111+
// Verify axis package has purl -- using toMatch in case dependency _has_ been
112+
// resolved by some other fixture.
113+
expect(axisPackage).toBeDefined();
114+
expect(axisPackage.info.purl).toMatch(/^pkg:maven\/axis\/axis@1\.4/);
115+
});
116+
81117
test('`snyk test --print-graph --all-projects` should not prune dependencies', async () => {
82118
const project = await createProjectFromWorkspace('maven-many-paths');
83119

0 commit comments

Comments
 (0)