Files
git.stella-ops.org/devops/docker/sbom_attest.sh
2025-12-26 18:11:06 +02:00

49 lines
1.6 KiB
Bash

#!/usr/bin/env bash
# Deterministic SBOM + attestation helper for DOCKER-44-002
# Usage: ./sbom_attest.sh <image-ref> [output-dir] [cosign-key]
# - image-ref: fully qualified image (e.g., ghcr.io/stellaops/policy:1.2.3)
# - output-dir: defaults to ./sbom
# - cosign-key: path to cosign key (PEM). If omitted, uses keyless if allowed (COSIGN_EXPERIMENTAL=1)
set -euo pipefail
IMAGE_REF=${1:?"image ref required"}
OUT_DIR=${2:-sbom}
COSIGN_KEY=${3:-}
mkdir -p "${OUT_DIR}"
# Normalize filename (replace / and : with _)
name_safe() {
echo "$1" | tr '/:' '__'
}
BASENAME=$(name_safe "${IMAGE_REF}")
SPDX_JSON="${OUT_DIR}/${BASENAME}.spdx.json"
CDX_JSON="${OUT_DIR}/${BASENAME}.cdx.json"
ATTESTATION="${OUT_DIR}/${BASENAME}.sbom.att"
# Freeze timestamps for reproducibility
export SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH:-1704067200}
# Generate SPDX 3.0-ish JSON (syft formats are stable and offline-friendly)
syft "${IMAGE_REF}" -o spdx-json > "${SPDX_JSON}"
# Generate CycloneDX 1.6 JSON
syft "${IMAGE_REF}" -o cyclonedx-json > "${CDX_JSON}"
# Attach SBOMs as cosign attestations (one per format)
export COSIGN_EXPERIMENTAL=${COSIGN_EXPERIMENTAL:-1}
COSIGN_ARGS=("attest" "--predicate" "${SPDX_JSON}" "--type" "spdx" "${IMAGE_REF}")
if [[ -n "${COSIGN_KEY}" ]]; then
COSIGN_ARGS+=("--key" "${COSIGN_KEY}")
fi
cosign "${COSIGN_ARGS[@]}"
COSIGN_ARGS=("attest" "--predicate" "${CDX_JSON}" "--type" "cyclonedx" "${IMAGE_REF}")
if [[ -n "${COSIGN_KEY}" ]]; then
COSIGN_ARGS+=("--key" "${COSIGN_KEY}")
fi
cosign "${COSIGN_ARGS[@]}"
echo "SBOMs written to ${SPDX_JSON} and ${CDX_JSON}" >&2
echo "Attestations pushed for ${IMAGE_REF}" >&2