Safeguard
Software Supply Chain•

How do you sign artifacts and record provenance in CircleCI?

Bind CircleCI signing and cloud access to one project and branch with OIDC identity, record SLSA style provenance, and verify both before you deploy.

Safeguard Security Team
5 min read

To sign artifacts and record provenance in CircleCI, tie signing to the job's OIDC identity instead of a stored key, generate a provenance statement that names the source commit and builder, sign both, and make the deploy step verify the signature and expected identity before it runs.

What does provenance add to a signature?

A signature says someone with a key vouched for the file. Provenance says how the file was made. The SLSA specification describes provenance as verifiable information about software artifacts describing where, when and how something was produced, and defines a predicate that records the builder, the build parameters, the resolved dependencies such as the exact git commit, and the artifacts produced.

Its level model is useful for setting a target. Build level 1 means provenance exists, which helps avoid mistakes but is trivial to forge. Level 2 requires signed provenance generated by a hosted build platform, which deters tampering after the build. Level 3 needs a hardened build platform that resists tampering during the build. A team moving from nothing should aim for level 1 this month and level 2 soon, and be honest about which it has reached.

What identity does a CircleCI job carry?

CircleCI provides OpenID Connect ID tokens in environment variables, CIRCLE_OIDC_TOKEN and CIRCLE_OIDC_TOKEN_V2. The second adds source of change details to the subject claim. The documentation lists claims for the organization, the project ID, the job ID, the pipeline and the context IDs, and says the project ID claim is for restricting access to specific projects. The default audience is the organization ID.

With the V2 subject, the trust policy for a cloud role can be limited to one project and one branch, for example refs/heads/main under a named repository. The docs show that pattern for AWS, and a mapping for Google Cloud workload identity federation. Forked builds only receive OIDC tokens when the setting to pass secrets to forked pull requests is enabled, so leave that off for projects that sign releases.

How does identity based signing work?

Sigstore's documentation describes keyless signing: an ephemeral key pair is created, the signer proves an OpenID Connect identity, a certificate authority issues a short-lived certificate binding the key to that identity, and the signing event is recorded in a transparency log. Cosign can take an identity token directly, and the token's audience must contain sigstore. Verification then checks the identity and issuer, not a key you have to guard.

The catch for CircleCI is that its default token audience is the organization ID. The pages we read do not show a Sigstore ready configuration, so check CircleCI's custom claims documentation for whether you can set the audience Sigstore requires. If not, use a signing key held in a cloud key service, reached by the OIDC role described above, and avoid a key stored in a context.

A constructed example

A release workflow builds a container image, writes a provenance file naming the commit and workflow, signs the image and the file, and pushes them. The cloud role that allows the push trusts only the project ID and main branch. The deploy job runs in a different project with a different role. It pulls the image, verifies the signature and the expected build identity, compares the commit in provenance to the release tag, and refuses to run if anything differs. A developer who pushes a feature branch cannot produce an image that passes.

What to do

  1. Decide your target level, level 1 first, and write the expectation: which project, branch and workflow may build releases.
  2. Restrict the release role to that project and branch using the OIDC claims.
  3. Keep forked pull request secrets disabled on release projects.
  4. Generate provenance for each release artifact, including source commit and builder identity.
  5. Sign artifacts and provenance, using identity based signing if your audience settings allow it, or a key in a managed key service.
  6. Verify in the deploy step, and fail closed when the signature, identity or commit does not match.
  7. Store signatures and provenance next to the artifact, and keep records for audit.

Safeguard's policy gates can block a release that fails checks like these, as in the CI/CD actions demo.

Quick check

Is signing the same as provenance?

No. A signature shows who vouched for an artifact. Provenance records how it was built, from which source and by which builder.

Why bind a cloud role to project and branch?

So only the release workflow can obtain release credentials. A job in another project or branch has a different identity and is refused.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.