-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #130 from chizhg/slsa-v1
feat: add the SLSA models for its v1.0 spec
- Loading branch information
Showing
14 changed files
with
1,482 additions
and
12 deletions.
There are no files selected for viewing
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
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
140 changes: 140 additions & 0 deletions
140
src/main/java/io/github/intoto/slsa/models/v1/BuildDefinition.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,140 @@ | ||
package io.github.intoto.slsa.models.v1; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.fasterxml.jackson.annotation.JsonInclude.Include; | ||
import jakarta.validation.Valid; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotEmpty; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
/** | ||
* The BuildDefinition describes all of the inputs to the build. It SHOULD contain all the | ||
* information necessary and sufficient to initialize the build and begin execution. | ||
* | ||
* <p>The externalParameters and internalParameters are the top-level inputs to the template, | ||
* meaning inputs not derived from another input. Each is an arbitrary JSON object, though it is | ||
* RECOMMENDED to keep the structure simple with string values to aid verification. The same field | ||
* name SHOULD NOT be used for both externalParameters and internalParameters. | ||
* | ||
* <p>The parameters SHOULD only contain the actual values passed in through the interface to the | ||
* build platform. Metadata about those parameter values, particularly digests of artifacts | ||
* referenced by those parameters, SHOULD instead go in resolvedDependencies. The documentation for | ||
* buildType SHOULD explain how to convert from a parameter to the dependency uri. For example: | ||
* | ||
* <pre> | ||
* {@code <script>} | ||
* "externalParameters": { | ||
* "repository": "https://github.com/octocat/hello-world", | ||
* "ref": "refs/heads/main" | ||
* }, | ||
* "resolvedDependencies": [{ | ||
* "uri": "git+https://github.com/octocat/hello-world@refs/heads/main", | ||
* "digest": {"gitCommit": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d"} | ||
* }] | ||
* {@code </script>} | ||
* </pre> | ||
*/ | ||
public class BuildDefinition { | ||
|
||
/** | ||
* Identifies the template for how to perform the build and interpret the parameters and | ||
* dependencies. | ||
* | ||
* <p>The URI SHOULD resolve to a human-readable specification that includes: overall description | ||
* of the build type; schema for externalParameters and internalParameters; unambiguous | ||
* instructions for how to initiate the build given this BuildDefinition, and a complete example. | ||
* Example: https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1 | ||
*/ | ||
@NotBlank(message = "buildType must not be empty or blank") | ||
private String buildType; | ||
|
||
/** | ||
* The parameters that are under external control, such as those set by a user or tenant of the | ||
* build platform. They MUST be complete at SLSA Build L3, meaning that there is no additional | ||
* mechanism for an external party to influence the build. (At lower SLSA Build levels, the | ||
* completeness MAY be best effort.) | ||
* | ||
* <p>The build platform SHOULD be designed to minimize the size and complexity of | ||
* externalParameters, in order to reduce fragility and ease verification. Consumers SHOULD have | ||
* an expectation of what “good” looks like; the more information that they need to check, the | ||
* harder that task becomes. | ||
* | ||
* <p>Verifiers SHOULD reject unrecognized or unexpected fields within externalParameters. | ||
*/ | ||
@NotEmpty(message = "externalParameters must not be empty") | ||
private Map<String, Object> externalParameters; | ||
|
||
/** | ||
* The parameters that are under the control of the entity represented by builder.id. The primary | ||
* intention of this field is for debugging, incident response, and vulnerability management. The | ||
* values here MAY be necessary for reproducing the build. There is no need to verify these | ||
* parameters because the build platform is already trusted, and in many cases it is not practical | ||
* to do so. | ||
*/ | ||
@JsonInclude(Include.NON_EMPTY) | ||
private Map<String, Object> internalParameters; | ||
|
||
/** | ||
* Unordered collection of artifacts needed at build time. Completeness is best effort, at least | ||
* through SLSA Build L3. For example, if the build script fetches and executes | ||
* “example.com/foo.sh”, which in turn fetches “example.com/bar.tar.gz”, then both “foo.sh” and | ||
* “bar.tar.gz” SHOULD be listed here. | ||
*/ | ||
private List<ResourceDescriptor> resolvedDependencies; | ||
|
||
public String getBuildType() { | ||
return buildType; | ||
} | ||
|
||
public void setBuildType(String buildType) { | ||
this.buildType = buildType; | ||
} | ||
|
||
public Map<String, Object> getExternalParameters() { | ||
return externalParameters; | ||
} | ||
|
||
public void setExternalParameters(Map<String, Object> externalParameters) { | ||
this.externalParameters = externalParameters; | ||
} | ||
|
||
public Map<String, Object> getInternalParameters() { | ||
return internalParameters; | ||
} | ||
|
||
public void setInternalParameters(Map<String, Object> internalParameters) { | ||
this.internalParameters = internalParameters; | ||
} | ||
|
||
public List<ResourceDescriptor> getResolvedDependencies() { | ||
return resolvedDependencies; | ||
} | ||
|
||
public void setResolvedDependencies( | ||
List<ResourceDescriptor> resolvedDependencies) { | ||
this.resolvedDependencies = resolvedDependencies; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
io.github.intoto.slsa.models.v1.BuildDefinition buildDefinition = (io.github.intoto.slsa.models.v1.BuildDefinition) o; | ||
return buildType.equals(buildDefinition.buildType) && Objects.equals(externalParameters, | ||
buildDefinition.externalParameters) | ||
&& Objects.equals(internalParameters, buildDefinition.internalParameters) && Objects.equals( | ||
resolvedDependencies, buildDefinition.resolvedDependencies); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(buildType, externalParameters, internalParameters, | ||
resolvedDependencies); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
src/main/java/io/github/intoto/slsa/models/v1/BuildMetadata.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,73 @@ | ||
package io.github.intoto.slsa.models.v1; | ||
|
||
import com.fasterxml.jackson.annotation.JsonFormat; | ||
import java.time.OffsetDateTime; | ||
import java.util.Objects; | ||
|
||
public class BuildMetadata { | ||
|
||
/** | ||
* Identifies this particular build invocation, which can be useful for finding associated logs or | ||
* other ad-hoc analysis. The exact meaning and format is defined by builder.id; by default it is | ||
* treated as opaque and case-sensitive. The value SHOULD be globally unique. | ||
*/ | ||
private String invocationId; | ||
|
||
/** | ||
* The timestamp of when the build started. A point in time, represented as a string in RFC 3339 | ||
* format in the UTC time zone ("Z"). | ||
*/ | ||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX") | ||
private OffsetDateTime startedOn; | ||
|
||
/** | ||
* The timestamp of when the build completed.A point in time, represented as a string in RFC 3339 | ||
* format in the UTC time zone ("Z"). | ||
*/ | ||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX") | ||
private OffsetDateTime finishedOn; | ||
|
||
public String getInvocationId() { | ||
return invocationId; | ||
} | ||
|
||
public void setInvocationId(String invocationId) { | ||
this.invocationId = invocationId; | ||
} | ||
|
||
public OffsetDateTime getStartedOn() { | ||
return startedOn; | ||
} | ||
|
||
public void setStartedOn(OffsetDateTime startedOn) { | ||
this.startedOn = startedOn; | ||
} | ||
|
||
public OffsetDateTime getFinishedOn() { | ||
return finishedOn; | ||
} | ||
|
||
public void setFinishedOn(OffsetDateTime finishedOn) { | ||
this.finishedOn = finishedOn; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
BuildMetadata buildMetadata = (BuildMetadata) o; | ||
return Objects.equals(invocationId, buildMetadata.invocationId) | ||
&& Objects.equals(startedOn, buildMetadata.startedOn) | ||
&& Objects.equals(finishedOn, buildMetadata.finishedOn); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash( | ||
invocationId, startedOn, finishedOn); | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
src/main/java/io/github/intoto/slsa/models/v1/Builder.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,93 @@ | ||
package io.github.intoto.slsa.models.v1; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
|
||
/** | ||
* The build platform, or builder for short, represents the transitive closure of all the entities | ||
* that are, by necessity, trusted to faithfully run the build and record the provenance. This | ||
* includes not only the software but the hardware and people involved in running the service. For | ||
* example, a particular instance of Tekton could be a build platform, while Tekton itself is not. | ||
* For more info, see Build model. | ||
* | ||
* <p>The id MUST reflect the trust base that consumers care about. How detailed to be is a | ||
* judgement call. For example, GitHub Actions supports both GitHub-hosted runners and self-hosted | ||
* runners. The GitHub-hosted runner might be a single identity because it’s all GitHub from the | ||
* consumer’s perspective. Meanwhile, each self-hosted runner might have its own identity because | ||
* not all runners are trusted by all consumers. | ||
* | ||
* <p>Consumers MUST accept only specific signer-builder pairs. For example, “GitHub” can sign | ||
* provenance for the “GitHub Actions” builder, and “Google” can sign provenance for the “Google | ||
* Cloud Build” builder, but “GitHub” cannot sign for the “Google Cloud Build” builder. | ||
* | ||
* <p>Design rationale: The builder is distinct from the signer in order to support the case where | ||
* one signer generates attestations for more than one builder, as in the GitHub Actions example | ||
* above. The field is REQUIRED, even if it is implicit from the signer, to aid readability and | ||
* debugging. It is an object to allow additional fields in the future, in case one URI is not | ||
* sufficient. | ||
*/ | ||
public class Builder { | ||
|
||
/** | ||
* URI indicating the builder’s identity. (<a | ||
* href="https://github.com/in-toto/attestation/blob/main/spec/field_types.md#TypeURI">TypeURI</a>) | ||
*/ | ||
@NotBlank(message = "builder Id must not be empty or blank") | ||
private String id; | ||
|
||
/** | ||
* Dependencies used by the orchestrator that are not run within the workload and that do not | ||
* affect the build, but might affect the provenance generation or security guarantees. | ||
*/ | ||
private List<ResourceDescriptor> builderDependencies; | ||
|
||
/** | ||
* Map of names of components of the build platform to their version. | ||
*/ | ||
private Map<String, String> version; | ||
|
||
public String getId() { | ||
return id; | ||
} | ||
|
||
public void setId(String id) { | ||
this.id = id; | ||
} | ||
|
||
public List<ResourceDescriptor> getBuilderDependencies() { | ||
return builderDependencies; | ||
} | ||
|
||
public void setBuilderDependencies( | ||
List<ResourceDescriptor> builderDependencies) { | ||
this.builderDependencies = builderDependencies; | ||
} | ||
|
||
public Map<String, String> getVersion() { | ||
return version; | ||
} | ||
|
||
public void setVersion(Map<String, String> version) { | ||
this.version = version; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
io.github.intoto.slsa.models.v1.Builder builder = (io.github.intoto.slsa.models.v1.Builder) o; | ||
return id.equals(builder.id) && Objects.equals(builderDependencies, builder.builderDependencies) | ||
&& Objects.equals(version, builder.version); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(id, version); | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
src/main/java/io/github/intoto/slsa/models/v1/Provenance.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,63 @@ | ||
package io.github.intoto.slsa.models.v1; | ||
|
||
import io.github.intoto.models.Predicate; | ||
import jakarta.validation.Valid; | ||
import jakarta.validation.constraints.NotNull; | ||
import java.util.Objects; | ||
|
||
public class Provenance extends Predicate { | ||
|
||
/** | ||
* The input to the build. The accuracy and completeness are implied by runDetails.builder.id. | ||
*/ | ||
@Valid | ||
@NotNull(message = "buildDefinition must not be null") | ||
private BuildDefinition buildDefinition; | ||
|
||
/** | ||
* Details specific to this particular execution of the build. | ||
*/ | ||
@Valid | ||
@NotNull(message = "runDetails must not be null") | ||
private RunDetails runDetails; | ||
|
||
public BuildDefinition getBuildDefinition() { | ||
return buildDefinition; | ||
} | ||
|
||
public void setBuildDefinition(BuildDefinition buildDefinition) { | ||
this.buildDefinition = buildDefinition; | ||
} | ||
|
||
public RunDetails getRunDetails() { | ||
return runDetails; | ||
} | ||
|
||
public void setRunDetails(RunDetails runDetails) { | ||
this.runDetails = runDetails; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Provenance provenance = (Provenance) o; | ||
return Objects.equals(buildDefinition, provenance.buildDefinition) | ||
&& Objects.equals(runDetails, provenance.runDetails); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash( | ||
buildDefinition, runDetails); | ||
} | ||
|
||
@Override | ||
public String getPredicateType() { | ||
return "https://slsa.dev/provenance/v1"; | ||
} | ||
} |
Oops, something went wrong.