Files
git.stella-ops.org/.github/workflows/examples/example-sbom-sign.yml
StellaOps Bot 907783f625 Add property-based tests for SBOM/VEX document ordering and Unicode normalization determinism
- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency.
- Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling.
- Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies.
- Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification.
- Create validation script for CI/CD templates ensuring all required files and structures are present.
2025-12-26 15:17:58 +02:00

185 lines
5.3 KiB
YAML

# .github/workflows/examples/example-sbom-sign.yml
# Example: Generate and sign SBOM with keyless signing
#
# This example shows how to:
# 1. Generate SBOM using Syft
# 2. Sign the SBOM with StellaOps
# 3. Attach SBOM attestation to container image
#
# The signed SBOM provides:
# - Proof of SBOM generation time
# - Binding to CI/CD identity (repo, branch, workflow)
# - Transparency log entry for audit
name: Generate and Sign SBOM
on:
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
inputs:
image:
description: 'Container image to scan (with digest)'
required: true
type: string
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
generate-sbom:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
outputs:
sbom-digest: ${{ steps.sbom.outputs.digest }}
image-digest: ${{ steps.resolve.outputs.digest }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Syft
uses: anchore/sbom-action/download-syft@v0
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Resolve Image Digest
id: resolve
run: |
if [[ -n "${{ github.event.inputs.image }}" ]]; then
IMAGE="${{ github.event.inputs.image }}"
else
IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}"
fi
# Resolve to digest if not already
if [[ ! "$IMAGE" =~ @sha256: ]]; then
DIGEST=$(docker manifest inspect "$IMAGE" -v | jq -r '.Descriptor.digest')
IMAGE="${IMAGE%%:*}@${DIGEST}"
else
DIGEST="${IMAGE##*@}"
fi
echo "image=${IMAGE}" >> $GITHUB_OUTPUT
echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
echo "Resolved image: $IMAGE"
- name: Generate SBOM
id: sbom
run: |
set -euo pipefail
IMAGE="${{ steps.resolve.outputs.image }}"
SBOM_FILE="sbom.cdx.json"
echo "::group::Generating SBOM for $IMAGE"
syft "$IMAGE" \
--output cyclonedx-json="${SBOM_FILE}" \
--source-name "${{ github.repository }}" \
--source-version "${{ github.sha }}"
echo "::endgroup::"
# Calculate SBOM digest
SBOM_DIGEST="sha256:$(sha256sum "${SBOM_FILE}" | cut -d' ' -f1)"
echo "digest=${SBOM_DIGEST}" >> $GITHUB_OUTPUT
echo "SBOM digest: ${SBOM_DIGEST}"
# Store for upload
echo "${SBOM_DIGEST}" > sbom-digest.txt
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: |
sbom.cdx.json
sbom-digest.txt
if-no-files-found: error
sign-sbom:
needs: generate-sbom
uses: ./.github/workflows/examples/stellaops-sign.yml
with:
artifact-digest: ${{ needs.generate-sbom.outputs.sbom-digest }}
artifact-type: sbom
predicate-type: 'https://cyclonedx.org/bom/1.5'
push-attestation: true
permissions:
id-token: write
contents: read
packages: write
attach-to-image:
needs: [generate-sbom, sign-sbom]
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Download SBOM
uses: actions/download-artifact@v4
with:
name: sbom
- name: Install StellaOps CLI
uses: stella-ops/setup-cli@v1
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Attach SBOM to Image
env:
IMAGE_DIGEST: ${{ needs.generate-sbom.outputs.image-digest }}
ATTESTATION_DIGEST: ${{ needs.sign-sbom.outputs.attestation-digest }}
run: |
echo "::group::Attaching SBOM attestation to image"
stella attest attach \
--image "${IMAGE_DIGEST}" \
--attestation "${ATTESTATION_DIGEST}" \
--type sbom
echo "::endgroup::"
- name: Summary
run: |
cat >> $GITHUB_STEP_SUMMARY << EOF
## SBOM Signed and Attached
| Field | Value |
|-------|-------|
| **Image** | \`${{ needs.generate-sbom.outputs.image-digest }}\` |
| **SBOM Digest** | \`${{ needs.generate-sbom.outputs.sbom-digest }}\` |
| **Attestation** | \`${{ needs.sign-sbom.outputs.attestation-digest }}\` |
| **Rekor UUID** | \`${{ needs.sign-sbom.outputs.rekor-uuid }}\` |
### Verify SBOM
\`\`\`bash
stella attest verify \\
--artifact "${{ needs.generate-sbom.outputs.sbom-digest }}" \\
--certificate-identity "repo:${{ github.repository }}:ref:${{ github.ref }}" \\
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
\`\`\`
### Download SBOM
\`\`\`bash
stella sbom download \\
--image "${{ needs.generate-sbom.outputs.image-digest }}" \\
--output sbom.cdx.json
\`\`\`
EOF