Giter VIP home page Giter VIP logo

attest-sbom's Introduction

actions/attest-sbom

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

Attestations bind some subject (a named artifact along with its digest) to a a Software Bill of Materials (SBOM) using the in-toto format. The action accepts SBOMs which have been generated by external tools. Provided SBOMs must be in either the SPDX or CycloneDX JSON-serialized 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.

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 and your SBOM has been generated:

    - uses: actions/attest-sbom@v1
      with:
        subject-path: '<PATH TO ARTIFACT>'
        sbom-path: '<PATH TO SBOM>'

    The subject-path parameter should identify the artifact for which you want to generate an SBOM attestation. The sbom-path parameter should identify the SBOM document to be associated with the subject.

Inputs

See action.yml

- uses: actions/attest-sbom@v1
  with:
    # Path to the artifact serving as the subject of the attestation. Must
    # specify exactly one of "subject-path" or "subject-digest". May contain a
    # glob pattern or list of paths (total subject count cannot exceed 2500).
    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" or "subject-digest".
    subject-digest:

    # Subject name as it should appear in the attestation. Required unless
    # "subject-path" is specified, in which case it will be inferred from the
    # path.
    subject-name:

    # Path to the JSON-formatted SBOM file to attest. File size cannot exceed
    # 16MB.
    sbom-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:

    # 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
bundle-path Absolute path to the file containing the generated attestation /tmp/attestaion.jsonl

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

If multiple subjects are being attested at the same time, each attestation will be written to the output file on a separate line (using the JSON Lines format).

Attestation Limits

Subject Limits

No more than 2500 subjects can be attested at the same time. Subjects will be processed in batches 50. After the initial group of 50, each subsequent batch will incur an exponentially increasing amount of delay (capped at 1 minute of delay per batch) to avoid overwhelming the attestation API.

SBOM Limits

The SBOM supplied via the sbom-path input cannot exceed 16MB.

Examples

Identify Subject and SBOM by Path

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

name: build-attest

on:
  workflow_dispatch:

jobs:
  build:
    permissions:
      id-token: write
      contents: read
      attestations: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Build artifact
        run: make my-app
      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          format: 'spdx-json'
          output-file: 'sbom.spdx.json'
      - name: Attest
        uses: actions/attest-sbom@v1
        with:
          subject-path: '${{ github.workspace }}/my-app'
          sbom-path: 'sbom.spdx.json'

Identify Multiple Subjects

If you are generating multiple artifacts, you can generate an attestation for each by using a wildcard in the subject-path input.

- uses: actions/attest-sbom@v1
  with:
    subject-path: 'dist/**/my-bin-*'
    sbom-path: '${{ github.workspace }}/my-bin.sbom.spdx.json'

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-sbom@v1
  with:
    subject-path: 'dist/foo, dist/bar'
- uses: actions/attest-sbom@v1
  with:
    subject-path: |
      dist/foo
      dist/bar

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.

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/[email protected]
        with:
          context: .
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
          format: 'cyclonedx-json'
          output-file: 'sbom.cyclonedx.json'
      - name: Attest
        uses: actions/attest-sbom@v1
        id: attest
        with:
          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          subject-digest: ${{ steps.push.outputs.digest }}
          sbom-path: 'sbom.cyclonedx.json'
          push-to-registry: true

attest-sbom's People

Contributors

bdehamer avatar dependabot[bot] avatar ejahngithub avatar phillmv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

attest-sbom's Issues

Attestations for multi-platform images

What is the recommended way to attest SBOMs for multi-arch images? The documented way of generating and attesting surely doesn't work:

  • First anchore/sbom-action generates an SBOM for a single platform (most likely amd64)
  • Then actions/attest-sbom attaches that single-platform SBOM to the multi-platform index

Here's an example:

$ crane digest jkreileder/cf-ips-to-hcloud-fw:1.0.11
sha256:bf5a71bdd31fc00feb2a727b1a0f9442e2d93460d0d6f3e11685937714dda3e9
$ crane digest --platform linux/amd64 jkreileder/cf-ips-to-hcloud-fw:1.0.11
sha256:ed9821fe41944f3b90050accd78aa3b52256809b31cb024ffd3eff31b8718ce0
$ crane digest --platform linux/arm64 jkreileder/cf-ips-to-hcloud-fw:1.0.11
sha256:43818671e5ed3569fa86a69f1ba6f4e8b83ebe3b6f2a0909b10a9007566cab0f

This was generated by https://github.com/jkreileder/cf-ips-to-hcloud-fw/blob/48ab6e2f78e92677684ca33cfd39f41971026801/.github/workflows/docker.yaml in https://github.com/jkreileder/cf-ips-to-hcloud-fw/actions/runs/9020189970.

Docker buildx itself generated two SBOMs:

$ docker buildx imagetools inspect jkreileder/cf-ips-to-hcloud-fw@sha256:bf5a71bdd31fc00feb2a727b1a0f9442e2d93460d0d6f3e11685937714dda3e9 --format "{{ json .SBOM }}"
{
  "linux/amd64": {
    "SPDX": {
[...]
    }
  },
  "linux/arm64": {
    "SPDX": {
[...]
    }
  }
}

The SBOM from anchore/sbom-action however is amd64-specific: https://github.com/jkreileder/cf-ips-to-hcloud-fw/actions/runs/9020189970/artifacts/1488347718

=> The generated attestation (https://github.com/jkreileder/cf-ips-to-hcloud-fw/attestations/816931) is amd64-specific and basically useless for arm64.

How should this be handled? Extract the SBOMs from the docker build (as shown above) and pass those to actions/attest-sbom although it doesn't follow the expected format? Wouldn't it be better to just directly attest the already pushed SBOMs?

Note that this might apply to build provenance attestations as well if those ever contain platform specific things. (Docker buildx e.g. does, so it attaches multiple provenances too. See docker buildx imagetools inspect jkreileder/cf-ips-to-hcloud-fw@sha256:bf5a71bdd31fc00feb2a727b1a0f9442e2d93460d0d6f3e11685937714dda3e9 --format "{{ json .Provenance }}" for example.)

Error uploading artifact to container registry

After successfully generating an SBOM and then attesting it, this action fails to upload the artifact with a generic error: Error uploading artifact to container registry

Here's the action log (IDs redacted):

Run actions/attest-sbom@v[1](https://github.com/x/x/actions/runs/X/job/X#step:19:1)
  with:
    subject-name: ghcr.io/x/x
    subject-digest: sha[2](https://github.com/x/x/actions/runs/x/job/x#step:19:2)56:x[3](https://github.com/x/x/actions/runs/x/job/x#step:19:3)x
    sbom-path: x.spdx.json
    push-to-registry: true
    github-token: ***
  env:
    ANCHORE_SBOM_ACTION_PRIOR_ARTIFACT: x_latest.spdx.json
Run actions/attest-sbom/predicate@53[4](https://github.com/x/x/actions/runs/x/job/x#step:19:4)x
  with:
    sbom-path: x.spdx.json
  env:
    ANCHORE_SBOM_ACTION_PRIOR_ARTIFACT: x_latest.spdx.json
Run actions/attest@49[5](https://github.com/x/x/actions/runs/x/job/x#step:19:5)x[6](https://github.com/x/x/actions/runs/x/job/x#step:19:6)7d
  with:
    subject-digest: sha256:x[7](https://github.com/x/x/actions/runs/x/job/x#step:19:7)x[8](https://github.com/x/x/actions/runs/x/job/x#step:19:8)x[9](https://github.com/x/x/actions/runs/x/job/x#step:19:9)x
    subject-name: ghcr.io/x/x
    predicate-type: https://spdx.dev/Document/v2.3
    predicate-path: /home/runner/work/_temp/lrJC03/predicate.json
    push-to-registry: true
    github-token: ***
  env:
    ANCHORE_SBOM_ACTION_PRIOR_ARTIFACT: x_latest.spdx.json
  
Attestation created for ghcr.io/x/x@sha256:b[10](https://github.com/x/x/actions/runs/x/job/x#step:19:11)x
Attestation signed using certificate from GitHub Sigstore instance
Attestation uploaded to repository
https://github.com/x/x/attestations/793731
Error: Error uploading artifact to container registry

I can view the attestation from the web UI and the image has been published to the registry. The attestation is not linked, but I can download it from the workflow summary.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.