From 4b80119701a6899559cde5f4538756d68f9a2f1e Mon Sep 17 00:00:00 2001 From: Patrick McEvoy Date: Mon, 3 Aug 2026 18:01:22 +0100 Subject: [PATCH] Allow optional Cargo image provenance Keeps deterministic byte verification, base-image attestation, and Liskov OIDC manifest/image binding mandatory while allowing derived-image provenance publication to be disabled.\n\nRefs BKLG-20260803-0d11. --- .github/workflows/cargo-runtime-image.yml | 6 +++++ README.md | 22 ++++++++++++++----- .../src/cargo-workflow.test.ts | 9 +++++++- package.json | 2 +- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cargo-runtime-image.yml b/.github/workflows/cargo-runtime-image.yml index 3a816ad..d64ca77 100644 --- a/.github/workflows/cargo-runtime-image.yml +++ b/.github/workflows/cargo-runtime-image.yml @@ -50,6 +50,11 @@ on: description: "Exact workflow identity that attested the base rootfs." required: true type: string + attest-runtime-image: + description: "Publish GitHub build provenance for the derived runtime image. Disable for repositories where GitHub artifact attestations are unavailable." + required: false + type: boolean + default: true bootstrap-mode: required: false type: string @@ -230,6 +235,7 @@ jobs: "${RUNNER_TEMP}/cargo-runtime-image-two.tar.xz" - name: Attest deterministic Cargo runtime image + if: ${{ inputs.attest-runtime-image }} uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a with: subject-path: ${{ runner.temp }}/cargo-runtime-image-one.tar.xz diff --git a/README.md b/README.md index be408c4..391bcce 100644 --- a/README.md +++ b/README.md @@ -150,11 +150,19 @@ each build at the declared absolute path, normalizes the rootfs archive, rejects any embedded `liskov-runtime-contact`, and requires both complete images to have the same digest and bytes. -Only after that proof does the workflow attest the generated image, import the -exact authored manifest, and invoke the existing scoped upload/finalization -action. Callers must pin the base image's SHA-256, source commit, repository, -and signer workflow. Release callers should use the maintained promoted rootfs; -a release-candidate rootfs remains suitable only for an explicitly controlled +Only after that proof does the workflow optionally attest the generated image, +import the exact authored manifest, and invoke the existing scoped +upload/finalization action. Generated-image attestation defaults on. Set +`attest-runtime-image: false` when GitHub artifact attestations are unavailable, +including private repositories whose organization plan does not provide them. +This skips only publication of GitHub build provenance for the derived image: +Liskov still verifies the caller's GitHub OIDC identity and binds the exact +Application, manifest digest pair, source commit, workflow, and image digest. +The base image remains digest- and attestation-verified in both modes. + +Callers must pin the base image's SHA-256, source commit, repository, and signer +workflow. Release callers should use the maintained promoted rootfs; a +release-candidate rootfs remains suitable only for an explicitly controlled canary. ```yaml @@ -172,6 +180,7 @@ jobs: base-attestation-repository: proof-computer/liskov-runtime-images base-attestation-source-digest: base-attestation-signer-workflow: proof-computer/liskov-runtime-images/.github/workflows/ci.yml + attest-runtime-image: false # optional; defaults to true ``` ## À-la-carte actions @@ -201,6 +210,9 @@ Compose your own job from these (`uses: proof-computer/liskov-github-actions/act - `v1.2.0` adds backward-compatible caller-prepared artifact bytes, sanitized Diagnostic metadata, existing-CID gateway verification, multi-target artifact-pin attestation, reusable-workflow outputs, and durable build-manifest run artifacts. +- `v1.2.3` allows Cargo callers to skip publishing derived-image GitHub build + provenance while retaining deterministic byte proof, base-image attestation, + and Liskov's exact OIDC/manifest/image binding. - Reusable workflows reference their own JS actions by the literal `@v1` major tag, so a caller pinned to `@v1` executes the matching released action surface. diff --git a/actions/runtime-image-upload/src/cargo-workflow.test.ts b/actions/runtime-image-upload/src/cargo-workflow.test.ts index e07a048..c8c6708 100644 --- a/actions/runtime-image-upload/src/cargo-workflow.test.ts +++ b/actions/runtime-image-upload/src/cargo-workflow.test.ts @@ -5,9 +5,15 @@ import { describe, it } from "node:test"; import { parse } from "yaml"; describe("Cargo runtime-image reusable workflow", () => { - it("pins inputs, proves two builds, attests, then finalizes", async () => { + it("pins inputs, proves two builds, optionally attests, then finalizes", async () => { const path = new URL("../../../.github/workflows/cargo-runtime-image.yml", import.meta.url); const workflow = parse(await readFile(path, "utf8")) as Record; + const trigger = object(workflow.on, "on"); + const workflowCall = object(trigger.workflow_call, "workflow_call"); + const inputs = object(workflowCall.inputs, "inputs"); + const attestInput = object(inputs["attest-runtime-image"], "attest-runtime-image"); + assert.equal(attestInput.type, "boolean"); + assert.equal(attestInput.default, true); const jobs = object(workflow.jobs, "jobs"); const job = object(jobs["build-upload"], "build-upload"); assert.equal(job["runs-on"], "ubuntu-24.04-arm"); @@ -32,6 +38,7 @@ describe("Cargo runtime-image reusable workflow", () => { steps[attest]?.uses, "actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a" ); + assert.equal(steps[attest]?.if, "${{ inputs.attest-runtime-image }}"); assert.equal( steps[upload]?.uses, "proof-computer/liskov-github-actions/actions/runtime-image-upload@v1" diff --git a/package.json b/package.json index fec8980..04f8613 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "liskov-github-actions", - "version": "1.2.2", + "version": "1.2.3", "private": true, "type": "module", "description": "Reusable GitHub Actions + workflows for Liskov CI: manifest-bound artifact and runtime-image publication plus marketplace OIDC ingest.",