this repo has no description

Setup Build SBoM & Build Provenance

authored by

Jonatan Männchen and committed by
Louis Pilfold
8a42e12a a2b368a1

+120 -1
+31 -1
.github/actions/build-container/action.yml
··· 15 15 uses: robinraju/release-downloader@v1 16 16 with: 17 17 releaseId: "${{ inputs.release-id }}" 18 - fileName: "gleam-${{ inputs.version }}-{x86_64-unknown-linux-musl,aarch64-unknown-linux-musl}.tar.gz" 18 + fileName: "gleam-${{ inputs.version }}-{x86_64-unknown-linux-musl,aarch64-unknown-linux-musl}.*" 19 19 20 20 - name: "Unpack release files into correct location" 21 21 shell: bash ··· 32 32 33 33 # Move files into place 34 34 mv gleam "gleam-$SHORT" 35 + 36 + # The SBoM is added to the images so that the Docker Scout Scanner is 37 + # able to find the info about the gleam binary since it was not 38 + # installed by the operating system package manager. 39 + mv "gleam-$VERSION-$LONG.tar.gz.sbom.spdx.json" "gleam-$SHORT.sbom.spdx.json" 35 40 36 41 # Delete Unused Files 37 42 rm -rf "gleam-$VERSION-$LONG*" ··· 74 79 platforms: linux/amd64,linux/arm64 75 80 file: containers/${{ matrix.base-image }}.dockerfile 76 81 push: true 82 + 83 + # Enabling `provenance` will cause the action to create SLSA build 84 + # provenance and push it alongside the tagged image. In practical terms, 85 + # we're adding info to the tag that attests to where, when, and how the 86 + # asset and image was built. 87 + # 88 + # For more info on Docker Attestations, see: 89 + # https://docs.docker.com/build/ci/github-actions/attestations/ 90 + provenance: true 91 + 92 + # Enabling `sbom` will trigger an SBoM Scan using Docker Scout: 93 + # https://docs.docker.com/scout/how-tos/view-create-sboms/ 94 + # The scan will detect any operating system packages as well as the Gleam 95 + # Build SBoM added into the Docker Container. 96 + # 97 + # Why is this helpful? 98 + # * If you build services on top of these container images, you can track 99 + # all dependencies that ship with Gleam, plus the rest of your stack in 100 + # the image. 101 + # * This makes it easier to do image-level vulnerability scans and 102 + # compliance checks. 103 + # 104 + # For more info on Docker SBoMs, see: 105 + # https://docs.docker.com/build/metadata/attestations/sbom/ 106 + sbom: true 77 107 tags: ${{ steps.versions.outputs.container-tag }} 78 108 labels: | 79 109 org.opencontainers.image.title=gleam
+71
.github/actions/build-release/action.yml
··· 28 28 ${{ steps.build.outputs.archive }} 29 29 ${{ steps.build.outputs.archive }}.sha256 30 30 ${{ steps.build.outputs.archive }}.sha512 31 + ${{ steps.build.outputs.archive }}.sigstore 32 + ${{ steps.build.outputs.archive }}.sbom.spdx.json 33 + ${{ steps.build.outputs.archive }}.sbom.cyclonedx.json 31 34 32 35 runs: 33 36 using: "composite" ··· 38 41 toolchain: ${{ inputs.toolchain }} 39 42 target: ${{ inputs.target }} 40 43 cache-key: v1-${{ inputs.target }} 44 + 45 + - name: Install Cargo SBoM 46 + shell: bash 47 + # The `cargo-sbom` version is specified in the next line. Change it to 48 + # keep it up-to-date. 49 + run: cargo install cargo-sbom@~0.9.1 41 50 42 51 - name: Build WASM release binary 43 52 if: ${{ inputs.target != 'wasm32-unknown-unknown' }} ··· 124 133 TARGET: "${{ inputs.target }}" 125 134 ARCHIVE: "${{ steps.build.outputs.archive }}" 126 135 136 + # By using `cargo-sbom``, we create two formats of Build SBoMs 137 + # (SPDX and CycloneDX) for the gleam build. 138 + # We store those files alongside the build artifacts on the GitHub Release 139 + # page and also use them to create Container SBoMs for Docker images. 140 + # 141 + # Why is this helpful? 142 + # * It gives us and our users complete visibility into which dependencies 143 + # and which versions are present in the build / container image. 144 + # * The SBoM can be fed into vulnerability scanners so that anyone can check 145 + # if any dependencies have known security issues. 146 + - name: Generate Build SBoM 147 + shell: bash 148 + run: | 149 + cargo-sbom \ 150 + --output-format spdx_json_2_3 \ 151 + > "$ARCHIVE.sbom.spdx.json" 152 + 153 + cargo-sbom \ 154 + --output-format cyclone_dx_json_1_4 \ 155 + > "$ARCHIVE.sbom.cyclonedx.json" 156 + env: 157 + ARCHIVE: "${{ steps.build.outputs.archive }}" 158 + 127 159 - name: Hash Build Archive 128 160 shell: bash 129 161 run: | ··· 132 164 env: 133 165 ARCHIVE: "${{ steps.build.outputs.archive }}" 134 166 167 + # We provide SLSA Provenance for the distribution build. This attests to 168 + # where, when, and how the asset or image was built. 169 + # 170 + # Why is this helpful? 171 + # * It provides a record of the exact Git commit (git sha) and GitHub 172 + # Actions workflow used to produce a release. 173 + # * Users or automated systems can verify that the artifact you’re 174 + # downloading was indeed built from the official Gleam repo, on a 175 + # particular date, using the correct pipeline and not tampered with later. 176 + # * The attestation is published to a transparency log for extra 177 + # verification: https://github.com/gleam-lang/gleam/attestations/ 178 + # 179 + # For more information, see: 180 + # * https://github.com/actions/attest 181 + # * https://github.com/actions/attest-sbom 182 + - name: Attest Distribution Assets with SBoM 183 + id: attest-sbom 184 + uses: actions/attest-sbom@v2 185 + with: 186 + subject-path: | 187 + ${{ steps.build.outputs.archive }} 188 + ${{ steps.build.outputs.archive }}.sbom.spdx.json 189 + ${{ steps.build.outputs.archive }}.sbom.cyclonedx.json 190 + sbom-path: "${{ steps.build.outputs.archive }}.sbom.spdx.json" 191 + 192 + # The provenanve information is stored alongside the built artifact with 193 + # the `.sigstore` file extension. 194 + - name: "Copy SBoM provenance" 195 + id: sbom-provenance 196 + shell: bash 197 + run: | 198 + cp "$ATTESTATION" "$ARCHIVE.sigstore" 199 + env: 200 + ARCHIVE: "${{ steps.build.outputs.archive }}" 201 + ATTESTATION: "${{ steps.attest-sbom.outputs.bundle-path }}" 202 + 135 203 - name: Upload artifact 136 204 uses: actions/upload-artifact@v4 137 205 with: ··· 140 208 ${{ steps.build.outputs.archive }} 141 209 ${{ steps.build.outputs.archive }}.sha256 142 210 ${{ steps.build.outputs.archive }}.sha512 211 + ${{ steps.build.outputs.archive }}.sigstore 212 + ${{ steps.build.outputs.archive }}.sbom.spdx.json 213 + ${{ steps.build.outputs.archive }}.sbom.cyclonedx.json 143 214 overwrite: true
+2
.github/workflows/release-containers.yaml
··· 6 6 7 7 permissions: 8 8 packages: write 9 + id-token: write 10 + attestations: write 9 11 10 12 jobs: 11 13 publish-container-images:
+4
.github/workflows/release-nightly.yaml
··· 12 12 permissions: 13 13 contents: write 14 14 packages: write 15 + id-token: write 16 + attestations: write 15 17 16 18 jobs: 17 19 # Check if the actions already ran in the last 24 hours ··· 48 50 *.tar.gz 49 51 *.sha256 50 52 *.sha512 53 + *.sigstore 54 + *.sbom.*.json 51 55 52 56 build-release: 53 57 name: build-release
+2
.github/workflows/release.yaml
··· 10 10 11 11 permissions: 12 12 contents: write 13 + id-token: write 14 + attestations: write 13 15 14 16 jobs: 15 17 build-release:
+1
containers/elixir-alpine.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/elixir-slim.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/elixir.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/erlang-alpine.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/erlang-slim.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/erlang.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/node-alpine.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/node-slim.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/node.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]
+1
containers/scratch.dockerfile
··· 2 2 3 3 ARG TARGETARCH 4 4 COPY gleam-${TARGETARCH} /bin/gleam 5 + COPY gleam-${TARGETARCH}.sbom.spdx.json /opt/sbom/ 5 6 6 7 CMD ["gleam"]