Skip to content

Commit 2cf85f1

Browse files
committed
fix: builder.id resolves to commons-release-plugin version
1 parent 92c9d69 commit 2cf85f1

7 files changed

Lines changed: 75 additions & 6 deletions

File tree

pom.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,25 @@
320320
</includes>
321321
</resource>
322322
</resources>
323+
<testResources>
324+
<!-- Filter the attestation fixture and plugin coordinate file so they carry the current plugin version. -->
325+
<testResource>
326+
<directory>src/test/resources</directory>
327+
<filtering>true</filtering>
328+
<includes>
329+
<include>attestations/**</include>
330+
<include>plugin.properties</include>
331+
</includes>
332+
</testResource>
333+
<testResource>
334+
<directory>src/test/resources</directory>
335+
<filtering>false</filtering>
336+
<excludes>
337+
<exclude>attestations/**</exclude>
338+
<exclude>plugin.properties</exclude>
339+
</excludes>
340+
</testResource>
341+
</testResources>
323342
<pluginManagement>
324343
<plugins>
325344
<plugin>

src/main/java/org/apache/commons/release/plugin/mojos/BuildAttestationMojo.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.apache.maven.plugin.AbstractMojo;
5353
import org.apache.maven.plugin.MojoExecutionException;
5454
import org.apache.maven.plugin.MojoFailureException;
55+
import org.apache.maven.plugin.descriptor.PluginDescriptor;
5556
import org.apache.maven.plugins.annotations.LifecyclePhase;
5657
import org.apache.maven.plugins.annotations.Mojo;
5758
import org.apache.maven.plugins.annotations.Parameter;
@@ -165,6 +166,12 @@ public class BuildAttestationMojo extends AbstractMojo {
165166
*/
166167
@Parameter(property = "commons.release.signAttestation", defaultValue = "true")
167168
private boolean signAttestation;
169+
/**
170+
* Descriptor of this plugin; used to fill in {@code builder.id} with the plugin's own
171+
* Package URL so that consumers can resolve the exact code that produced the provenance.
172+
*/
173+
@Parameter(defaultValue = "${plugin}", readonly = true)
174+
private PluginDescriptor pluginDescriptor;
168175
/**
169176
* GPG signer used for signing; lazily initialized from plugin parameters when {@code null}.
170177
*/
@@ -225,8 +232,10 @@ public void execute() throws MojoFailureException, MojoExecutionException {
225232
final BuildDefinition buildDefinition = new BuildDefinition()
226233
.setExternalParameters(BuildDefinitions.externalParameters(session))
227234
.setResolvedDependencies(getBuildDependencies());
235+
final String builderId = String.format("pkg:maven/%s/%s@%s",
236+
pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(), pluginDescriptor.getVersion());
228237
final RunDetails runDetails = new RunDetails()
229-
.setBuilder(new Builder())
238+
.setBuilder(new Builder().setId(builderId))
230239
.setMetadata(getBuildMetadata());
231240
final Provenance provenance = new Provenance()
232241
.setBuildDefinition(buildDefinition)
@@ -451,6 +460,15 @@ void setSignAttestation(final boolean signAttestation) {
451460
this.signAttestation = signAttestation;
452461
}
453462

463+
/**
464+
* Sets the plugin descriptor. Intended for testing.
465+
*
466+
* @param pluginDescriptor the plugin descriptor
467+
*/
468+
void setPluginDescriptor(final PluginDescriptor pluginDescriptor) {
469+
this.pluginDescriptor = pluginDescriptor;
470+
}
471+
454472
/**
455473
* Sets the GPG signer used for signing. Intended for testing.
456474
*

src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Builder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class Builder {
3636
private List<ResourceDescriptor> builderDependencies = new ArrayList<>();
3737
/** Identifier URI of the builder. */
3838
@JsonProperty("id")
39-
private String id = "https://commons.apache.org/builds/0.1.0";
39+
private String id;
4040
/** Map of build platform component names to their versions. */
4141
@JsonProperty("version")
4242
private Map<String, String> version = new HashMap<>();

src/site/markdown/slsa/v0.1.0.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,11 @@ These are appended after the build tool entries above.
134134

135135
### Builder
136136

137-
The `builder.id` is always `https://commons.apache.org/builds/0.1.0`.
138-
It represents the commons-release-plugin acting as the build platform.
137+
The `builder.id` is the [Package URL](https://github.com/package-url/purl-spec) of the
138+
`commons-release-plugin` release that produced the attestation, e.g.
139+
`pkg:maven/org.apache.commons/commons-release-plugin@1.9.3`. It identifies the trust boundary of
140+
the "build platform": the exact plugin code that emitted the provenance. Verifiers can resolve the
141+
PURL to the signed artifact on Maven Central to inspect the builder.
139142

140143
## Subjects
141144

@@ -256,7 +259,7 @@ contains that envelope.
256259
},
257260
"runDetails": {
258261
"builder": {
259-
"id": "https://commons.apache.org/builds/0.1.0",
262+
"id": "pkg:maven/org.apache.commons/commons-release-plugin@1.9.3",
260263
"builderDependencies": [],
261264
"version": {}
262265
},

src/test/java/org/apache/commons/release/plugin/mojos/BuildAttestationMojoTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.apache.maven.model.Model;
5656
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
5757
import org.apache.maven.plugin.MojoExecutionException;
58+
import org.apache.maven.plugin.descriptor.PluginDescriptor;
5859
import org.apache.maven.plugins.gpg.AbstractGpgSigner;
5960
import org.apache.maven.project.MavenProject;
6061
import org.apache.maven.project.MavenProjectHelper;
@@ -76,6 +77,7 @@ public class BuildAttestationMojoTest {
7677
private static JsonNode expectedStatement;
7778
@TempDir
7879
private static Path localRepositoryPath;
80+
private static PluginDescriptor pluginDescriptor;
7981
private static RepositorySystemSession repoSession;
8082

8183
private static void assertStatementContent(final JsonNode statement) {
@@ -111,6 +113,7 @@ private static void configureBuildAttestationMojo(final BuildAttestationMojo moj
111113
mojo.setScmConnectionUrl("scm:git:https://github.com/apache/commons-text.git");
112114
mojo.setMavenHome(new File(System.getProperty("maven.home", ".")));
113115
mojo.setAlgorithmNames("SHA-512,SHA-256,SHA-1,MD5");
116+
mojo.setPluginDescriptor(pluginDescriptor);
114117
mojo.setSignAttestation(signAttestation);
115118
mojo.setSigner(createMockSigner());
116119
}
@@ -209,6 +212,14 @@ static void setup() throws Exception {
209212
try (InputStream in = BuildAttestationMojoTest.class.getResourceAsStream("/attestations/commons-text-1.4.intoto.json")) {
210213
expectedStatement = OBJECT_MAPPER.readTree(in);
211214
}
215+
final Properties pluginProps = new Properties();
216+
try (InputStream in = BuildAttestationMojoTest.class.getResourceAsStream("/plugin.properties")) {
217+
pluginProps.load(in);
218+
}
219+
pluginDescriptor = new PluginDescriptor();
220+
pluginDescriptor.setGroupId(pluginProps.getProperty("plugin.groupId"));
221+
pluginDescriptor.setArtifactId(pluginProps.getProperty("plugin.artifactId"));
222+
pluginDescriptor.setVersion(pluginProps.getProperty("plugin.version"));
212223
}
213224

214225
@Test

src/test/resources/attestations/commons-text-1.4.intoto.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@
175175
},
176176
"runDetails": {
177177
"builder": {
178-
"id": "https://commons.apache.org/builds/0.1.0",
178+
"id": "pkg:maven/${project.groupId}/${project.artifactId}@${project.version}",
179179
"builderDependencies": [],
180180
"version": {}
181181
},
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one or more
2+
# contributor license agreements. See the NOTICE file distributed with
3+
# this work for additional information regarding copyright ownership.
4+
# The ASF licenses this file to You under the Apache License, Version 2.0
5+
# (the "License"); you may not use this file except in compliance with
6+
# the License. You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
plugin.groupId=${project.groupId}
17+
plugin.artifactId=${project.artifactId}
18+
plugin.version=${project.version}

0 commit comments

Comments
 (0)