diff --git a/.github/workflows/build-embeddings.yml b/.github/workflows/build-embeddings.yml index 0947c2a..b31b88e 100644 --- a/.github/workflows/build-embeddings.yml +++ b/.github/workflows/build-embeddings.yml @@ -122,8 +122,12 @@ jobs: permissions: contents: read packages: write + id-token: write + attestations: write + artifact-metadata: write outputs: embeddings-image-digest: ${{ steps.publish.outputs.digest }} + attestation-url: ${{ steps.attest.outputs.attestation-url }} steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 @@ -168,10 +172,9 @@ jobs: GH_TOKEN: ${{ github.token }} run: bash .github/scripts/verify-ghcr-package-private.sh "${VECTORSTORE_PACKAGE_NAME}" - - name: Record published embeddings digest + - name: Validate published embeddings digest env: DIGEST: ${{ steps.publish.outputs.digest }} - TAG: ${{ env.VECTORSTORE_IMAGE }}:git-${{ github.sha }}-run-${{ github.run_id }}-${{ github.run_attempt }} run: | set -euo pipefail if [[ ! "${DIGEST}" =~ ^sha256:[0-9a-f]{64}$ ]]; then @@ -179,10 +182,74 @@ jobs: exit 1 fi + - name: Generate embeddings provenance attestation + id: attest + uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1 + with: + subject-name: ${{ env.VECTORSTORE_IMAGE }} + subject-digest: ${{ steps.publish.outputs.digest }} + push-to-registry: true + + - name: Record published embeddings digest + env: + DIGEST: ${{ steps.publish.outputs.digest }} + TAG: ${{ env.VECTORSTORE_IMAGE }}:git-${{ github.sha }}-run-${{ github.run_id }}-${{ github.run_attempt }} + SOURCE_COMMIT: ${{ github.sha }} + ATTESTATION_URL: ${{ steps.attest.outputs.attestation-url }} + run: | + set -euo pipefail + if [[ -z "${ATTESTATION_URL}" ]]; then + echo "::error::Attestation action did not return an attestation URL." + exit 1 + fi + { - echo "### Immutable embeddings image" + echo "### Attested embeddings image" echo "" + echo "- Image: \`${VECTORSTORE_IMAGE}@${DIGEST}\`" echo "- Tag: \`${TAG}\`" - echo "- Digest: \`${DIGEST}\`" - echo "- MCP build input: \`${VECTORSTORE_IMAGE}@${DIGEST}\`" + echo "- Source commit: [\`${SOURCE_COMMIT}\`](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/commit/${SOURCE_COMMIT})" + echo "- Attestation: [view provenance](${ATTESTATION_URL})" } >> "${GITHUB_STEP_SUMMARY}" + + verify-vectorstore-provenance: + needs: generate-and-publish-vectorstore + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read + attestations: read + steps: + - name: Log in to GHCR + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Verify provenance through GitHub + env: + GH_TOKEN: ${{ github.token }} + DIGEST: ${{ needs.generate-and-publish-vectorstore.outputs.embeddings-image-digest }} + run: | + set -euo pipefail + gh attestation verify \ + "oci://${VECTORSTORE_IMAGE}@${DIGEST}" \ + --repo "${GITHUB_REPOSITORY}" \ + --signer-workflow "${GITHUB_REPOSITORY}/.github/workflows/build-embeddings.yml" \ + --source-ref "${GITHUB_REF}" \ + --source-digest "${GITHUB_SHA}" + + - name: Verify registry-attached provenance + env: + GH_TOKEN: ${{ github.token }} + DIGEST: ${{ needs.generate-and-publish-vectorstore.outputs.embeddings-image-digest }} + run: | + set -euo pipefail + gh attestation verify \ + "oci://${VECTORSTORE_IMAGE}@${DIGEST}" \ + --repo "${GITHUB_REPOSITORY}" \ + --signer-workflow "${GITHUB_REPOSITORY}/.github/workflows/build-embeddings.yml" \ + --source-ref "${GITHUB_REF}" \ + --source-digest "${GITHUB_SHA}" \ + --bundle-from-oci