This is an automated email from the ASF dual-hosted git repository.

ppkarwasz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-release-plugin.git


The following commit(s) were added to refs/heads/master by this push:
     new 546dfbf  Add SLSA data models
546dfbf is described below

commit 546dfbf92a3d016d6bb54ebdda175b3db59762bd
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Tue May 5 09:24:57 2026 +0200

    Add SLSA data models
    
    Adds SLSA data models annotated with Jackson annotation for 
serialization/deserialization to JSON.
---
 fb-excludes.xml                                    |   6 +
 pom.xml                                            |  17 ++
 .../release/plugin/slsa/v1_2/BuildDefinition.java  | 187 ++++++++++++++++
 .../release/plugin/slsa/v1_2/BuildMetadata.java    | 141 +++++++++++++
 .../commons/release/plugin/slsa/v1_2/Builder.java  | 129 +++++++++++
 .../release/plugin/slsa/v1_2/DsseEnvelope.java     | 130 ++++++++++++
 .../release/plugin/slsa/v1_2/Provenance.java       | 124 +++++++++++
 .../plugin/slsa/v1_2/ResourceDescriptor.java       | 235 +++++++++++++++++++++
 .../release/plugin/slsa/v1_2/RunDetails.java       | 149 +++++++++++++
 .../release/plugin/slsa/v1_2/Signature.java        | 107 ++++++++++
 .../release/plugin/slsa/v1_2/Statement.java        | 131 ++++++++++++
 .../release/plugin/slsa/v1_2/package-info.java     |  34 +++
 12 files changed, 1390 insertions(+)

diff --git a/fb-excludes.xml b/fb-excludes.xml
index 2cba281..9681064 100644
--- a/fb-excludes.xml
+++ b/fb-excludes.xml
@@ -18,6 +18,12 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
     xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 
https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd";>
 
+  <!-- SLSA provenance data models are short-lived DTOs serialized to JSON; 
defensive copying adds no safety. -->
+  <Match>
+    <Package name="org.apache.commons.release.plugin.slsa.v1_2" />
+    <Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2" />
+  </Match>
+
   <!-- Omit junit tests -->
   <Match>
     <Class name="~.*\.*Test.*"/>
diff --git a/pom.xml b/pom.xml
index 0e61c9e..23b1da9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -102,7 +102,20 @@
     <!-- Until Maven plugins used here don't fail the Moditect plugin -->
     <moditect.skip>true</moditect.skip>
     <japicmp.skip>true</japicmp.skip>
+    <!-- Dependency versions -->
+    <commons.jackson.version>2.21.2</commons.jackson.version>
   </properties>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>com.fasterxml.jackson</groupId>
+        <artifactId>jackson-bom</artifactId>
+        <version>${commons.jackson.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
   <dependencies>
     <dependency>
       <groupId>org.apache.commons</groupId>
@@ -160,6 +173,10 @@
       <artifactId>commons-compress</artifactId>
       <version>1.28.0</version>
     </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-annotations</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apache.maven.plugin-testing</groupId>
       <artifactId>maven-plugin-testing-harness</artifactId>
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/BuildDefinition.java
 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/BuildDefinition.java
new file mode 100644
index 0000000..43bcb94
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/BuildDefinition.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Inputs that define the build: the build type, external and internal 
parameters, and resolved dependencies.
+ *
+ * <p>Specifies everything that influenced the build output. Together with 
{@link RunDetails}, it forms the complete
+ * {@link Provenance} record.</p>
+ *
+ * @see <a href="https://slsa.dev/spec/v1.2";>SLSA v1.2 Specification</a>
+ */
+public class BuildDefinition {
+
+    /**
+     * URI indicating what type of build was performed.
+     */
+    @JsonProperty("buildType")
+    private String buildType = 
"https://commons.apache.org/proper/commons-release-plugin/slsa/v0.1.0";;
+
+    /**
+     * Inputs passed to the build.
+     */
+    @JsonProperty("externalParameters")
+    private Map<String, Object> externalParameters = new HashMap<>();
+
+    /**
+     * Parameters set by the build platform.
+     */
+    @JsonProperty("internalParameters")
+    private Map<String, Object> internalParameters = new HashMap<>();
+
+    /**
+     * Artifacts the build depends on, specified by URI and digest.
+     */
+    @JsonProperty("resolvedDependencies")
+    private List<ResourceDescriptor> resolvedDependencies;
+
+    /**
+     * Creates a new BuildDefinition instance with the default build type.
+     */
+    public BuildDefinition() {
+    }
+
+    /**
+     * Creates a new BuildDefinition with the given build type and external 
parameters.
+     *
+     * @param buildType          URI indicating what type of build was 
performed
+     * @param externalParameters inputs passed to the build
+     */
+    public BuildDefinition(String buildType, Map<String, Object> 
externalParameters) {
+        this.buildType = buildType;
+        this.externalParameters = externalParameters;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        BuildDefinition that = (BuildDefinition) o;
+        return Objects.equals(buildType, that.buildType) && 
Objects.equals(externalParameters, that.externalParameters) && 
Objects.equals(internalParameters,
+                that.internalParameters) && 
Objects.equals(resolvedDependencies, that.resolvedDependencies);
+    }
+
+    /**
+     * Gets the URI indicating what type of build was performed.
+     *
+     * <p>Determines the meaning of {@code externalParameters} and {@code 
internalParameters}.</p>
+     *
+     * @return the build type URI
+     */
+    public String getBuildType() {
+        return buildType;
+    }
+
+    /**
+     * Gets the inputs passed to the build, such as command-line arguments or 
environment variables.
+     *
+     * @return the external parameters map, or {@code null} if not set
+     */
+    public Map<String, Object> getExternalParameters() {
+        return externalParameters;
+    }
+
+    /**
+     * Gets the artifacts the build depends on, such as sources, dependencies, 
build tools, and base images,
+     * specified by URI and digest.
+     *
+     * @return the internal parameters map, or {@code null} if not set
+     */
+    public Map<String, Object> getInternalParameters() {
+        return internalParameters;
+    }
+
+    /**
+     * Gets the materials that influenced the build.
+     *
+     * <p>Considered incomplete unless resolved materials are present.</p>
+     *
+     * @return the list of resolved dependencies, or {@code null} if not set
+     */
+    public List<ResourceDescriptor> getResolvedDependencies() {
+        return resolvedDependencies;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(buildType, externalParameters, internalParameters, 
resolvedDependencies);
+    }
+
+    /**
+     * Sets the URI indicating what type of build was performed.
+     *
+     * @param buildType the build type URI
+     * @return this for chaining
+     */
+    public BuildDefinition setBuildType(String buildType) {
+        this.buildType = buildType;
+        return this;
+    }
+
+    /**
+     * Sets the inputs passed to the build.
+     *
+     * @param externalParameters the external parameters map
+     * @return this for chaining
+     */
+    public BuildDefinition setExternalParameters(Map<String, Object> 
externalParameters) {
+        this.externalParameters = externalParameters;
+        return this;
+    }
+
+    /**
+     * Sets the artifacts the build depends on.
+     *
+     * @param internalParameters the internal parameters map
+     * @return this for chaining
+     */
+    public BuildDefinition setInternalParameters(Map<String, Object> 
internalParameters) {
+        this.internalParameters = internalParameters;
+        return this;
+    }
+
+    /**
+     * Sets the materials that influenced the build.
+     *
+     * @param resolvedDependencies the list of resolved dependencies
+     * @return this for chaining
+     */
+    public BuildDefinition setResolvedDependencies(List<ResourceDescriptor> 
resolvedDependencies) {
+        this.resolvedDependencies = resolvedDependencies;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "BuildDefinition{buildType='" + buildType + '\''
+                + ", externalParameters=" + externalParameters
+                + ", internalParameters=" + internalParameters
+                + ", resolvedDependencies=" + resolvedDependencies + '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/BuildMetadata.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/BuildMetadata.java
new file mode 100644
index 0000000..595e0f7
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/BuildMetadata.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.time.OffsetDateTime;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Metadata about a build invocation: its identifier and start and finish 
timestamps.
+ *
+ * @see <a href="https://slsa.dev/spec/v1.2";>SLSA v1.2 Specification</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class BuildMetadata {
+
+    /** Timestamp when the build completed. */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = 
"yyyy-MM-dd'T'HH:mm:ss'Z'")
+    @JsonProperty("finishedOn")
+    private OffsetDateTime finishedOn;
+    /** Identifier for this build invocation. */
+    @JsonProperty("invocationId")
+    private String invocationId;
+    /** Timestamp when the build started. */
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = 
"yyyy-MM-dd'T'HH:mm:ss'Z'")
+    @JsonProperty("startedOn")
+    private OffsetDateTime startedOn;
+
+    /** Creates a new BuildMetadata instance. */
+    public BuildMetadata() {
+    }
+
+    /**
+     * Creates a new BuildMetadata instance with all fields set.
+     *
+     * @param invocationId identifier for this build invocation
+     * @param startedOn    timestamp when the build started
+     * @param finishedOn   timestamp when the build completed
+     */
+    public BuildMetadata(String invocationId, OffsetDateTime startedOn, 
OffsetDateTime finishedOn) {
+        this.invocationId = invocationId;
+        this.startedOn = startedOn;
+        this.finishedOn = finishedOn;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof BuildMetadata)) {
+            return false;
+        }
+        BuildMetadata that = (BuildMetadata) o;
+        return Objects.equals(invocationId, that.invocationId) && 
Objects.equals(startedOn, that.startedOn) && Objects.equals(finishedOn, 
that.finishedOn);
+    }
+
+    /**
+     * Gets the timestamp of when the build completed, serialized as RFC 3339 
in UTC ({@code "Z"} suffix).
+     *
+     * @return the completion timestamp, or {@code null} if not set
+     */
+    public OffsetDateTime getFinishedOn() {
+        return finishedOn;
+    }
+
+    /**
+     * Gets the identifier for this build invocation.
+     *
+     * @return the invocation identifier, or {@code null} if not set
+     */
+    public String getInvocationId() {
+        return invocationId;
+    }
+
+    /**
+     * Gets the timestamp of when the build started, serialized as RFC 3339 in 
UTC ({@code "Z"} suffix).
+     *
+     * @return the start timestamp, or {@code null} if not set
+     */
+    public OffsetDateTime getStartedOn() {
+        return startedOn;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(invocationId, startedOn, finishedOn);
+    }
+
+    /**
+     * Sets the timestamp of when the build completed.
+     *
+     * @param finishedOn the completion timestamp
+     * @return this for chaining
+     */
+    public BuildMetadata setFinishedOn(OffsetDateTime finishedOn) {
+        this.finishedOn = finishedOn;
+        return this;
+    }
+
+    /**
+     * Sets the identifier for this build invocation.
+     *
+     * @param invocationId the invocation identifier
+     * @return this for chaining
+     */
+    public BuildMetadata setInvocationId(String invocationId) {
+        this.invocationId = invocationId;
+        return this;
+    }
+
+    /**
+     * Sets the timestamp of when the build started.
+     *
+     * @param startedOn the start timestamp
+     * @return this for chaining
+     */
+    public BuildMetadata setStartedOn(OffsetDateTime startedOn) {
+        this.startedOn = startedOn;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "BuildMetadata{invocationId='" + invocationId + "', startedOn=" 
+ startedOn + ", finishedOn=" + finishedOn + '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Builder.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Builder.java
new file mode 100644
index 0000000..508d622
--- /dev/null
+++ b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Builder.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Entity that executed the build and is trusted to have correctly performed 
the operation and populated the provenance.
+ *
+ * @see <a href="https://slsa.dev/spec/v1.2";>SLSA v1.2 Specification</a>
+ */
+public class Builder {
+
+    /** Orchestrator dependencies that may affect provenance generation. */
+    @JsonProperty("builderDependencies")
+    private List<ResourceDescriptor> builderDependencies = new ArrayList<>();
+    /** Identifier URI of the builder. */
+    @JsonProperty("id")
+    private String id;
+    /** Map of build platform component names to their versions. */
+    @JsonProperty("version")
+    private Map<String, String> version = new HashMap<>();
+
+    /** Creates a new Builder instance. */
+    public Builder() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Builder)) {
+            return false;
+        }
+        Builder that = (Builder) o;
+        return Objects.equals(id, that.id)
+                && Objects.equals(builderDependencies, 
that.builderDependencies)
+                && Objects.equals(version, that.version);
+    }
+
+    /**
+     * Gets orchestrator dependencies that do not run within the build 
workload and do not affect the build output,
+     * but may affect provenance generation or security guarantees.
+     *
+     * @return the list of builder dependencies, or {@code null} if not set
+     */
+    public List<ResourceDescriptor> getBuilderDependencies() {
+        return builderDependencies;
+    }
+
+    /**
+     * Gets the identifier of the builder.
+     *
+     * @return the builder identifier URI
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Gets a map of build platform component names to their versions.
+     *
+     * @return the version map, or {@code null} if not set
+     */
+    public Map<String, String> getVersion() {
+        return version;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, builderDependencies, version);
+    }
+
+    /**
+     * Sets the orchestrator dependencies that may affect provenance 
generation or security guarantees.
+     *
+     * @param builderDependencies the list of builder dependencies
+     * @return this for chaining
+     */
+    public Builder setBuilderDependencies(List<ResourceDescriptor> 
builderDependencies) {
+        this.builderDependencies = builderDependencies;
+        return this;
+    }
+
+    /**
+     * Sets the identifier of the builder.
+     *
+     * @param id the builder identifier URI
+     * @return this for chaining
+     */
+    public Builder setId(String id) {
+        this.id = id;
+        return this;
+    }
+
+    /**
+     * Sets the map of build platform component names to their versions.
+     *
+     * @param version the version map
+     * @return this for chaining
+     */
+    public Builder setVersion(Map<String, String> version) {
+        this.version = version;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "Builder{id='" + id + "', builderDependencies=" + 
builderDependencies + ", version=" + version + '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/DsseEnvelope.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/DsseEnvelope.java
new file mode 100644
index 0000000..e68e575
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/DsseEnvelope.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * DSSE (Dead Simple Signing Envelope) that wraps a signed in-toto statement 
payload.
+ *
+ * @see <a 
href="https://github.com/secure-systems-lab/dsse/blob/v1.0.2/envelope.md";>DSSE 
Envelope specification</a>
+ */
+public class DsseEnvelope {
+
+    /** The payload type URI for in-toto attestation statements. */
+    public static final String PAYLOAD_TYPE = "application/vnd.in-toto+json";
+    /** Serialized statement bytes, Base64-encoded in JSON. */
+    @JsonProperty("payload")
+    private byte[] payload;
+    /** Content type identifying the format of {@link #payload}. */
+    @JsonProperty("payloadType")
+    private String payloadType = PAYLOAD_TYPE;
+    /** One or more signatures over the PAE-encoded payload. */
+    @JsonProperty("signatures")
+    private List<Signature> signatures;
+
+    /** Creates a new DsseEnvelope instance with {@code payloadType} pre-set 
to {@link #PAYLOAD_TYPE}. */
+    public DsseEnvelope() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof DsseEnvelope)) {
+            return false;
+        }
+        DsseEnvelope envelope = (DsseEnvelope) o;
+        return Objects.equals(payloadType, envelope.payloadType) && 
Arrays.equals(payload, envelope.payload)
+                && Objects.equals(signatures, envelope.signatures);
+    }
+
+    /**
+     * Gets the serialized payload bytes.
+     *
+     * <p>When serialized to JSON the bytes are Base64-encoded.</p>
+     *
+     * @return the payload bytes, or {@code null} if not set
+     */
+    public byte[] getPayload() {
+        return payload;
+    }
+
+    /**
+     * Gets the payload type URI.
+     *
+     * @return the payload type, never {@code null} in a valid envelope
+     */
+    public String getPayloadType() {
+        return payloadType;
+    }
+
+    /**
+     * Gets the list of signatures over the PAE-encoded payload.
+     *
+     * @return the signatures, or {@code null} if not set
+     */
+    public List<Signature> getSignatures() {
+        return signatures;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(payloadType, Arrays.hashCode(payload), signatures);
+    }
+
+    /**
+     * Sets the serialized payload bytes.
+     *
+     * @param payload the payload bytes
+     * @return this for chaining
+     */
+    public DsseEnvelope setPayload(byte[] payload) {
+        this.payload = payload;
+        return this;
+    }
+
+    /**
+     * Sets the payload type URI.
+     *
+     * @param payloadType the payload type URI
+     * @return this for chaining
+     */
+    public DsseEnvelope setPayloadType(String payloadType) {
+        this.payloadType = payloadType;
+        return this;
+    }
+
+    /**
+     * Sets the list of signatures over the PAE-encoded payload.
+     *
+     * @param signatures the signatures
+     * @return this for chaining
+     */
+    public DsseEnvelope setSignatures(List<Signature> signatures) {
+        this.signatures = signatures;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "DsseEnvelope{payloadType='" + payloadType + "', payload=<" + 
(payload != null ? payload.length : 0)
+                + " bytes>, signatures=" + signatures + '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Provenance.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Provenance.java
new file mode 100644
index 0000000..6002dce
--- /dev/null
+++ b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Provenance.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Root predicate of an SLSA v1.2 provenance attestation, describing what was 
built and how.
+ *
+ * <p>Combines a {@link BuildDefinition} (the inputs) with {@link RunDetails} 
(the execution context). Intended to be
+ * used as the {@code predicate} field of an in-toto {@link Statement}.</p>
+ *
+ * @see <a href="https://slsa.dev/spec/v1.2";>SLSA v1.2 Specification</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Provenance {
+
+    /** Predicate type URI used in the in-toto {@link Statement} wrapping this 
provenance. */
+    public static final String PREDICATE_TYPE = 
"https://slsa.dev/provenance/v1";;
+
+    /** Inputs that defined the build. */
+    @JsonProperty("buildDefinition")
+    private BuildDefinition buildDefinition;
+
+    /** Details about the build invocation. */
+    @JsonProperty("runDetails")
+    private RunDetails runDetails;
+
+    /** Creates a new Provenance instance. */
+    public Provenance() {
+    }
+
+    /**
+     * Creates a new Provenance with the given build definition and run 
details.
+     *
+     * @param buildDefinition inputs that defined the build
+     * @param runDetails      details about the build invocation
+     */
+    public Provenance(BuildDefinition buildDefinition, RunDetails runDetails) {
+        this.buildDefinition = buildDefinition;
+        this.runDetails = runDetails;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Provenance that = (Provenance) o;
+        return Objects.equals(buildDefinition, that.buildDefinition) && 
Objects.equals(runDetails, that.runDetails);
+    }
+
+    /**
+     * Gets the build definition describing all inputs that produced the build 
output.
+     *
+     * <p>Includes source code, dependencies, build tools, base images, and 
other materials.</p>
+     *
+     * @return the build definition, or {@code null} if not set
+     */
+    public BuildDefinition getBuildDefinition() {
+        return buildDefinition;
+    }
+
+    /**
+     * Gets the details about the invocation of the build tool and the 
environment in which it was run.
+     *
+     * @return the run details, or {@code null} if not set
+     */
+    public RunDetails getRunDetails() {
+        return runDetails;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(buildDefinition, runDetails);
+    }
+
+    /**
+     * Sets the build definition describing all inputs that produced the build 
output.
+     *
+     * @param buildDefinition the build definition
+     * @return this for chaining
+     */
+    public Provenance setBuildDefinition(BuildDefinition buildDefinition) {
+        this.buildDefinition = buildDefinition;
+        return this;
+    }
+
+    /**
+     * Sets the details about the invocation of the build tool and the 
environment in which it was run.
+     *
+     * @param runDetails the run details
+     * @return this for chaining
+     */
+    public Provenance setRunDetails(RunDetails runDetails) {
+        this.runDetails = runDetails;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "Provenance{buildDefinition=" + buildDefinition + ", 
runDetails=" + runDetails + '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/ResourceDescriptor.java
 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/ResourceDescriptor.java
new file mode 100644
index 0000000..cb3510e
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/ResourceDescriptor.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.Map;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Description of an artifact or resource referenced in the build, identified 
by URI and cryptographic digest.
+ *
+ * <p>Used to represent inputs to, outputs from, or byproducts of the build 
process.</p>
+ *
+ * @see <a href="https://slsa.dev/spec/v1.2";>SLSA v1.2 Specification</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ResourceDescriptor {
+
+    /** Additional key-value metadata about the resource. */
+    @JsonProperty("annotations")
+    private Map<String, Object> annotations;
+    /** Raw contents of the resource, base64-encoded in JSON. */
+    @JsonProperty("content")
+    private byte[] content;
+    /** Map of digest algorithm names to hex-encoded values. */
+    @JsonProperty("digest")
+    private Map<String, String> digest;
+    /** Download URI for the resource, if different from {@link #uri}. */
+    @JsonProperty("downloadLocation")
+    private String downloadLocation;
+    /** Media type of the resource. */
+    @JsonProperty("mediaType")
+    private String mediaType;
+    /** Human-readable name of the resource. */
+    @JsonProperty("name")
+    private String name;
+    /** URI identifying the resource. */
+    @JsonProperty("uri")
+    private String uri;
+
+    /** Creates a new ResourceDescriptor instance. */
+    public ResourceDescriptor() {
+    }
+
+    /**
+     * Creates a new ResourceDescriptor with the given URI and digest.
+     *
+     * @param uri    URI identifying the resource
+     * @param digest map of digest algorithm names to their hex-encoded values
+     */
+    public ResourceDescriptor(String uri, Map<String, String> digest) {
+        this.uri = uri;
+        this.digest = digest;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        ResourceDescriptor that = (ResourceDescriptor) o;
+        return Objects.equals(uri, that.uri) && Objects.equals(digest, 
that.digest);
+    }
+
+    /**
+     * Gets additional key-value metadata about the resource, such as 
filename, size, or builder-specific attributes.
+     *
+     * @return the annotations map, or {@code null} if not set
+     */
+    public Map<String, Object> getAnnotations() {
+        return annotations;
+    }
+
+    /**
+     * Gets the raw contents of the resource, base64-encoded when serialized 
to JSON.
+     *
+     * @return the resource content, or {@code null} if not set
+     */
+    public byte[] getContent() {
+        return content;
+    }
+
+    /**
+     * Gets the map of cryptographic digest algorithms to their corresponding 
hex-encoded values for this resource.
+     *
+     * <p>Common keys include {@code "sha256"} and {@code "sha512"}.</p>
+     *
+     * @return the digest map, or {@code null} if not set
+     */
+    public Map<String, String> getDigest() {
+        return digest;
+    }
+
+    /**
+     * Gets the download URI for the resource, if different from {@link 
#getUri()}.
+     *
+     * @return the download location URI, or {@code null} if not set
+     */
+    public String getDownloadLocation() {
+        return downloadLocation;
+    }
+
+    /**
+     * Gets the media type of the resource (e.g., {@code 
"application/octet-stream"}).
+     *
+     * @return the media type, or {@code null} if not set
+     */
+    public String getMediaType() {
+        return mediaType;
+    }
+
+    /**
+     * Gets the name of the resource.
+     *
+     * @return the resource name, or {@code null} if not set
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Gets the URI identifying the resource.
+     *
+     * @return the resource URI, or {@code null} if not set
+     */
+    public String getUri() {
+        return uri;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(uri, digest);
+    }
+
+    /**
+     * Sets additional key-value metadata about the resource.
+     *
+     * @param annotations the annotations map
+     * @return this for chaining
+     */
+    public ResourceDescriptor setAnnotations(Map<String, Object> annotations) {
+        this.annotations = annotations;
+        return this;
+    }
+
+    /**
+     * Sets the raw contents of the resource.
+     *
+     * @param content the resource content
+     * @return this for chaining
+     */
+    public ResourceDescriptor setContent(byte[] content) {
+        this.content = content;
+        return this;
+    }
+
+    /**
+     * Sets the map of cryptographic digest algorithms to their hex-encoded 
values.
+     *
+     * @param digest the digest map
+     * @return this for chaining
+     */
+    public ResourceDescriptor setDigest(Map<String, String> digest) {
+        this.digest = digest;
+        return this;
+    }
+
+    /**
+     * Sets the download URI for the resource.
+     *
+     * @param downloadLocation the download location URI
+     * @return this for chaining
+     */
+    public ResourceDescriptor setDownloadLocation(String downloadLocation) {
+        this.downloadLocation = downloadLocation;
+        return this;
+    }
+
+    /**
+     * Sets the media type of the resource.
+     *
+     * @param mediaType the media type
+     * @return this for chaining
+     */
+    public ResourceDescriptor setMediaType(String mediaType) {
+        this.mediaType = mediaType;
+        return this;
+    }
+
+    /**
+     * Sets the name of the resource.
+     *
+     * @param name the resource name
+     * @return this for chaining
+     */
+    public ResourceDescriptor setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    /**
+     * Sets the URI identifying the resource.
+     *
+     * @param uri the resource URI
+     * @return this for chaining
+     */
+    public ResourceDescriptor setUri(String uri) {
+        this.uri = uri;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "ResourceDescriptor{uri='" + uri + '\'' + ", digest=" + digest 
+ '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/RunDetails.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/RunDetails.java
new file mode 100644
index 0000000..da14aef
--- /dev/null
+++ b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/RunDetails.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.List;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Details about the build invocation: the builder identity, execution 
metadata, and any byproduct artifacts.
+ *
+ * @see <a href="https://slsa.dev/spec/v1.2";>SLSA v1.2 Specification</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class RunDetails {
+
+    /**
+     * Entity that executed the build.
+     */
+    @JsonProperty("builder")
+    private Builder builder;
+    /**
+     * Artifacts produced as a side effect of the build.
+     */
+    @JsonProperty("byproducts")
+    private List<ResourceDescriptor> byproducts;
+    /**
+     * Metadata about the build invocation.
+     */
+    @JsonProperty("metadata")
+    private BuildMetadata metadata;
+
+    /**
+     * Creates a new RunDetails instance.
+     */
+    public RunDetails() {
+    }
+
+    /**
+     * Creates a new RunDetails with the given builder and metadata.
+     *
+     * @param builder  entity that executed the build
+     * @param metadata metadata about the build invocation
+     */
+    public RunDetails(Builder builder, BuildMetadata metadata) {
+        this.builder = builder;
+        this.metadata = metadata;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        RunDetails that = (RunDetails) o;
+        return Objects.equals(builder, that.builder) && 
Objects.equals(metadata, that.metadata) && Objects.equals(byproducts, 
that.byproducts);
+    }
+
+    /**
+     * Gets the builder that executed the invocation.
+     *
+     * <p>Trusted to have correctly performed the operation and populated this 
provenance.</p>
+     *
+     * @return the builder, or {@code null} if not set
+     */
+    public Builder getBuilder() {
+        return builder;
+    }
+
+    /**
+     * Gets artifacts produced as a side effect of the build that are not the 
primary output.
+     *
+     * @return the list of byproduct artifacts, or {@code null} if not set
+     */
+    public List<ResourceDescriptor> getByproducts() {
+        return byproducts;
+    }
+
+    /**
+     * Gets the metadata about the build invocation, including its identifier 
and timing.
+     *
+     * @return the build metadata, or {@code null} if not set
+     */
+    public BuildMetadata getMetadata() {
+        return metadata;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(builder, metadata, byproducts);
+    }
+
+    /**
+     * Sets the builder that executed the invocation.
+     *
+     * @param builder the builder
+     * @return this for chaining
+     */
+    public RunDetails setBuilder(Builder builder) {
+        this.builder = builder;
+        return this;
+    }
+
+    /**
+     * Sets the artifacts produced as a side effect of the build that are not 
the primary output.
+     *
+     * @param byproducts the list of byproduct artifacts
+     * @return this for chaining
+     */
+    public RunDetails setByproducts(List<ResourceDescriptor> byproducts) {
+        this.byproducts = byproducts;
+        return this;
+    }
+
+    /**
+     * Sets the metadata about the build invocation.
+     *
+     * @param metadata the build metadata
+     * @return this for chaining
+     */
+    public RunDetails setMetadata(BuildMetadata metadata) {
+        this.metadata = metadata;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "RunDetails{builder=" + builder + ", metadata=" + metadata + ", 
byproducts=" + byproducts + '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Signature.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Signature.java
new file mode 100644
index 0000000..77e7698
--- /dev/null
+++ b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Signature.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * A single cryptographic signature within a DSSE envelope.
+ *
+ * @see <a 
href="https://github.com/secure-systems-lab/dsse/blob/v1.0.2/envelope.md";>DSSE 
Envelope specification</a>
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Signature {
+
+    /**
+     * Hint for which key was used to sign; unset is treated as empty.
+     *
+     * <p>Consumers MUST NOT require this field to be set, and MUST NOT use it 
for security decisions.</p>
+     */
+    @JsonProperty("keyid")
+    private String keyid;
+
+    /** Raw signature bytes of the PAE-encoded payload. */
+    @JsonProperty("sig")
+    private byte[] sig;
+
+    /** Creates a new Signature instance. */
+    public Signature() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Signature)) {
+            return false;
+        }
+        Signature signature = (Signature) o;
+        return Objects.equals(keyid, signature.keyid) && Arrays.equals(sig, 
signature.sig);
+    }
+
+    /**
+     * Gets the key identifier hint, or {@code null} if not set.
+     *
+     * @return the key identifier, or {@code null}
+     */
+    public String getKeyid() {
+        return keyid;
+    }
+
+    /**
+     * Gets the raw signature bytes.
+     *
+     * @return the signature bytes, or {@code null} if not set
+     */
+    public byte[] getSig() {
+        return sig;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(keyid, Arrays.hashCode(sig));
+    }
+
+    /**
+     * Sets the key identifier hint.
+     *
+     * @param keyid the key identifier, or {@code null} to leave unset
+     * @return this for chaining
+     */
+    public Signature setKeyid(String keyid) {
+        this.keyid = keyid;
+        return this;
+    }
+
+    /**
+     * Sets the raw signature bytes.
+     *
+     * @param sig the signature bytes
+     * @return this for chaining
+     */
+    public Signature setSig(byte[] sig) {
+        this.sig = sig;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "Signature{keyid='" + keyid + "', sig=<" + (sig != null ? 
sig.length : 0) + " bytes>}";
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Statement.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Statement.java
new file mode 100644
index 0000000..1d779c6
--- /dev/null
+++ b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/Statement.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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 org.apache.commons.release.plugin.slsa.v1_2;
+
+import java.util.List;
+import java.util.Objects;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * In-toto v1 attestation envelope that binds a set of subject artifacts to an 
SLSA provenance predicate.
+ *
+ * @see <a 
href="https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md";>in-toto
 Statement v1</a>
+ */
+public class Statement {
+
+    /** The in-toto statement schema URI. */
+    public static final String TYPE = "https://in-toto.io/Statement/v1";;
+    /** The provenance predicate. */
+    @JsonProperty("predicate")
+    private Provenance predicate;
+    /** URI identifying the type of the predicate. */
+    @JsonProperty("predicateType")
+    private String predicateType;
+    /** Software artifacts that the attestation applies to. */
+    @JsonProperty("subject")
+    private List<ResourceDescriptor> subject;
+
+    /** Creates a new Statement instance. */
+    public Statement() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Statement)) {
+            return false;
+        }
+        Statement statement = (Statement) o;
+        return Objects.equals(subject, statement.subject) && 
Objects.equals(predicateType, statement.predicateType) && 
Objects.equals(predicate,
+                statement.predicate);
+    }
+
+    /**
+     * Type of JSON object.
+     *
+     * @return Always {@value TYPE}
+     */
+    @JsonProperty("_type")
+    public String getType() {
+        return TYPE;
+    }
+
+    /**
+     * Gets the provenance predicate.
+     *
+     * <p>Unset is treated the same as set-but-empty. May be omitted if {@code 
predicateType} fully describes the
+     * predicate.</p>
+     *
+     * @return the provenance predicate, or {@code null} if not set
+     */
+    public Provenance getPredicate() {
+        return predicate;
+    }
+
+    /**
+     * Gets the URI identifying the type of the predicate.
+     *
+     * @return the predicate type URI, or {@code null} if no predicate has 
been set
+     */
+    public String getPredicateType() {
+        return predicateType;
+    }
+
+    /**
+     * Gets the set of software artifacts that the attestation applies to.
+     *
+     * <p>Each element represents a single artifact. Artifacts are matched 
purely by digest, regardless of content type.</p>
+     *
+     * @return the list of subject artifacts, or {@code null} if not set
+     */
+    public List<ResourceDescriptor> getSubject() {
+        return subject;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(subject, predicateType, predicate);
+    }
+
+    /**
+     * Sets the provenance predicate and automatically assigns {@code 
predicateType} to the SLSA provenance v1 URI.
+     *
+     * @param predicate the provenance predicate
+     * @return this for chaining
+     */
+    public Statement setPredicate(Provenance predicate) {
+        this.predicate = predicate;
+        this.predicateType = Provenance.PREDICATE_TYPE;
+        return this;
+    }
+
+    /**
+     * Sets the set of software artifacts that the attestation applies to.
+     *
+     * @param subject the list of subject artifacts
+     * @return this for chaining
+     */
+    public Statement setSubject(List<ResourceDescriptor> subject) {
+        this.subject = subject;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        return "Statement{_type='" + TYPE + "', subject=" + subject + ", 
predicateType='" + predicateType + "', predicate=" + predicate + '}';
+    }
+}
diff --git 
a/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/package-info.java 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/package-info.java
new file mode 100644
index 0000000..69a5ce2
--- /dev/null
+++ 
b/src/main/java/org/apache/commons/release/plugin/slsa/v1_2/package-info.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      https://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.
+ */
+
+/**
+ * SLSA 1.2 Build Attestation Models.
+ *
+ * <p>This package provides Jackson-annotated model classes that implement the 
<a href="https://slsa.dev/spec/v1.2";>Supply-chain Levels for Software Artifacts
+ * (SLSA) v1.2 specification</a>.</p>
+ *
+ * <h2>Overview</h2>
+ *
+ * <p>SLSA is a framework for evaluating and improving the security posture of 
build systems. SLSA v1.2 defines a standard for recording build provenance:
+ * information about how software artifacts were produced.</p>
+ *
+ * @see <a href="https://slsa.dev/spec/v1.2";>SLSA v1.2 Specification</a>
+ * @see <a href="https://github.com/in-toto/attestation";>In-toto Attestation 
Framework</a>
+ * @see <a href="https://github.com/FasterXML/jackson";>Jackson JSON 
processor</a>
+ */
+package org.apache.commons.release.plugin.slsa.v1_2;
+

Reply via email to