-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: AdamKorcz <[email protected]>
- Loading branch information
Showing
3 changed files
with
281 additions
and
0 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
internal/builders/maven/plugins/verification-plugin/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Maven verification plugin | ||
|
||
The Maven verification plugin can be used to verify the provenance of the dependencies of a Java project. | ||
|
||
It is meant to make it easy for project owners and consumers to: | ||
1: Check how many and which dependencies of a Maven-based project are released with provenance files. | ||
2: Verify the provenance files of the dependencies of a given Maven-based project. | ||
|
||
The plugin wraps the [the slsa verifier](https://github.com/slsa-framework/slsa-verifier) and invokes it for all the dependencies in a `pom.xml`. | ||
|
||
## Prerequisites | ||
|
||
To use the plugin you must have Go, Java and Maven installed. It has currently only been tested on Ubuntu. | ||
|
||
## Development status | ||
|
||
The plugin is in its early stages and is not ready for production. | ||
|
||
Things that work well are: | ||
1: Resolving dependencies and checking whether they have provenance files in the remote repository. | ||
2: Running the slsa-verifier against dependencies with provenance files. | ||
3: Outputting the result from the slsa-verifier. | ||
|
||
Things that are unfinished: | ||
1: What to do with the results from the verifier. Currently we have not taken a stand on what the Maven verification plugin should do with the output from the slsa-verifier. This is a UX decision more than it is a technical decision. | ||
|
||
## Using the Maven verification plugin | ||
|
||
### Invoking it directly | ||
|
||
It can be run from the root of a given project file. | ||
A pseudo-workflow looks like this: | ||
1: `git clone --depth=1 https://github.com/slsa-framework/slsa-github-generator` | ||
2: `cd slsa-github-generator/internal/builders/maven/plugins/verification-plugin` | ||
3: `mvn clean install` | ||
4: `cd /tmp` | ||
5: `git clone your repository to text` | ||
6: `cd into your repository` | ||
7: `mvn io.github.adamkorcz:slsa-verification-plugin:0.0.1:verify` | ||
|
||
The plugin will now go through all the dependencies in the `pom.xml` file and check if they have a provenance statement attached to their release. If a dependency has a SLSA provenance file, the Maven verification plugin will fetch it from the remote repository and invoke the `slsa-verifier` binary against the dependency and the provenance file. | ||
|
||
### Integrating it into your Maven build cycle | ||
|
||
The plugin can also live in your Maven build cycle. If you add it to your own `pom.xml`, the plugin will execute during the validation phase of the Maven build cycle. |
47 changes: 47 additions & 0 deletions
47
internal/builders/maven/plugins/verification-plugin/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
<groupId>io.github.adamkorcz</groupId> | ||
<artifactId>slsa-verification-plugin</artifactId> | ||
<packaging>maven-plugin</packaging> | ||
<version>0.0.1</version> | ||
|
||
<name>Slsa Verification Mojo</name> | ||
<url>http://maven.apache.org</url> | ||
|
||
<properties> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-core</artifactId> | ||
<version>3.2.5</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-plugin-api</artifactId> | ||
<version>3.6.3</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven.plugin-tools</groupId> | ||
<artifactId>maven-plugin-annotations</artifactId> | ||
<version>3.6.0</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-project</artifactId> | ||
<version>2.2.1</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.twdata.maven</groupId> | ||
<artifactId>mojo-executor</artifactId> | ||
<version>2.4.0</version> | ||
</dependency> | ||
</dependencies> | ||
</project> |
189 changes: 189 additions & 0 deletions
189
...n/plugins/verification-plugin/src/main/java/io/github/adamkorcz/SlsaVerificationMojo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
// Copyright 2023 SLSA Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package io.github.adamkorcz; | ||
|
||
import org.apache.maven.artifact.Artifact; | ||
import org.apache.maven.execution.MavenSession; | ||
import org.apache.maven.plugin.AbstractMojo; | ||
import org.apache.maven.plugin.BuildPluginManager; | ||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.apache.maven.plugin.MojoFailureException; | ||
import org.apache.maven.plugins.annotations.LifecyclePhase; | ||
import org.apache.maven.plugins.annotations.Component; | ||
import org.apache.maven.plugins.annotations.Mojo; | ||
import org.apache.maven.plugins.annotations.Parameter; | ||
import org.apache.maven.project.MavenProject; | ||
|
||
import static org.twdata.maven.mojoexecutor.MojoExecutor.*; | ||
|
||
import java.io.File; | ||
import java.util.Set; | ||
|
||
/* | ||
SlsaVerificationMojo is a Maven plugin that wraps https://github.com/slsa-framework/slsa-verifier. | ||
At a high level, it does the following: | ||
1: Install the slsa-verifier. | ||
2: Loop through all dependencies of a pom.xml. Resolve each dependency. | ||
3: Check if each dependency also has a provenance file. | ||
4: Run the slsa-verifier for the dependency if there is a provenance file. | ||
5: Output the results. | ||
The plugin is meant to be installed and then run from the root of a given project file. | ||
A pseudo-workflow looks like this: | ||
1: git clone --depth=1 https://github.com/slsa-framework/slsa-github-generator | ||
2: cd slsa-github-generator/internal/builders/maven/plugins/verification-plugin | ||
3: mvn clean install | ||
4: cd /tmp | ||
5: git clone your repository | ||
6: cd into your repository | ||
7: mvn io.github.adamkorcz:slsa-verification-plugin:0.0.1:verify | ||
*/ | ||
@Mojo(name = "verify", defaultPhase = LifecyclePhase.VALIDATE) | ||
public class SlsaVerificationMojo extends AbstractMojo { | ||
@Parameter(defaultValue = "${project}", required = true, readonly = true) | ||
private MavenProject project; | ||
|
||
/** | ||
* Custom path of GOHOME, default value is $HOME/go | ||
**/ | ||
@Parameter(property = "slsa.gohome") | ||
private String gohome; | ||
|
||
@Component | ||
private MavenSession mavenSession; | ||
|
||
@Component | ||
private BuildPluginManager pluginManager; | ||
|
||
|
||
public void execute() throws MojoExecutionException, MojoFailureException { | ||
// Check Go Home directory | ||
if ((gohome == null) || gohome.equals("")) { | ||
gohome = System.getProperty("user.home") + "/go"; | ||
} | ||
if (!(new File(gohome + "/bin")).exists()) { | ||
getLog().info("Skipping slsa verification: Golang not installed or GOHOME not set properly."); | ||
return; | ||
} | ||
|
||
// Install slsa verifier with go | ||
try { | ||
executeMojo( | ||
plugin( | ||
groupId("org.codehaus.mojo"), | ||
artifactId("exec-maven-plugin"), | ||
version("3.1.0") | ||
), | ||
goal("exec"), | ||
configuration( | ||
element(name("executable"), "go"), | ||
element(name("commandlineArgs"), "install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@latest") | ||
), | ||
executionEnvironment( | ||
project, | ||
mavenSession, | ||
pluginManager | ||
) | ||
); | ||
} catch(MojoExecutionException e) { | ||
getLog().info("Skipping slsa verification: Fail to retrieve slsa-verifier."); | ||
return; | ||
} | ||
|
||
// Verify the slsa of each dependency | ||
Set<Artifact> dependencyArtifacts = project.getDependencyArtifacts(); | ||
for (Artifact artifact : dependencyArtifacts ) { | ||
// Retrieve the dependency jar and its slsa file | ||
String artifactStr = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(); | ||
try { | ||
// Retrieve the slsa file of the artifact | ||
executeMojo( | ||
plugin( | ||
groupId("com.googlecode.maven-download-plugin"), | ||
artifactId("download-maven-plugin"), | ||
version("1.7.0") | ||
), | ||
goal("artifact"), | ||
configuration( | ||
element(name("outputDirectory"), "${project.build.directory}/slsa"), | ||
element(name("groupId"), artifact.getGroupId()), | ||
element(name("artifactId"), artifact.getArtifactId()), | ||
element(name("version"), artifact.getVersion()), | ||
element(name("type"), "intoto.build.slsa"), | ||
element(name("classifier"), "jar") | ||
), | ||
executionEnvironment( | ||
project, | ||
mavenSession, | ||
pluginManager | ||
) | ||
); | ||
|
||
// Retrieve the dependency jar if slsa file does exists for this artifact | ||
executeMojo( | ||
plugin( | ||
groupId("org.apache.maven.plugins"), | ||
artifactId("maven-dependency-plugin"), | ||
version("3.6.0") | ||
), | ||
goal("copy"), | ||
configuration( | ||
element(name("outputDirectory"), "${project.build.directory}/slsa"), | ||
element(name("artifact"), artifactStr) | ||
), | ||
executionEnvironment( | ||
project, | ||
mavenSession, | ||
pluginManager | ||
) | ||
); | ||
} catch(MojoExecutionException e) { | ||
getLog().info("Skipping slsa verification for " + artifactStr + ": No slsa file found."); | ||
continue; | ||
} | ||
|
||
// Verify slsa file | ||
try { | ||
// Run slsa verification on the artifact and print the result | ||
// It will never fail the build process | ||
String arguments = "verify-artifact --provenance-path "; | ||
arguments += "${project.build.directory}/slsa/" + artifact.getArtifactId() + "-" + artifact.getVersion() + "-jar.intoto.build.slsa "; | ||
arguments += " --source-uri ./ ${project.build.directory}/slsa/" + artifact.getArtifactId() + "-" + artifact.getVersion() + ".jar"; | ||
executeMojo( | ||
plugin( | ||
groupId("org.codehaus.mojo"), | ||
artifactId("exec-maven-plugin"), | ||
version("3.1.0") | ||
), | ||
goal("exec"), | ||
configuration( | ||
element(name("executable"), gohome + "/bin/slsa-verifier"), | ||
element(name("commandlineArgs"), arguments), | ||
element(name("useMavenLogger"), "true") | ||
), | ||
executionEnvironment( | ||
project, | ||
mavenSession, | ||
pluginManager | ||
) | ||
); | ||
} catch(MojoExecutionException e) { | ||
// TODO: Properly interpret the output based on the verification plugin. | ||
getLog().info("Skipping slsa verification: Fail to run slsa verifier."); | ||
return; | ||
} | ||
} | ||
} | ||
} |