Action for generating build provenance attestations for workflow artifacts
Go to file
dependabot[bot] c6f9859ac6
Some checks failed
Check Transpiled JavaScript / Check dist/ (push) Failing after 20s
Continuous Integration / TypeScript Tests (push) Failing after 1s
Continuous Integration / Test attest-provenance action (push) Failing after 1s
CodeQL / Analyze (TypeScript) (push) Failing after 2s
Public-Good Sigstore Prober / prober (push) Failing after 2s
GitHub Sigstore Prober / prober (push) Failing after 1s
Bump the actions-minor group with 3 updates (#765)
Bumps the actions-minor group with 3 updates: [actions/checkout](https://github.com/actions/checkout), [actions/setup-node](https://github.com/actions/setup-node) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `actions/checkout` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](1af3b93b68...8e8c483db8)

Updates `actions/setup-node` from 6.0.0 to 6.1.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](2028fbc5c2...395ad32622)

Updates `github/codeql-action` from 4.31.5 to 4.31.7
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fdbfb4d275...cf1bb45a27)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor
- dependency-name: actions/setup-node
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor
- dependency-name: github/codeql-action
  dependency-version: 4.31.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-08 10:18:51 -08:00
__tests__ Bump the npm-development group across 1 directory with 11 updates (#752) 2025-11-20 10:18:58 -08:00
.github Bump the actions-minor group with 3 updates (#765) 2025-12-08 10:18:51 -08:00
dist Bump the npm-development group across 1 directory with 11 updates (#752) 2025-11-20 10:18:58 -08:00
predicate Bump to node24 runtime (#692) 2025-08-26 20:53:13 -07:00
src bump @actions/attest from 1.4.1 to 1.4.2 (#225) 2024-09-05 10:04:26 -07:00
.gitattributes Initial commit 2024-02-20 11:26:39 -08:00
.gitignore reference @actions/attest package (#10) 2024-02-26 14:49:08 -08:00
.markdown-lint.yml refactor eslint config (#690) 2025-08-26 16:57:28 -07:00
.node-version Bump to node24 runtime (#692) 2025-08-26 20:53:13 -07:00
.prettierignore Initial commit 2024-02-20 11:26:39 -08:00
.prettierrc.json Initial commit 2024-02-20 11:26:39 -08:00
action.yml bump attest-build-provenance/predicate to v2.0.0 (#693) 2025-08-28 14:03:13 -07:00
CODEOWNERS add package-security team to CODEOWNERS 2024-02-23 17:15:18 -08:00
eslint.config.mjs refactor eslint config (#690) 2025-08-26 16:57:28 -07:00
jest.setup.js unit test (#13) 2024-02-29 17:04:03 -08:00
LICENSE Initial commit 2024-02-20 11:26:39 -08:00
package-lock.json Bump the npm-development group with 3 updates (#766) 2025-12-08 10:18:08 -08:00
package.json Bump the npm-development group with 3 updates (#766) 2025-12-08 10:18:08 -08:00
README.md update doc references to v3 release (#697) 2025-08-28 14:23:03 -07:00
RELEASE.md update release documentation (#66) 2024-05-10 10:47:07 -07:00
tsconfig.json Bump jest and @types/jest (#660) 2025-06-17 09:51:53 -07:00
tsconfig.lint.json refactor eslint config (#690) 2025-08-26 16:57:28 -07:00

actions/attest-build-provenance

Public-Good Sigstore Prober GitHub Sigstore Prober

Generate signed build provenance attestations for workflow artifacts. Internally powered by the @actions/attest package.

Attestations bind some subject (a named artifact along with its digest) to a SLSA build provenance predicate using the in-toto format.

A verifiable signature is generated for the attestation using a short-lived Sigstore-issued signing certificate. If the repository initiating the GitHub Actions workflow is public, the public-good instance of Sigstore will be used to generate the attestation signature. If the repository is private/internal, it will use the GitHub private Sigstore instance.

Once the attestation has been created and signed, it will be uploaded to the GH attestations API and associated with the repository from which the workflow was initiated.

Attestations can be verified using the attestation command in the GitHub CLI.

See Using artifact attestations to establish provenance for builds for more information on artifact attestations.

Note

Artifact attestations are available in public repositories for all current GitHub plans. They are not available on legacy plans, such as Bronze, Silver, or Gold. If you are on a GitHub Free, GitHub Pro, or GitHub Team plan, artifact attestations are only available for public repositories. To use artifact attestations in private or internal repositories, you must be on a GitHub Enterprise Cloud plan.

Usage

Within the GitHub Actions workflow which builds some artifact you would like to attest:

  1. Ensure that the following permissions are set:

    permissions:
      id-token: write
      attestations: write
    

    The id-token permission gives the action the ability to mint the OIDC token necessary to request a Sigstore signing certificate. The attestations permission is necessary to persist the attestation.

  2. Add the following to your workflow after your artifact has been built:

    - uses: actions/attest-build-provenance@v3
      with:
        subject-path: '<PATH TO ARTIFACT>'
    

    The subject-path parameter should identify the artifact for which you want to generate an attestation.

Inputs

See action.yml

- uses: actions/attest-build-provenance@v3
  with:
    # Path to the artifact serving as the subject of the attestation. Must
    # specify exactly one of "subject-path", "subject-digest", or
    # "subject-checksums". May contain a glob pattern or list of paths
    # (total subject count cannot exceed 1024).
    subject-path:

    # SHA256 digest of the subject for the attestation. Must be in the form
    # "sha256:hex_digest" (e.g. "sha256:abc123..."). Must specify exactly one
    # of "subject-path", "subject-digest", or "subject-checksums".
    subject-digest:

    # Subject name as it should appear in the attestation. Required when
    # identifying the subject with the "subject-digest" input.
    subject-name:

    # Path to checksums file containing digest and name of subjects for
    # attestation. Must specify exactly one of "subject-path", "subject-digest",
    # or "subject-checksums".
    subject-checksums:

    # Whether to push the attestation to the image registry. Requires that the
    # "subject-name" parameter specify the fully-qualified image name and that
    # the "subject-digest" parameter be specified. Defaults to false.
    push-to-registry:

    # Whether to attach a list of generated attestations to the workflow run
    # summary page. Defaults to true.
    show-summary:

    # The GitHub token used to make authenticated API requests. Default is
    # ${{ github.token }}
    github-token:

Outputs

Name Description Example
attestation-id GitHub ID for the attestation 123456
attestation-url URL for the attestation summary https://github.com/foo/bar/attestations/123456
bundle-path Absolute path to the file containing the generated attestation /tmp/attestation.json

Attestations are saved in the JSON-serialized Sigstore bundle format.

If multiple subjects are being attested at the same time, a single attestation will be created with references to each of the supplied subjects.

The absolute path to the generated attestation is appended to the file ${RUNNER_TEMP}/created_attestation_paths.txt. This file will accumulate the paths to all attestations created over the course of a single workflow.

Attestation Limits

Subject Limits

No more than 1024 subjects can be attested at the same time.

Examples

Identify Subject by Path

For the basic use case, simply add the attest-build-provenance action to your workflow and supply the path to the artifact for which you want to generate attestation.

name: build-attest

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      attestations: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Build artifact
        run: make my-app
      - name: Attest
        uses: actions/attest-build-provenance@v3
        with:
          subject-path: '${{ github.workspace }}/my-app'

Identify Multiple Subjects

If you are generating multiple artifacts, you can attest all of them at the same time by using a wildcard in the subject-path input.

- uses: actions/attest-build-provenance@v3
  with:
    subject-path: 'dist/**/my-bin-*'

For supported wildcards along with behavior and documentation, see @actions/glob which is used internally to search for files.

Alternatively, you can explicitly list multiple subjects with either a comma or newline delimited list:

- uses: actions/attest-build-provenance@v3
  with:
    subject-path: 'dist/foo, dist/bar'
- uses: actions/attest-build-provenance@v3
  with:
    subject-path: |
      dist/foo
      dist/bar      

Identify Subjects with Checksums File

If you are using tools like goreleaser or jreleaser which generate a checksums file you can identify the attestation subjects by passing the path of the checksums file to the subject-checksums input. Each of the artifacts identified in the checksums file will be listed as a subject for the attestation.

- name: Calculate artifact digests
  run: |
    shasum -a 256 foo_0.0.1_* > subject.checksums.txt    
- uses: actions/attest-build-provenance@v3
  with:
    subject-checksums: subject.checksums.txt

The file referenced by the subject-checksums input must conform to the same format used by the shasum tools. Each subject should be listed on a separate line including the hex-encoded digest (either SHA256 or SHA512), a space, a single character flag indicating either binary (*) or text ( ) input mode, and the filename.

b569bf992b287f55d78bf8ee476497e9b7e9d2bf1c338860bfb905016218c740  foo_0.0.1_darwin_amd64
a54fc515e616cac7fcf11a49d5c5ec9ec315948a5935c1e11dd610b834b14dde  foo_0.0.1_darwin_arm64

Container Image

When working with container images you can invoke the action with the subject-name and subject-digest inputs.

If you want to publish the attestation to the container registry with the push-to-registry option, it is important that the subject-name specify the fully-qualified image name (e.g. "ghcr.io/user/app" or "acme.azurecr.io/user/app"). Do NOT include a tag as part of the image name -- the specific image being attested is identified by the supplied digest.

Attestation bundles are stored in the OCI registry according to the Cosign Bundle Specification.

Note

: When pushing to Docker Hub, please use "index.docker.io" as the registry portion of the image name.

name: build-attested-image

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      packages: write
      contents: read
      attestations: write
    env:
      REGISTRY: ghcr.io
      IMAGE_NAME: ${{ github.repository }}

    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push image
        id: push
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
      - name: Attest
        uses: actions/attest-build-provenance@v3
        id: attest
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          subject-digest: ${{ steps.push.outputs.digest }}
          push-to-registry: true

Integration with actions/upload-artifact

If you'd like to create an attestation for an archive created with the actions/upload-artifact action you can feed the digest of the generated artifact directly into the subject-digest input of the attestation action.

- name: Upload build artifact
  id: upload
  uses: actions/upload-artifact@v4
  with:
    path: dist/*
    name: artifact.zip

- uses: actions/attest-build-provenance@v3
  with:
    subject-name: artifact.zip
    subject-digest: sha256:${{ steps.upload.outputs.artifact-digest }}