#!/usr/bin/env bash set -euo pipefail # Create and verify a DSSE attestation for a policy blob using cosign. # Intended for CI and offline use; works with base64 inlined keys. usage() { cat <<'USAGE' Usage: attest-verify.sh --file [--predicate ] [--type stella.policy] [--out-dir out/policy-sign] Env: COSIGN_KEY_B64 base64-encoded PEM private key (if not using COSIGN_KEY path) COSIGN_PASSWORD passphrase for the private key (optional) USAGE } FILE="" PREDICATE="" TYPE="stella.policy" OUT_DIR="out/policy-sign" while [[ $# -gt 0 ]]; do case "$1" in --file) FILE="$2"; shift 2;; --predicate) PREDICATE="$2"; shift 2;; --type) TYPE="$2"; shift 2;; --out-dir) OUT_DIR="$2"; shift 2;; -h|--help) usage; exit 0;; *) echo "Unknown arg: $1" >&2; usage; exit 1;; esac done if [[ -z "$FILE" ]]; then echo "--file is required" >&2; exit 1; fi if [[ ! -f "$FILE" ]]; then echo "file not found: $FILE" >&2; exit 1; fi if ! command -v cosign >/dev/null 2>&1; then echo "cosign is required on PATH" >&2 exit 1 fi mkdir -p "$OUT_DIR" BASENAME=$(basename "$FILE") KEY_PATH=${COSIGN_KEY:-"$OUT_DIR/cosign.key"} PUB_OUT="$OUT_DIR/cosign.pub" BUNDLE="$OUT_DIR/${BASENAME}.attestation.sigstore" if [[ -n "${COSIGN_KEY_B64:-}" ]]; then printf "%s" "$COSIGN_KEY_B64" | base64 -d > "$KEY_PATH" chmod 600 "$KEY_PATH" fi if [[ ! -f "$KEY_PATH" ]]; then echo "Missing signing key; set COSIGN_KEY_B64 or COSIGN_KEY path" >&2 exit 1 fi export COSIGN_PASSWORD=${COSIGN_PASSWORD:-} if [[ -z "$PREDICATE" ]]; then PREDICATE="$OUT_DIR/${BASENAME}.predicate.json" sha256sum "$FILE" | awk '{print $1}' > "$OUT_DIR/${BASENAME}.sha256" cat > "$PREDICATE" < "$PUB_OUT" cosign attest-blob \ --predicate "$PREDICATE" \ --type "$TYPE" \ --bundle "$BUNDLE" \ --key "$KEY_PATH" \ "$FILE" cosign verify-blob-attestation \ --key "$PUB_OUT" \ --type "$TYPE" \ --bundle "$BUNDLE" \ "$FILE" printf "Attestation bundle -> %s\nVerified with -> %s\n" "$BUNDLE" "$PUB_OUT"