Skip to content

Commit

Permalink
move maven-plugin from slsa-github-generator (#664)
Browse files Browse the repository at this point in the history
Adds the maven plugin from
slsa-framework/slsa-github-generator#2439

Signed-off-by: AdamKorcz <adam@adalogics.com>
  • Loading branch information
AdamKorcz committed Jul 21, 2023
1 parent 59f6ba3 commit 1d65178
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 0 deletions.
47 changes: 47 additions & 0 deletions experimental/maven-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 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.

The plugin requires that the slsa-verifier is already installed on the machine.

## 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-verifier`
2: `cd slsa-verifier/experimental/maven-plugin`
3: `mvn clean install`
4: `cd /tmp`
5: `git clone your repository to text`
6: `cd into your repository`
7: `mvn io.github.slsa-framework: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 experimental/maven-plugin/pom.xml
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.slsa-framework</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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// 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.slsaframework;

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-verifier
2: cd slsa-verifier/experimental/maven-plugin
3: mvn clean install
4: cd /tmp
5: git clone your repository
6: cd into your repository
7: mvn io.github.slsa-framework: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.verifier.path", required = true)
private String verifierPath;

@Component
private MavenSession mavenSession;

@Component
private BuildPluginManager pluginManager;


public void execute() throws MojoExecutionException, MojoFailureException {
// 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
// This might be prone to command-injections. TODO: Secure against that.
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"), verifierPath),
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;
}
}
}
}

0 comments on commit 1d65178

Please sign in to comment.