
- A Workflow Contract is immutable and versioned, new revisions of the contract with new/different requirements can be added over time. This is especially useful for iterative integrations.
- A Workflow Contract can belong to more than one Workflow. This means that a change in a single contract will be propagated to many workflows. This is especially useful for org-wide standardization and fleet management.

Managing Contracts
- Web UI
- CLI
Contracts can be managed through the “Contracts” section in Chainloop platform:

- Web UI
- CLI

A Workflow Contract can be provided in json or yaml (cue format is also supported through the Chainloop CLI).
When creating or updating a contract from a file, the CLI resolves the contract name from either the
--name flag or the metadata.name field in the file. Provide at least one of them. You can also provide both as long as they have the same value — the command fails if they differ.Contract Management Scope
Contracts in Chainloop operate at two different scopes with corresponding management permissions:- Organization-scope contracts: Managed by users with Organization Admin or Organization Owner roles. These contracts can be used across all projects within the organization.
- Project-scope contracts: Managed by Project Admins. These contracts are specific to individual projects and can only be used within their respective project scope.
Restricting Contract Creation
Organizations can optionally enable the “Restrict Contract Creation to Organization Admins” setting to enforce stricter governance over contract management. When this setting is enabled:- Only users with Organization Admin or Organization Owner roles can create new contracts (regardless of the contract scope)
- Project Admins that are not Organization Admins can no longer create their own contracts
- Workflows created by non administrators must use existing contracts
Enabling the setting
Organization owner and admins can enable this setting in the organization settings.
Associating workflows to contracts
Once contracts are created, they can be attached to as many workflows as needed. Remember that workflows represent a unique source of data ingestion (attestations), usually representing a CI/CD pipeline.- Web UI
- CLI
In the workflows view, open the workflow’s actions menu, click “Edit” and associate the contract. Once the contract is associated, new attestations will automatically download and apply it, including required materials, policies, and so on.

Writing contracts
Example
See below a contract schema example:Note that the contract below is just an example crafted for educational purposes. In a real scenario, the contract will not contain such a disparate amount of materials or annotations.

Schema
- Schema
- Deprecated Schema
Materials
The contract can require one or more pieces of evidence (a.k.a material) to be attached during the attestation process.”At Least One Of” Material Groups
Sometimes a contract should accept any one of several alternatives rather than a specific material. Assign those materials to the samegroup and Chainloop treats them as an “at least one of” set: the attestation is satisfied as long as at least one member of the group is present.
For example, to accept either a CycloneDX or an SPDX SBOM:
- Materials in a group are not individually required — the requirement is enforced at the group level. Providing any single member satisfies the whole group.
- Materials without a
groupkeep their individualoptional/required behavior. - Group names must follow DNS-1123 label rules: lowercase letters, numbers, and hyphens (e.g.
sbom,sast-report).
chainloop attestation status surfaces each group’s rule and whether it has been satisfied yet, so you can see at a glance which alternatives are still outstanding.
Policy attachments
When defining a contract, a newpolicies section can be specified. Policies can be applied to any material, but also to the attestation statement as a whole.
Runner Context
New runner contexts will be added over time. If yours is not implemented yet, please contact us
skynet.contract.yaml showLineNumbers
- Require the attestation process to be executed in the target runner type unless the
--dry-runflag is set during initialization. - A link to the workload (i.e Github Action Run link) will be recorded both in the attestation and in the control plane during initialization.
- An additional set of environment variables will be resolved in addition to the ones defined in the contract
envAllowList.
AZURE_PIPELINE
The following environment variables will be automatically added to the attestation. For more information on what they mean, refer to this link.
BUILD_REQUESTEDFOREMAILBUILD_REQUESTEDFORBUILD_REPOSITORY_URIBUILD_REPOSITORY_NAMEBUILD_BUILDIDBUILD_BUILDNUMBERBUILD_BUILDURIBUILD_REASONAGENT_VERSIONTF_BUILD
CIRCLECI_BUILD
The following environment variables will be automatically added to the attestation. For more information on their meaning, refer to the official CircleCI documentation.
CIRCLE_BUILD_URLCIRCLE_JOBCIRCLE_BRANCH(optional)CIRCLE_NODE_TOTALCIRCLE_NODE_INDEX
DAGGER_PIPELINE
To use Chainloop With Dagger you can use this Dagger module
Commit Signature Verification: Dagger pipelines can run in various CI environments. Chainloop automatically detects the underlying platform (GitHub Actions or GitLab CI) and verifies commit signatures through the appropriate API when GITHUB_TOKEN or CI_JOB_TOKEN is available. The verification status and signature algorithm are recorded in the attestation annotations.
GITHUB_ACTION
The following environment variables will be automatically added to the attestation. For more information on what they do refer to this link.
GITHUB_ACTORGITHUB_REFGITHUB_REPOSITORYGITHUB_REPOSITORY_OWNERGITHUB_RUN_IDGITHUB_SHARUNNER_NAMERUNNER_OS
GITHUB_TOKEN is available, Chainloop automatically verifies commit signatures through GitHub’s API and records the verification status (verified, unverified, unavailable, not_applicable) and signature algorithm (e.g., PGP, SSH, X509) in the attestation annotations. This provides auditable evidence that commits are cryptographically signed and verified by GitHub.
The default GITHUB_TOKEN provided by GitHub Actions has sufficient permissions to query commit verification status. No additional configuration is required - the token is automatically available in the workflow environment.
GITLAB_PIPELINE
The following environment variables will be automatically added to the attestation. More information about what they mean in GitLab’s official documentation
GITLAB_USER_EMAILGITLAB_USER_LOGINCI_PROJECT_URLCI_COMMIT_SHACI_JOB_URLCI_PIPELINE_URLCI_RUNNER_VERSIONCI_RUNNER_DESCRIPTIONCI_COMMIT_REF_NAME
CI_JOB_TOKEN is available, Chainloop automatically verifies commit signatures through GitLab’s API and records the verification status (verified, unverified, unavailable, not_applicable) and signature algorithm (e.g., PGP, SSH, X509) in the attestation annotations. This provides auditable evidence that commits are cryptographically signed and verified by GitLab.
The CI_JOB_TOKEN is automatically available in GitLab CI pipelines and has the necessary permissions to query commit signature information.
JENKINS_JOB
The following environment variables will be automatically added to the attestation. For more information on how to use Jenkins environment variables, refer to the official Jenkins documentation.
JOB_NAMEBUILD_URLGIT_BRANCH(optional)GIT_COMMIT(optional)AGENT_WORKDIRNODE_NAME
TEAMCITY_PIPELINE
The following environment variables will be automatically added to the attestation. For more information on TeamCity environment variables, refer to the official TeamCity documentation.
BUILD_URLTEAMCITY_PROJECT_NAMETEAMCITY_VERSIONBUILD_NUMBERUSERTEAMCITY_GIT_VERSIONBUILD_VCS_NUMBERHOME
TEKTON_PIPELINE
The following variables are automatically discovered and added to the attestation. No environment variable wiring is needed in your Pipeline YAML — the runner discovers everything from Kubernetes pod labels and the ServiceAccount namespace file.
A run link will be recorded in the control plane during initialization, using the format
tekton://<namespace>/pipelineruns/<name>. If the TEKTON_DASHBOARD_URL environment variable is set, a Tekton Dashboard URL will be used instead.
RBAC requirement: The TaskRun ServiceAccount needs
get permission on pods in its namespace for pod label discovery. If the permission is missing, the runner degrades gracefully and captures only the variables available without it.Skip storing runner-discovered environment variables
As shown above, each runner automatically discovers a set of environment variables and stores them in the attestation as build metadata. If your organization prefers not to persist these auto-discovered variables, an organization owner or admin can opt out with theskip_runner_env_vars organization setting.
When this setting is enabled, the environment variables that the runner injects automatically (the per-runner lists above) are no longer collected into the attestation. The following are not affected:
- The contract’s
envAllowList— these are an explicit, user-defined opt-in and are always resolved and injected. - Runner detection — Chainloop still detects the runner type and enforces the contract’s
runnerconstraint. - The structured runner metadata, such as the recorded run link, which is unaffected.
This setting is disabled by default (
false), preserving the current behavior. It applies to the whole organization, and only organization owners and admins can change it.- Web UI
- CLI
Navigate to the organization settings and enable the Skip Runner-Discovered Environment Variables toggle.

Gather Additional Runner Configuration
The Chainloop CLI Enterprise Edition provides a runner context that can be used to gather the runner context. When Chainloop CLI Enterprise Edition is used it enables automatic retrieval of the following data:- Branch protection rules
- Pull request requirements
- Commit policies
- Verifying that proper protections were in place during the build process
- Understanding what security measures are protecting the code
- Proving that security policies were followed during development
