In the previous step, we performed an attestation process that contained two pieces of evidence, but none of those were required. Now, our Security and Compliance team wants to force us to always provide those pieces of evidence, this is achieved through the definition of contracts.

A contract is the interface between development pipelines and the requirements defined by the Security and Compliance teams in the Chainloop Service. It defines the pieces of evidence that are expected to be received as part of the attestation process, as well as some additional constraints, like the type of source (Github, Dagger …, etc.) and the policies that must be evaluated.

See our Contracts reference for more information.

Create a contract

First, let’s create a simple contract, exposing two materials: a container image reference, and an optional SBOM.

Click on “Create Contract”, and create a new contract with the name “qs-contract”, and with the following schema:

schemaVersion: v1
materials:
  - name: container
    type: CONTAINER_IMAGE
  - name: sbom
    type: SBOM_CYCLONEDX_JSON
    optional: true

Initialize an Attestation process

Let’s perform another attestation, but note that this time we are explicitly referencing the contract we just created.

chainloop att init --workflow qs-contract --project myproject --contract qs-contract --replace
INF Attestation initialized! now you can check its status or add materials to it
┌───────────────────────────┬──────────────────────────────────────┐
│ Initialized At            │ 14 Mar 25 10:52 UTC                  │
├───────────────────────────┼──────────────────────────────────────┤
│ Attestation ID            │ a7d4e66b-2f88-44ad-8fda-9dab8dc1bd43 │
│ Organization              │ silly-greider-943                    │
│ Name                      │ qs-contract                          │
│ Project                   │ myproject                            │
│ Version                   │ none                                 │
│ Contract                  │ myproject-qs-contract (revision 1)
│ Timestamp Authority       │ http://timestamp.digicert.com        │
│ Policy violation strategy │ ADVISORY                             │
└───────────────────────────┴──────────────────────────────────────┘
┌────────────────────────────────┐
│ Materials                      │
├──────────┬─────────────────────┤
│ Name     │ container           │
│ Type     │ CONTAINER_IMAGE     │
│ Set      │ No                  │
│ Required │ Yes                 │
├──────────┼─────────────────────┤
│ Name     │ sbom                │
│ Type     │ SBOM_CYCLONEDX_JSON │
│ Set      │ No                  │
│ Required │ No                  │
└──────────┴─────────────────────┘

Alternatively, you can create the contract on the fly during the attestation process. To do so, you can provide the reference to a remote, or local yaml file containing the contract definition.

chainloop att init --workflow qs-contract --project myproject --contract qs-contract.yaml --replace

Adding materials and pushing the attestation.

Note that the attestation init command output this time includes a section indicating that a CONTAINER_IMAGE is required alongside with an optional SBOM_CYCLONEDX_JSON.

What would happen if we try to push without adding any material?

chainloop att push
ERR some materials have not been crafted yet: container

We can see that Chainloop expects us, according to the contract, to provide at least the container image reference, and, optionally, its SBOM. Let’s add them:

chainloop att add --name container --value ghcr.io/chainloop-dev/chainloop/control-plane

Note that we have specified --name container, since that’s the material name that the contract expects. You can learn more about the adding materials process in the Adding Materials section.

And now the Software Bill of Materials:

chainloop att add --name sbom --value https://raw.githubusercontent.com/chainloop-dev/chainloop/refs/heads/main/docs/examples/quickstart/sbom.json

And now we can push the attestation:

chainloop att push
INF push completed

As before, we can see the details of our attestation in Chainloop Platform:

We have successfully created an attestation that matches the contract’s expectations.

Next steps

In the next step, we’ll learn how to run additional policies on the provided metadata