Files
attest/README.md

403 lines
14 KiB
Markdown
Raw Permalink Normal View History

# `actions/attest`
2024-02-20 11:22:22 -08:00
Generate signed attestations for workflow artifacts. Internally powered by the
[@actions/attest][1] package.
Attestations bind some subject (a named artifact along with its digest) to a
predicate (some assertion about that subject) using the [in-toto][2] format.
[Predicates][3] consist of a type URI and a JSON object containing
type-dependent parameters.
A verifiable signature is generated for the attestation using a short-lived
[Sigstore][4]-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.
When an attestation is created, the attestation is stored on the local
filesystem used by the runner. For each attestation created, the filesystem path
will be appended to the file `${RUNNER_TEMP}/created_attestation_paths.txt`.
This can be used to gather all attestations created by all jobs during a the
workflow.
2024-04-30 10:16:14 -04:00
Attestations can be verified using the [`attestation` command in the GitHub
CLI][5].
2024-02-20 11:22:22 -08:00
See [Using artifact attestations to establish provenance for builds][9] for more
information on artifact attestations.
<!-- prettier-ignore-start -->
> [!NOTE]
> Artifact attestations are available in public repositories for all
> current GitHub plans.
>
> To use artifact attestations in private or internal repositories, you must
> be on a GitHub Enterprise Cloud plan.
>
> Artifact attestations are NOT supported on GitHub Enterprise Server.
<!-- prettier-ignore-end -->
## Attestation Modes
This action supports three attestation modes, automatically detected based on
the inputs you provide:
<!-- markdownlint-disable MD013 -->
| Mode | When Used | Description |
| -------------- | ------------------------------------------------------ | ----------------------------------------------- |
| **Provenance** | No `sbom-path` or predicate inputs | Auto-generates [SLSA build provenance][10] |
| **SBOM** | `sbom-path` is provided | Creates attestation from SPDX or CycloneDX SBOM |
| **Custom** | `predicate-type`/`predicate`/`predicate-path` provided | User-supplied predicate |
<!-- markdownlint-enable MD013 -->
2024-02-28 09:35:04 -08:00
## Usage
2024-02-20 11:22:22 -08:00
2024-02-28 09:35:04 -08:00
Within the GitHub Actions workflow which builds some artifact you would like to
attest:
2024-02-20 11:22:22 -08:00
2024-02-28 09:35:04 -08:00
1. Ensure that the following permissions are set:
2024-02-20 11:22:22 -08:00
2024-02-28 09:35:04 -08:00
```yaml
permissions:
id-token: write
attestations: write
Create Artifact Metadata Storage Record on registry push (#313) * first pass at creating storage record Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record param in action config Signed-off-by: Meredith Lancaster <malancas@github.com> * use latest actions/attest version Signed-off-by: Meredith Lancaster <malancas@github.com> * update storage record params Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record id in result Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * add documentation on storage records Signed-off-by: Meredith Lancaster <malancas@github.com> * log storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record output Signed-off-by: Meredith Lancaster <malancas@github.com> * add new param Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record id output Signed-off-by: Meredith Lancaster <malancas@github.com> * fix linter errors Signed-off-by: Meredith Lancaster <malancas@github.com> * return all storage record ids Signed-off-by: Meredith Lancaster <malancas@github.com> * bump minor version Signed-off-by: Meredith Lancaster <malancas@github.com> * use expect string match function Signed-off-by: Meredith Lancaster <malancas@github.com> * add try catch block for storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * fix table column spacing Signed-off-by: Meredith Lancaster <malancas@github.com> * check for protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * check for artifact url protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * only fill registry_url for now Signed-off-by: Meredith Lancaster <malancas@github.com> * cleanup protocol handling Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * handle subject name correctly Signed-off-by: Meredith Lancaster <malancas@github.com> * move test Signed-off-by: Meredith Lancaster <malancas@github.com> * add back assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * add back output assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use url for subject name parsing Signed-off-by: Meredith Lancaster <malancas@github.com> * add missing test setpu Signed-off-by: Meredith Lancaster <malancas@github.com> * fix storage record fail test Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> --------- Signed-off-by: Meredith Lancaster <malancas@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 11:30:45 -08:00
artifact-metadata: write
2024-02-28 09:35:04 -08:00
```
2024-02-20 11:22:22 -08:00
The `id-token` permission gives the action the ability to mint the OIDC token
necessary to request a Sigstore signing certificate. The `attestations`
Create Artifact Metadata Storage Record on registry push (#313) * first pass at creating storage record Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record param in action config Signed-off-by: Meredith Lancaster <malancas@github.com> * use latest actions/attest version Signed-off-by: Meredith Lancaster <malancas@github.com> * update storage record params Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record id in result Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * add documentation on storage records Signed-off-by: Meredith Lancaster <malancas@github.com> * log storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record output Signed-off-by: Meredith Lancaster <malancas@github.com> * add new param Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record id output Signed-off-by: Meredith Lancaster <malancas@github.com> * fix linter errors Signed-off-by: Meredith Lancaster <malancas@github.com> * return all storage record ids Signed-off-by: Meredith Lancaster <malancas@github.com> * bump minor version Signed-off-by: Meredith Lancaster <malancas@github.com> * use expect string match function Signed-off-by: Meredith Lancaster <malancas@github.com> * add try catch block for storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * fix table column spacing Signed-off-by: Meredith Lancaster <malancas@github.com> * check for protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * check for artifact url protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * only fill registry_url for now Signed-off-by: Meredith Lancaster <malancas@github.com> * cleanup protocol handling Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * handle subject name correctly Signed-off-by: Meredith Lancaster <malancas@github.com> * move test Signed-off-by: Meredith Lancaster <malancas@github.com> * add back assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * add back output assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use url for subject name parsing Signed-off-by: Meredith Lancaster <malancas@github.com> * add missing test setpu Signed-off-by: Meredith Lancaster <malancas@github.com> * fix storage record fail test Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> --------- Signed-off-by: Meredith Lancaster <malancas@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 11:30:45 -08:00
permission is necessary to persist the attestation. The `artifact-metadata`
permission is necessary to create the artifact storage record.
2024-02-20 11:22:22 -08:00
1. Add the following to your workflow after your artifact has been built:
2024-02-20 11:22:22 -08:00
2024-02-28 09:35:04 -08:00
```yaml
- uses: actions/attest@v4
2024-02-28 09:35:04 -08:00
with:
subject-path: '<PATH TO ARTIFACT>'
2024-02-28 09:35:04 -08:00
```
2024-02-20 11:22:22 -08:00
By default, this generates a [SLSA build provenance][10] attestation. For
SBOM or custom attestations, see the [Attestation Modes](#attestation-modes)
section.
2024-02-20 11:22:22 -08:00
2024-02-28 09:35:04 -08:00
### Inputs
2024-02-20 11:22:22 -08:00
See [action.yml](action.yml)
2024-02-20 11:22:22 -08:00
```yaml
- uses: actions/attest@v4
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:
# Path to the JSON-formatted SBOM file (SPDX or CycloneDX) to attest.
# File size cannot exceed 16MB. When provided, creates an SBOM attestation.
# Cannot be used together with "predicate-type", "predicate", or
# "predicate-path".
sbom-path:
# URI identifying the type of the predicate. Required when using "predicate"
# or "predicate-path" for custom attestations.
predicate-type:
# String containing the value for the attestation predicate. String length
# cannot exceed 16MB. Must supply exactly one of "predicate-path" or
# "predicate" when creating custom attestations.
predicate:
# Path to the file which contains the content for the attestation predicate.
# File size cannot exceed 16MB. Must supply exactly one of "predicate-path"
# or "predicate" when creating custom attestations.
predicate-path:
# 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:
Create Artifact Metadata Storage Record on registry push (#313) * first pass at creating storage record Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record param in action config Signed-off-by: Meredith Lancaster <malancas@github.com> * use latest actions/attest version Signed-off-by: Meredith Lancaster <malancas@github.com> * update storage record params Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record id in result Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * add documentation on storage records Signed-off-by: Meredith Lancaster <malancas@github.com> * log storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record output Signed-off-by: Meredith Lancaster <malancas@github.com> * add new param Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record id output Signed-off-by: Meredith Lancaster <malancas@github.com> * fix linter errors Signed-off-by: Meredith Lancaster <malancas@github.com> * return all storage record ids Signed-off-by: Meredith Lancaster <malancas@github.com> * bump minor version Signed-off-by: Meredith Lancaster <malancas@github.com> * use expect string match function Signed-off-by: Meredith Lancaster <malancas@github.com> * add try catch block for storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * fix table column spacing Signed-off-by: Meredith Lancaster <malancas@github.com> * check for protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * check for artifact url protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * only fill registry_url for now Signed-off-by: Meredith Lancaster <malancas@github.com> * cleanup protocol handling Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * handle subject name correctly Signed-off-by: Meredith Lancaster <malancas@github.com> * move test Signed-off-by: Meredith Lancaster <malancas@github.com> * add back assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * add back output assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use url for subject name parsing Signed-off-by: Meredith Lancaster <malancas@github.com> * add missing test setpu Signed-off-by: Meredith Lancaster <malancas@github.com> * fix storage record fail test Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> --------- Signed-off-by: Meredith Lancaster <malancas@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 11:30:45 -08:00
# 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:
```
2024-02-20 11:22:22 -08:00
### Outputs
2024-02-20 11:22:22 -08:00
<!-- markdownlint-disable MD013 -->
2024-02-20 11:22:22 -08:00
Create Artifact Metadata Storage Record on registry push (#313) * first pass at creating storage record Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record param in action config Signed-off-by: Meredith Lancaster <malancas@github.com> * use latest actions/attest version Signed-off-by: Meredith Lancaster <malancas@github.com> * update storage record params Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record id in result Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * add documentation on storage records Signed-off-by: Meredith Lancaster <malancas@github.com> * log storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record output Signed-off-by: Meredith Lancaster <malancas@github.com> * add new param Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record id output Signed-off-by: Meredith Lancaster <malancas@github.com> * fix linter errors Signed-off-by: Meredith Lancaster <malancas@github.com> * return all storage record ids Signed-off-by: Meredith Lancaster <malancas@github.com> * bump minor version Signed-off-by: Meredith Lancaster <malancas@github.com> * use expect string match function Signed-off-by: Meredith Lancaster <malancas@github.com> * add try catch block for storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * fix table column spacing Signed-off-by: Meredith Lancaster <malancas@github.com> * check for protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * check for artifact url protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * only fill registry_url for now Signed-off-by: Meredith Lancaster <malancas@github.com> * cleanup protocol handling Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * handle subject name correctly Signed-off-by: Meredith Lancaster <malancas@github.com> * move test Signed-off-by: Meredith Lancaster <malancas@github.com> * add back assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * add back output assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use url for subject name parsing Signed-off-by: Meredith Lancaster <malancas@github.com> * add missing test setpu Signed-off-by: Meredith Lancaster <malancas@github.com> * fix storage record fail test Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> --------- Signed-off-by: Meredith Lancaster <malancas@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 11:30:45 -08:00
| Name | Description | Example |
| -------------------- | -------------------------------------------------------------- | ------------------------------------------------ |
Create Artifact Metadata Storage Record on registry push (#313) * first pass at creating storage record Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record param in action config Signed-off-by: Meredith Lancaster <malancas@github.com> * use latest actions/attest version Signed-off-by: Meredith Lancaster <malancas@github.com> * update storage record params Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record id in result Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * add documentation on storage records Signed-off-by: Meredith Lancaster <malancas@github.com> * log storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record output Signed-off-by: Meredith Lancaster <malancas@github.com> * add new param Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record id output Signed-off-by: Meredith Lancaster <malancas@github.com> * fix linter errors Signed-off-by: Meredith Lancaster <malancas@github.com> * return all storage record ids Signed-off-by: Meredith Lancaster <malancas@github.com> * bump minor version Signed-off-by: Meredith Lancaster <malancas@github.com> * use expect string match function Signed-off-by: Meredith Lancaster <malancas@github.com> * add try catch block for storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * fix table column spacing Signed-off-by: Meredith Lancaster <malancas@github.com> * check for protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * check for artifact url protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * only fill registry_url for now Signed-off-by: Meredith Lancaster <malancas@github.com> * cleanup protocol handling Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * handle subject name correctly Signed-off-by: Meredith Lancaster <malancas@github.com> * move test Signed-off-by: Meredith Lancaster <malancas@github.com> * add back assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * add back output assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use url for subject name parsing Signed-off-by: Meredith Lancaster <malancas@github.com> * add missing test setpu Signed-off-by: Meredith Lancaster <malancas@github.com> * fix storage record fail test Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> --------- Signed-off-by: Meredith Lancaster <malancas@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 11:30:45 -08:00
| `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` |
| `storage-record-ids` | GitHub IDs for the storage records | `987654` |
2024-02-20 11:22:22 -08:00
<!-- markdownlint-enable MD013 -->
2024-02-20 11:22:22 -08:00
Attestations are saved in the JSON-serialized [Sigstore bundle][6] format.
2024-02-20 11:22:22 -08:00
If multiple subjects are being attested at the same time, a single attestation
will be created with references to each of the supplied subjects.
2024-02-20 11:22:22 -08:00
## Attestation Limits
### Subject Limits
No more than 1024 subjects can be attested at the same time.
### Predicate Limits
Whether supplied via the `predicate` or `predicatePath` input, the predicate
string cannot exceed 16MB.
## Examples
2024-02-20 11:22:22 -08:00
### Provenance Attestation (Default)
2024-02-20 11:22:22 -08:00
The simplest use case - just specify the artifact path and a SLSA build
provenance attestation is automatically generated:
2024-02-20 11:22:22 -08:00
2024-02-28 09:35:04 -08:00
```yaml
name: build-attest-provenance
2024-02-28 09:35:04 -08:00
on:
workflow_dispatch:
jobs:
build:
permissions:
id-token: write
contents: read
attestations: write
2024-02-28 09:35:04 -08:00
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build artifact
run: make my-app
2024-02-28 09:35:04 -08:00
- name: Attest
uses: actions/attest@v4
2024-02-28 09:35:04 -08:00
with:
subject-path: '${{ github.workspace }}/my-app'
```
### SBOM Attestation
To create an SBOM attestation, provide the path to an SPDX or CycloneDX JSON
file:
```yaml
- name: Generate SBOM
run: syft . -o spdx-json > sbom.spdx.json
- uses: actions/attest@v4
with:
subject-path: '${{ github.workspace }}/my-app'
sbom-path: '${{ github.workspace }}/sbom.spdx.json'
```
### Custom Attestation
For custom attestations, provide your own predicate type and content:
```yaml
- uses: actions/attest@v4
with:
subject-path: '${{ github.workspace }}/my-app'
predicate-type: 'https://example.com/predicate/v1'
predicate: '{}'
2024-02-28 09:35:04 -08:00
```
2024-02-20 11:22:22 -08:00
### Identify Multiple Subjects
2024-02-20 11:22:22 -08:00
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.
2024-02-20 11:22:22 -08:00
```yaml
- uses: actions/attest@v4
with:
subject-path: 'dist/**/my-bin-*'
predicate-type: 'https://example.com/predicate/v1'
predicate: '{}'
2024-02-20 11:22:22 -08:00
```
2024-02-28 09:35:04 -08:00
For supported wildcards along with behavior and documentation, see
[@actions/glob][8] which is used internally to search for files.
2024-02-20 11:22:22 -08:00
Alternatively, you can explicitly list multiple subjects with either a comma or
newline delimited list:
```yaml
- uses: actions/attest@v4
with:
subject-path: 'dist/foo, dist/bar'
```
```yaml
- uses: actions/attest@v4
with:
subject-path: |
dist/foo
dist/bar
```
### Identify Subjects with Checksums File
If you are using tools like
[goreleaser](https://goreleaser.com/customization/checksum/) or
[jreleaser](https://jreleaser.org/guide/latest/reference/checksum.html) 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.
```yaml
- name: Calculate artifact digests
run: |
shasum -a 256 foo_0.0.1_* > subject.checksums.txt
- uses: actions/attest@v4
with:
subject-checksums: subject.checksums.txt
```
<!-- markdownlint-disable MD038 -->
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.
<!-- markdownlint-enable MD038 -->
```text
b569bf992b287f55d78bf8ee476497e9b7e9d2bf1c338860bfb905016218c740 foo_0.0.1_darwin_amd64
a54fc515e616cac7fcf11a49d5c5ec9ec315948a5935c1e11dd610b834b14dde foo_0.0.1_darwin_arm64
```
2024-02-28 09:35:04 -08:00
### Container Image
When working with container images you can invoke the action with the
`subject-name` and `subject-digest` inputs.
2024-02-20 11:22:22 -08:00
2024-02-28 09:35:04 -08:00
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.
2024-02-20 11:22:22 -08:00
#### Artifact Metadata Storage Records
When generating a build provenance attestation, if the `push-to-registry` option
is set to true, the Action will also emit an
[Artifact Metadata Storage Record](https://docs.github.com/en/rest/orgs/artifact-metadata?apiVersion=2022-11-28#create-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](https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/about-organizations)
> 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).
Create Artifact Metadata Storage Record on registry push (#313) * first pass at creating storage record Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record param in action config Signed-off-by: Meredith Lancaster <malancas@github.com> * use latest actions/attest version Signed-off-by: Meredith Lancaster <malancas@github.com> * update storage record params Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record id in result Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * add documentation on storage records Signed-off-by: Meredith Lancaster <malancas@github.com> * log storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record output Signed-off-by: Meredith Lancaster <malancas@github.com> * add new param Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record id output Signed-off-by: Meredith Lancaster <malancas@github.com> * fix linter errors Signed-off-by: Meredith Lancaster <malancas@github.com> * return all storage record ids Signed-off-by: Meredith Lancaster <malancas@github.com> * bump minor version Signed-off-by: Meredith Lancaster <malancas@github.com> * use expect string match function Signed-off-by: Meredith Lancaster <malancas@github.com> * add try catch block for storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * fix table column spacing Signed-off-by: Meredith Lancaster <malancas@github.com> * check for protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * check for artifact url protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * only fill registry_url for now Signed-off-by: Meredith Lancaster <malancas@github.com> * cleanup protocol handling Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * handle subject name correctly Signed-off-by: Meredith Lancaster <malancas@github.com> * move test Signed-off-by: Meredith Lancaster <malancas@github.com> * add back assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * add back output assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use url for subject name parsing Signed-off-by: Meredith Lancaster <malancas@github.com> * add missing test setpu Signed-off-by: Meredith Lancaster <malancas@github.com> * fix storage record fail test Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> --------- Signed-off-by: Meredith Lancaster <malancas@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 11:30:45 -08:00
> **NOTE**: When pushing to Docker Hub, please use "docker.io" as the registry
> portion of the image name.
2024-02-20 11:22:22 -08:00
```yaml
name: build-attested-image
2024-02-28 09:35:04 -08:00
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
packages: write
contents: read
attestations: write
Create Artifact Metadata Storage Record on registry push (#313) * first pass at creating storage record Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record param in action config Signed-off-by: Meredith Lancaster <malancas@github.com> * use latest actions/attest version Signed-off-by: Meredith Lancaster <malancas@github.com> * update storage record params Signed-off-by: Meredith Lancaster <malancas@github.com> * include storage record id in result Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * add documentation on storage records Signed-off-by: Meredith Lancaster <malancas@github.com> * log storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record output Signed-off-by: Meredith Lancaster <malancas@github.com> * add new param Signed-off-by: Meredith Lancaster <malancas@github.com> * add storage record id output Signed-off-by: Meredith Lancaster <malancas@github.com> * fix linter errors Signed-off-by: Meredith Lancaster <malancas@github.com> * return all storage record ids Signed-off-by: Meredith Lancaster <malancas@github.com> * bump minor version Signed-off-by: Meredith Lancaster <malancas@github.com> * use expect string match function Signed-off-by: Meredith Lancaster <malancas@github.com> * add try catch block for storage record creation Signed-off-by: Meredith Lancaster <malancas@github.com> * fix table column spacing Signed-off-by: Meredith Lancaster <malancas@github.com> * check for protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * check for artifact url protocol Signed-off-by: Meredith Lancaster <malancas@github.com> * only fill registry_url for now Signed-off-by: Meredith Lancaster <malancas@github.com> * cleanup protocol handling Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> * handle subject name correctly Signed-off-by: Meredith Lancaster <malancas@github.com> * move test Signed-off-by: Meredith Lancaster <malancas@github.com> * add back assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * add back output assert statements Signed-off-by: Meredith Lancaster <malancas@github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * use url for subject name parsing Signed-off-by: Meredith Lancaster <malancas@github.com> * add missing test setpu Signed-off-by: Meredith Lancaster <malancas@github.com> * fix storage record fail test Signed-off-by: Meredith Lancaster <malancas@github.com> * regenerate dist Signed-off-by: Meredith Lancaster <malancas@github.com> --------- Signed-off-by: Meredith Lancaster <malancas@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-18 11:30:45 -08:00
artifact-metadata: write
2024-02-28 09:35:04 -08:00
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@v4
2024-02-28 09:35:04 -08:00
id: attest
with:
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
2024-02-20 11:22:22 -08:00
```
[1]: https://github.com/actions/toolkit/tree/main/packages/attest
[2]: https://github.com/in-toto/attestation/tree/main/spec/v1
[3]:
https://github.com/in-toto/attestation/tree/main/spec/predicates#in-toto-attestation-predicates
[4]: https://www.sigstore.dev/
2024-04-30 10:16:14 -04:00
[5]: https://cli.github.com/manual/gh_attestation_verify
[6]:
https://github.com/sigstore/protobuf-specs/blob/main/protos/sigstore_bundle.proto
[8]: https://github.com/actions/toolkit/tree/main/packages/glob#patterns
[9]:
https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds
[10]: https://slsa.dev/spec/v1.0/provenance