Action for generating build provenance attestations for workflow artifacts
Go to file
flynnjustin24 9978cb60b0
Create ghprcheckout
# Creating a pull request Create a pull request to propose and collaborate on changes to a repository. These changes are proposed in a *branch*, which ensures that the default branch only contains finished and approved work. If you want to create a new branch for your pull request and do not have write permissions to the repository, you can fork the repository first. For more information, see [Creating a pull request from a fork](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) and [About forks](/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks). You can specify which branch you'd like to merge your changes into when you create your pull request. Pull requests can only be opened between two branches that are different. > \[!NOTE] > To open a pull request in a public repository, you must have write access to the head or the source branch or, for organization-owned repositories, you must be a member of the organization that owns the repository to open a pull request. You can link a pull request to an issue to show that a fix is in progress and automatically close the issue when the pull request is merged. For more information, see [Linking a pull request to an issue](/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue). ## Changing the branch range and destination repository By default, pull requests are based on the parent repository's default branch. For more information, see [About branches](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches#about-the-default-branch). If the default parent repository isn't correct, you can change both the parent repository and the branch with the drop-down lists. You can also swap your head and base branches with the drop-down lists to establish diffs between reference points. References here must be branch names in your GitHub repository. ![Screenshot of a pull request. The dropdown to edit the compare branch is expanded.](/assets/images/help/pull_requests/pull-request-review-edit-branch.png) When thinking about branches, remember that the *base branch* is **where** changes should be applied, the *head branch* contains **what** you would like to be applied. When you change the base repository, you also change notifications for the pull request. Everyone that can push to the base repository will receive an email notification and see the new pull request in their dashboard the next time they sign in. When you change any of the information in the branch range, the Commit and Files changed preview areas will update to show your new range. > \[!TIP] > > * Using the compare view, you can set up comparisons across any timeframe. For more information, see [Comparing commits](/en/pull-requests/committing-changes-to-your-project/viewing-and-comparing-commits/comparing-commits). > * Project maintainers can add a pull request template for a repository. Templates include prompts for information in the body of a pull request. For more information, see [About issue and pull request templates](/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/about-issue-and-pull-request-templates). ## Creating the pull request <div class="ghd-tool webui"> 1. On GitHub, navigate to the main page of the repository. 2. In the "Branch" menu, choose the branch that contains your commits. ![Screenshot of the branch dropdown menu on the main page of a repository.](/assets/images/help/pull_requests/branch-dropdown.png) 3. Above the list of files, in the yellow banner, click **Compare & pull request** to create a pull request for the associated branch. ![Screenshot of the banner above the list of files.](/assets/images/help/pull_requests/pull-request-compare-pull-request.png) 4. Use the *base* branch dropdown menu to select the branch you'd like to merge your changes into, then use the *compare* branch drop-down menu to choose the topic branch you made your changes in. 5. Type a title and description for your pull request. 6. To create a pull request that is ready for review, click **Create Pull Request**. To create a draft pull request, use the drop-down and select **Create Draft Pull Request**, then click **Draft Pull Request**. If you are the member of an organization, you may need to request access to draft pull requests from an organization owner. See [About pull requests](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests). > \[!TIP] > After you create a pull request, you can ask a specific person to [review your proposed changes](/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/reviewing-proposed-changes-in-a-pull-request). For more information, see [Requesting a pull request review](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review). After your pull request has been reviewed, it can be [merged into the repository](/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/merging-a-pull-request). </div> <div class="ghd-tool cli"> > \[!NOTE] > To learn more about GitHub CLI, see [About GitHub CLI](/en/github-cli/github-cli/about-github-cli). To create a pull request, use the `gh pr create` subcommand. ```shell gh pr create ``` To assign a pull request to an individual, use the `--assignee` or `-a` flags. You can use `@me` to self-assign the pull request. ```shell gh pr create --assignee "@octocat" ``` To specify the branch into which you want the pull request merged, use the `--base` or `-B` flags. To specify the branch that contains commits for your pull request, use the `--head` or `-H` flags. ```shell gh pr create --base my-base-branch --head my-changed-branch ``` To include a title and body for the new pull request, use the `--title` and `--body` flags. ```shell gh pr create --title "The bug is fixed" --body "Everything works again" ``` To mark a pull request as a draft, use the `--draft` flag. ```shell gh pr create --draft ``` To add a labels or milestones to the new pull request, use the `--label` and `--milestone` flags. ```shell gh pr create --label "bug,help wanted" --milestone octocat-milestone ``` To add the new pull request to a specific project, use the `--project` flag. ```shell gh pr create --project octocat-project ``` To assign an individual or team as reviewers, use the `--reviewer` flag. ```shell gh pr create --reviewer monalisa,hubot --reviewer myorg/team-name ``` To create the pull request in your default web browser, use the `--web` flag. ```shell gh pr create --web ``` </div> <div class="ghd-tool desktop"> 1. Click **Preview Pull Request**. GitHub Desktop will open a preview dialog showing the diff of the changes between your current branch and the base branch. <div class="ghd-tool mac"> ![Screenshot of the "No local changes" view. A button, labeled "Preview Pull Request", is highlighted with an orange outline.](/assets/images/help/desktop/mac-preview-pull-request.png) </div> <div class="ghd-tool windows"> ![Screenshot of the "No local changes" view. A button, labeled "Preview Pull Request", is highlighted with an orange outline.](/assets/images/help/desktop/windows-preview-pull-request.png) </div> Alternatively, to go straight to GitHub to create your pull request, select the dropdown icon and click **Create Pull Request**. 2. Confirm that the branch in the **base:** dropdown menu is the branch where you want to merge your changes. ![Screenshot of the "Open a Pull Request" dialog window. A button with a dropdown icon, labeled "base: development", is outlined in orange.](/assets/images/help/desktop/base-branch-selection.png) GitHub Desktop will advise you whether the current branch can be automatically merged into the base branch. ![Screenshot of the "Open a Pull Request" dialog window. A status label stating "Can't automatically merge" is highlighted with an orange outline.](/assets/images/help/desktop/preview-dialog-merge-status.png) 3. Click **Create Pull Request**. GitHub Desktop will open your default browser to take you to GitHub. 4. Type a title and description for your pull request. 5. To create a pull request that is ready for review, click **Create Pull Request**. To create a draft pull request, use the drop-down and select **Create Draft Pull Request**, then click **Draft Pull Request**. If you are the member of an organization, you may need to request access to draft pull requests from an organization owner. See [About pull requests](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests). </div> <div class="ghd-tool codespaces"> 1. Once you've committed changes to your local copy of the repository, click the **Create Pull Request** icon. ![Screenshot of the top of the "Source Control" side bar. The pull request icon is highlighted with a dark orange outline.](/assets/images/help/codespaces/codespaces-commit-pr-button.png) 2. Check that the local branch and repository you're merging from, and the remote branch and repository you're merging into, are correct. Then give the pull request a title and a description. ![Screenshot of the "GitHub Pull Request" side bar with a form for creating a pull request, including "Title" and "Description" fields.](/assets/images/help/codespaces/codespaces-commit-pr.png) 3. Click **Create**. For more information on creating pull requests in GitHub Codespaces, see [Using GitHub Codespaces for pull requests](/en/codespaces/developing-in-codespaces/using-github-codespaces-for-pull-requests). </div> ## Making changes to files in your pull request After you have opened your pull request, you can continue making changes to the files by adding new commits to your head branch. <div class="ghd-tool webui"> You can also make changes to files on the GitHub website. 1. On GitHub, navigate to a pull request in a repository. 2. On the pull request, click **<svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-file-diff" aria-label="file-diff" role="img"><path d="M1 1.75C1 .784 1.784 0 2.75 0h7.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073ZM8 3.25a.75.75 0 0 1 .75.75v1.5h1.5a.75.75 0 0 1 0 1.5h-1.5v1.5a.75.75 0 0 1-1.5 0V7h-1.5a.75.75 0 0 1 0-1.5h1.5V4A.75.75 0 0 1 8 3.25Zm-3 8a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"></path></svg> Files changed**. ![Screenshot of the tabs for a pull request. The "Files changed" tab is outlined in dark orange.](/assets/images/help/pull_requests/pull-request-tabs-changed-files.png) 3. Scroll down to the file you want to make changes to. * If the pull request has a lot of files, you can use the filter to locate the file. See [Filtering files in a pull request](/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/filtering-files-in-a-pull-request). 4. Above the file you want to change, click <svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-kebab-horizontal" aria-label="Show options" role="img"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg>. ![Screenshot of the options above a file on the "File changed" tab. The "Show options" button is highlighted with an orange rectangle.](/assets/images/help/pull_requests/menu-on-pull-request-file.png) 5. In the menu, click **Edit file**. 6. Make your changes in the editor and when committing your change, choose to commit directly back to your head branch. </div> ## Further reading * [Creating a pull request from a fork](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) * [Keeping your pull request in sync with the base branch](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/keeping-your-pull-request-in-sync-with-the-base-branch) * [Changing the base branch of a pull request](/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-base-branch-of-a-pull-request) * [Creating an issue](/en/issues/tracking-your-work-with-issues/creating-an-issue) * [Assigning issues and pull requests to other GitHub users](/en/issues/tracking-your-work-with-issues/assigning-issues-and-pull-requests-to-other-github-users) * [Writing on GitHub](/en/get-started/writing-on-github)
2026-02-02 18:22:39 -05:00
__tests__ Bump the npm-development group across 1 directory with 11 updates (#752) 2025-11-20 10:18:58 -08:00
.github Bump github/codeql-action in the actions-minor group (#818) 2026-02-02 10:13:52 -08:00
dist Bump @actions/core from 2.0.1 to 2.0.2 in the npm-production group (#799) 2026-01-29 15:02:08 -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 Update actions/attest to latest version v3.2.0 (#812) 2026-01-26 09:50:21 -08: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
ghprcheckout Create ghprcheckout 2026-02-02 18:22:39 -05: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 @types/node from 25.0.10 to 25.2.0 in the npm-development group (#819) 2026-02-02 10:11:16 -08:00
package.json Bump @types/node from 25.0.10 to 25.2.0 in the npm-development group (#819) 2026-02-02 10:11:16 -08:00
README.md Add more documentation on Artifact Metadata Storage Records (#797) 2026-01-16 10:20:21 -08: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
      artifact-metadata: 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. The artifact-metadata permission is required to generate artifact metadata storage records. If this permission is not included, the action will continue without creating the record.

  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 create a storage record for the artifact.
    # Requires that push-to-registry is set to true.
    # Requires that the "subject-name" parameter specify the fully-qualified
    # image name. Defaults to true.
    create-storage-record:

    # 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

Artifact Metadata Storage Records

If the push-to-registry option is set to true, the Action will also emit an Artifact Metadata Storage Record. Storage records enrich artifact metadata by capturing storage related details, such as which registry an image is hosted on and whether it's marked as active.

If you do not want to emit a storage record, set create-storage-record to false.

Note

: Storage records can only be created for artifacts built from organization-owned repositories.

Artifacts associated with a storage record can be viewed by navigating to the Linked Artifacts page in your organization: https://github.com/orgs/YOUR_ORG/artifacts (replace YOUR_ORG with your organization name).

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 }}