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.
Let’s perform another attestation, but note how this time the requirements have changed
Copy
chainloop att init --workflow build-container-image --project myproject --replace
Copy
┌───────────────────────────┬──────────────────────────────────────────────┐│ Initialized At │ 13 May 25 09:52 UTC │├───────────────────────────┼──────────────────────────────────────────────┤│ Attestation ID │ ce0a4e64-cdde-477a-8141-70cd3c198cf4 ││ Organization │ gs-demo ││ Name │ build-container-image ││ Project │ myproject ││ Version │ none ││ Contract │ myproject-build-container-image (revision 2) ││ 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 │ Yes │├──────────┼────────────────────────┤│ Name │ vulnerabilities-report ││ Type │ SARIF ││ Set │ No ││ Required │ Yes │└──────────┴────────────────────────┘
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.
Copy
chainloop att init --workflow build-container-image --project myproject --replace
Note that the attestation init command output this time includes a section indicating that a CONTAINER_IMAGE is required alongside with SBOM_CYCLONEDX_JSON and SARIF.
What would happen if we try to push without adding any material?
Copy
chainloop att pushERR some materials have not been crafted yet: container, sbom, vulnerabilities-report
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:
Copy
chainloop att add --name container --value ghcr.io/chainloop-dev/chainloop/control-plane
Copy
INF material added to attestation┌──────────┬─────────────────────────────────────────────────────────────────────────┐│ Name │ container │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Type │ CONTAINER_IMAGE │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Required │ Yes │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Value │ ghcr.io/chainloop-dev/chainloop/control-plane:latest │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Digest │ sha256:1872ea6f4758de022e127de8b8062db2937195e2ebb30fef6af2271b156f5cd7 │└──────────┴─────────────────────────────────────────────────────────────────────────┘
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.
Now the Software Bill of Materials:
Copy
chainloop att add --name sbom --value https://raw.githubusercontent.com/chainloop-dev/chainloop/refs/heads/main/docs/examples/quickstart/sbom.json
Copy
┌──────────┬─────────────────────────────────────────────────────────────────────────┐│ Name │ sbom │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Type │ SBOM_CYCLONEDX_JSON │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Required │ No │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Value │ sbom.json │├──────────┼─────────────────────────────────────────────────────────────────────────┤│ Digest │ sha256:f2888d10bcd93dc58431049a13acac1bc402231fb066e9e58fd986d91dec05f1 │└──────────┴─────────────────────────────────────────────────────────────────────────┘
And finally a vulnerability report created by grype in SARIF format
Copy
chainloop att add --name vulnerabilities-report --value https://raw.githubusercontent.com/chainloop-dev/chainloop/refs/heads/main/docs/examples/quickstart/vulnerability-report.json