Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/build-ai-cluster-iso.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ on:

permissions:
contents: read
id-token: write # B-0853.1: sigstore/cosign keyless OIDC signing. Fulcio CA
# mints a short-lived cert from the GitHub-issued OIDC token;
# Rekor transparency log records the signature. No private
Comment thread
AceHack marked this conversation as resolved.
# key material is handled in this workflow. The token-issuance
# scope is workflow-bound; granted permission cannot be
# exfiltrated to mint signatures for other workflows.
Comment thread
AceHack marked this conversation as resolved.

concurrency:
group: build-ai-cluster-iso-${{ github.workflow }}-${{ github.ref }}
Expand Down Expand Up @@ -300,6 +306,63 @@ jobs:
echo "to flash the stick. (ISO is ~1.5–2 GiB.)"
} >> "$GITHUB_STEP_SUMMARY"

# B-0853.1 — sigstore/cosign keyless OIDC signing of the ISO blob.
# Composes with B-0853 (sigstore artifact signing free-stuff substrate).
#
# Keyless model: GitHub OIDC token (from id-token: write permission at
# workflow level) is exchanged with Fulcio CA for a short-lived cert
# bound to this workflow's identity. cosign then signs the ISO blob
# with that cert + records the signature in the Rekor transparency log.
# No long-lived private key material in this workflow.
#
# Verification (any consumer):
# cosign verify-blob \
# --certificate <iso>.pem \
# --signature <iso>.sig \
# --certificate-identity-regexp '^https://github.com/Lucent-Financial-Group/Zeta' \
# --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
Comment thread
AceHack marked this conversation as resolved.
# <iso>
#
# Security: inputs to cosign are filesystem paths from steps.iso.outputs
# of THIS workflow (no github.event.* interpolation). Same discipline
# as the QEMU boot-test step above.
- name: Install cosign
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
# Pin verified via gh API 2026-05-27:
# gh api repos/sigstore/cosign-installer/releases/latest
# tag: v4.1.2; published: 2026-05-07T01:27:27Z
# Per .claude/rules/dep-pin-search-first-authority.md

- name: Sign ISO with cosign (keyless OIDC + Fulcio + Rekor)
env:
# Pass ISO path via env (not direct ${{ }} interpolation in run:)
# per the workflow's existing security discipline.
ISO_PATH: ${{ steps.iso.outputs.path }}
ISO_NAME: ${{ steps.iso.outputs.name }}
run: |
set -euo pipefail
# --yes: skip interactive Fulcio confirmation (CI is non-interactive)
# Output files emitted alongside the ISO:
# <iso>.sig — signature (base64; small)
# <iso>.pem — short-lived Fulcio cert (the verifier's anchor)
cosign sign-blob --yes \
--output-signature "${ISO_PATH}.sig" \
--output-certificate "${ISO_PATH}.pem" \
"${ISO_PATH}"
# Sanity: both artifacts present and non-empty.
test -s "${ISO_PATH}.sig" || { echo "::error::Empty signature"; exit 1; }
test -s "${ISO_PATH}.pem" || { echo "::error::Empty certificate"; exit 1; }
{
echo "## ISO signed via sigstore (cosign keyless OIDC)"
echo ""
echo "| Artifact | Path |"
echo "|---|---|"
echo "| Signature | \`${ISO_NAME}.sig\` |"
echo "| Certificate | \`${ISO_NAME}.pem\` |"
echo ""
echo "Verification: see workflow run logs for the canonical \`cosign verify-blob\` command."
} >> "$GITHUB_STEP_SUMMARY"

- name: Upload ISO as workflow artifact
# Available for download from the workflow run page for ~90 days.
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
Expand All @@ -309,3 +372,16 @@ jobs:
if-no-files-found: error
retention-days: 90
compression-level: 0 # ISO is already compressed; re-zipping wastes time

- name: Upload cosign signature + certificate as workflow artifact
# B-0853.1 sibling upload — sig + pem alongside the ISO for consumers.
# Separate artifact (not bundled with ISO) so consumers downloading
# just the ISO don't pay the (small) cost; verifiers can grab both.
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: ${{ steps.iso.outputs.name }}.cosign
path: |
${{ steps.iso.outputs.path }}.sig
${{ steps.iso.outputs.path }}.pem
if-no-files-found: error
retention-days: 90
Loading