Skip to content

feat: reusable signing actions (sign-oci, sign-blob) + wire into pack-build-image - #46

Merged
dcmcand merged 11 commits into
mainfrom
feat/reusable-signing-actions
Jul 30, 2026
Merged

feat: reusable signing actions (sign-oci, sign-blob) + wire into pack-build-image#46
dcmcand merged 11 commits into
mainfrom
feat/reusable-signing-actions

Conversation

@dcmcand

@dcmcand dcmcand commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add sign-oci and sign-blob composite actions for keyless cosign signing + build provenance/SBOM attestation.
  • Add sign-smoke.yaml to exercise both actions end-to-end (including negative tamper/wrong-identity cases) on push to this branch.
  • Wire sign-oci into pack-build-image.yaml: sign + attest images pushed to both GHCR and Quay after build, gated on inputs.push.

Test plan

  • actionlint clean locally for all touched workflow files
  • pre-commit run --all-files clean
  • sign-smoke.yaml green on push (image + chart smoke tests, tamper/wrong-identity negative cases)
  • lint-test.yaml actionlint job green on this PR
  • Real end-to-end exercise of pack-build-image.yaml signing at a future pack release

dcmcand added 8 commits July 17, 2026 13:48
Adds a keyless (cosign/Fulcio/Rekor) sign-oci composite action that signs
an OCI image by digest and attests build provenance + SPDX SBOM, plus a
sign-smoke workflow that builds a throwaway ghcr image, signs/attests it,
and verifies the signature, provenance attestation, and SBOM package
count end-to-end.
Sign the packaged Helm chart .tgz with keyless cosign and attach the
bundle + SBOM to the GitHub Release alongside the chart.
…ws; document reusable-workflow signer verification

pack-build-image.yaml's sign-oci steps used `uses: ./.github/actions/sign-oci`,
which resolves against the CALLING pack repo's checkout when invoked as a
reusable workflow, not this repo -- so it would fail at a real pack release.
Add the same job.workflow_repository@job.workflow_sha checkout that
pack-release.yaml already uses for its Python script, and point both sign-oci
steps and pack-release.yaml's sign-blob step at that checkout instead.

Extend .github/actionlint.yaml's existing ignore-list workaround (actionlint
doesn't yet know about job.workflow_repository/job.workflow_sha) to cover
pack-build-image.yaml too.

verifying-nebari-artifacts.md's gh attestation verify commands only passed
--repo, which is not sufficient to pin the signer when the attestation was
generated by a reusable workflow (per the gh CLI manual) -- add
--signer-workflow pointing at pack-build-image.yaml or pack-release.yaml as
appropriate, for every affected command.

Repoint sign-smoke.yaml's trigger from the throwaway feature branch to push
on main + pull_request (path-filtered to the sign actions/workflow), so it
gets real post-merge regression coverage instead of only running on this
branch.
@dcmcand
dcmcand marked this pull request as ready for review July 17, 2026 13:35
@dcmcand

dcmcand commented Jul 17, 2026

Copy link
Copy Markdown
Contributor Author

End-to-end validation against a real pack (journey 8)

Validated these reusable signing workflows by wiring them into nebari-dev/llm-serving-pack (test branch test/signing-integration: callers pinned at @feat/reusable-signing-actions, id-token/attestations granted at the caller jobs, chart bumped to prerelease 0.1.3-signingtest.1).

Container images (pack-build-image)

  • Build run succeeded for all 4 images (operator, model-downloader, key-manager, frontend); each signed + attested in both registries.
  • cosign verify ghcr.io/nebari-dev/llm-serving-pack/operator:sha-3a94a9d -> verified: cosign signature (sigstore.dev/cosign/sign/v1) + SLSA provenance (slsa.dev/provenance/v1) + SPDX SBOM (spdx.dev/Document/v2.3), transparency log + cert chain checked.
  • cosign verify quay.io/nebari/llm-serving-pack-operator:sha-3a94a9d -> verified (confirms the both-registries requirement).
  • Certificate identity: pack-build-image.yaml (the reusable workflow), issuer https://token.actions.githubusercontent.com.

Chart .tgz (pack-release)

  • Release run created prerelease nebari-llm-serving-0.1.3-signingtest.1 with assets .tgz + .tgz.sigstore.json (bundle) + .tgz.spdx.json (SBOM).
  • cosign verify-blob --bundle … against the pack-release.yaml identity -> Verified OK.

Notes

  • This exercised the reusable-workflow action-loading fix (_dot-github) in a real external-caller context, i.e. the path the in-repo sign-smoke test structurally cannot cover.
  • The consumer commands + identities in verifying-nebari-artifacts.md were used verbatim and pass.
  • Follow-up (phase 2, separate repo): signing the canonical OCI chart at quay.io/nebari/charts happens in nebari-dev/helm-repository's own release workflow and is being implemented separately. The .tgz on the GitHub Release (validated above) and the OCI chart consumers helm install are distinct artifacts; this PR covers the pack side (images + .tgz).
  • Test scaffolding (pack prerelease/tag, the helm-repository sync PR, and the test branch) will be cleaned up.

Adds a boolean `sync` input (default true) gating the sync-chart step, so
callers can run the full release path (read version, pin tags, package,
sign/attest, GitHub Release) without opening a PR in nebari-dev/helm-repository.
Makes NEBARI_HELM_REPO_TOKEN required: false since it is only used by the sync
step (needed only when sync is true). Default preserves existing behavior.

Closes #47
@dcmcand
dcmcand merged commit a6c757c into main Jul 30, 2026
5 checks passed
@dcmcand
dcmcand deleted the feat/reusable-signing-actions branch July 30, 2026 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant