test fixes and new product advisories work

This commit is contained in:
master
2026-01-28 02:30:48 +02:00
parent 82caceba56
commit 644887997c
288 changed files with 69101 additions and 375 deletions

View File

@@ -0,0 +1,182 @@
#!/bin/bash
# Copyright (c) StellaOps. All rights reserved.
# Licensed under the BUSL-1.1 license.
#
# collect-rekor-proofs.sh
# Collects Rekor transparency log inclusion proofs for release artifacts
#
# Usage: ./collect-rekor-proofs.sh --artifacts <dir> --output <dir>
#
# Prerequisites:
# - rekor-cli installed (https://github.com/sigstore/rekor)
# - Artifacts must already be signed and uploaded to Rekor
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Default values
ARTIFACTS_DIR="artifacts"
OUTPUT_DIR="rekor-proofs"
REKOR_SERVER="${REKOR_SERVER:-https://rekor.sigstore.dev}"
PUBLIC_KEY_FILE="cosign.pub"
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--artifacts)
ARTIFACTS_DIR="$2"
shift 2
;;
--output)
OUTPUT_DIR="$2"
shift 2
;;
--public-key)
PUBLIC_KEY_FILE="$2"
shift 2
;;
--rekor-server)
REKOR_SERVER="$2"
shift 2
;;
--help)
echo "Usage: $0 --artifacts <dir> --output <dir>"
echo ""
echo "Options:"
echo " --artifacts Directory containing signed artifacts (default: artifacts)"
echo " --output Output directory for Rekor proofs (default: rekor-proofs)"
echo " --public-key Path to public key file (default: cosign.pub)"
echo " --rekor-server Rekor server URL (default: https://rekor.sigstore.dev)"
exit 0
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
exit 1
;;
esac
done
# Check for rekor-cli
if ! command -v rekor-cli &> /dev/null; then
echo -e "${YELLOW}Warning: rekor-cli not found. Skipping Rekor proof collection.${NC}"
echo "Install from: https://github.com/sigstore/rekor/releases"
mkdir -p "$OUTPUT_DIR"
echo '{"warning": "rekor-cli not available", "proofs": []}' > "${OUTPUT_DIR}/inclusion-proofs.json"
exit 0
fi
# Create output directories
mkdir -p "${OUTPUT_DIR}/log-entries"
echo -e "${GREEN}Collecting Rekor inclusion proofs${NC}"
echo " Artifacts: ${ARTIFACTS_DIR}"
echo " Output: ${OUTPUT_DIR}"
echo " Rekor Server: ${REKOR_SERVER}"
# Initialize inclusion proofs JSON
proofs_json='{"proofs": []}'
checkpoint=""
# Function to collect proof for a single artifact
collect_proof() {
local artifact_path="$1"
local artifact_name
artifact_name=$(basename "$artifact_path")
local sig_path="${artifact_path}.sig"
if [[ ! -f "$sig_path" ]]; then
echo -e " ${YELLOW}Skipping ${artifact_name}: no signature file found${NC}"
return
fi
echo " Processing: ${artifact_name}"
# Search for the entry in Rekor
local search_result
if ! search_result=$(rekor-cli search --artifact "$artifact_path" --rekor_server "$REKOR_SERVER" 2>/dev/null); then
echo -e " ${YELLOW}No Rekor entry found${NC}"
return
fi
# Extract UUIDs from search result
local uuids
uuids=$(echo "$search_result" | grep -oE '[0-9a-f]{64}' || true)
if [[ -z "$uuids" ]]; then
echo -e " ${YELLOW}No matching entries in Rekor${NC}"
return
fi
# Get the first (most recent) UUID
local uuid
uuid=$(echo "$uuids" | head -1)
echo " Found entry: ${uuid}"
# Get the full log entry
local entry_file="${OUTPUT_DIR}/log-entries/${uuid}.json"
if rekor-cli get --uuid "$uuid" --rekor_server "$REKOR_SERVER" --format json > "$entry_file" 2>/dev/null; then
echo -e " ${GREEN}Saved log entry${NC}"
# Extract log index and integrated time
local log_index
log_index=$(jq -r '.LogIndex' "$entry_file" 2>/dev/null || echo "-1")
local integrated_time
integrated_time=$(jq -r '.IntegratedTime' "$entry_file" 2>/dev/null || echo "0")
# Add to proofs JSON
proofs_json=$(echo "$proofs_json" | jq --arg uuid "$uuid" \
--arg artifact "$artifact_name" \
--argjson logIndex "$log_index" \
--argjson integratedTime "$integrated_time" \
--arg path "log-entries/${uuid}.json" \
'.proofs += [{"uuid": $uuid, "artifactName": $artifact, "logIndex": $logIndex, "integratedTime": $integratedTime, "inclusionProofPath": $path}]')
else
echo -e " ${YELLOW}Failed to retrieve entry details${NC}"
fi
}
# Get Rekor checkpoint (signed tree head)
echo ""
echo "Fetching Rekor checkpoint..."
if checkpoint_result=$(curl -s "${REKOR_SERVER}/api/v1/log" 2>/dev/null); then
echo "$checkpoint_result" > "${OUTPUT_DIR}/checkpoint.json"
checkpoint=$(echo "$checkpoint_result" | jq -r '.signedTreeHead // empty' 2>/dev/null || true)
if [[ -n "$checkpoint" ]]; then
echo -e " ${GREEN}Checkpoint saved${NC}"
fi
fi
# Process all artifacts
echo ""
echo "Processing artifacts..."
for artifact in "${ARTIFACTS_DIR}"/stella-*.tar.gz "${ARTIFACTS_DIR}"/stella-*.zip; do
if [[ -f "$artifact" ]]; then
collect_proof "$artifact"
fi
done
# Also process checksums if signed
for checksum_file in "${ARTIFACTS_DIR}"/*.sums "${ARTIFACTS_DIR}"/SHA256SUMS "${ARTIFACTS_DIR}"/SHA512SUMS; do
if [[ -f "$checksum_file" ]] && [[ -f "${checksum_file}.sig" ]]; then
collect_proof "$checksum_file"
fi
done
# Write final inclusion proofs JSON
echo "$proofs_json" | jq '.' > "${OUTPUT_DIR}/inclusion-proofs.json"
# Count proofs
proof_count=$(echo "$proofs_json" | jq '.proofs | length')
echo ""
echo -e "${GREEN}Collected ${proof_count} inclusion proof(s)${NC}"
echo "Files written to: ${OUTPUT_DIR}/"
echo ""
echo "Contents:"
ls -la "${OUTPUT_DIR}/"

View File

@@ -0,0 +1,185 @@
#!/bin/bash
# Copyright (c) StellaOps. All rights reserved.
# Licensed under the BUSL-1.1 license.
#
# generate-slsa-provenance.sh
# Generates SLSA v1.0 provenance statements for release artifacts
#
# Usage: ./generate-slsa-provenance.sh --version <version> --commit <sha> --output <dir>
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Default values
VERSION=""
COMMIT=""
OUTPUT_DIR="provenance"
ARTIFACTS_DIR="artifacts"
BUILDER_ID="${BUILDER_ID:-https://ci.stella-ops.org/builder/v1}"
BUILD_TYPE="${BUILD_TYPE:-https://stella-ops.io/ReleaseBuilder/v1}"
REPOSITORY_URI="${REPOSITORY_URI:-git+https://git.stella-ops.org/stella-ops.org/git.stella-ops.org}"
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--version)
VERSION="$2"
shift 2
;;
--commit)
COMMIT="$2"
shift 2
;;
--output)
OUTPUT_DIR="$2"
shift 2
;;
--artifacts)
ARTIFACTS_DIR="$2"
shift 2
;;
--builder-id)
BUILDER_ID="$2"
shift 2
;;
--build-type)
BUILD_TYPE="$2"
shift 2
;;
--help)
echo "Usage: $0 --version <version> --commit <sha> --output <dir>"
echo ""
echo "Options:"
echo " --version Release version (required)"
echo " --commit Git commit SHA (required)"
echo " --output Output directory for provenance files (default: provenance)"
echo " --artifacts Directory containing release artifacts (default: artifacts)"
echo " --builder-id Builder ID URI (default: https://ci.stella-ops.org/builder/v1)"
echo " --build-type Build type URI (default: https://stella-ops.io/ReleaseBuilder/v1)"
exit 0
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
exit 1
;;
esac
done
# Validate required arguments
if [[ -z "$VERSION" ]]; then
echo -e "${RED}Error: --version is required${NC}"
exit 1
fi
if [[ -z "$COMMIT" ]]; then
echo -e "${RED}Error: --commit is required${NC}"
exit 1
fi
# Create output directory
mkdir -p "$OUTPUT_DIR"
# Get timestamps
STARTED_ON="${BUILD_STARTED_ON:-$(date -u +%Y-%m-%dT%H:%M:%SZ)}"
FINISHED_ON="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
# Get invocation ID from CI environment
INVOCATION_ID="${CI_JOB_ID:-${GITHUB_RUN_ID:-$(uuidgen || cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "local-build")}}"
echo -e "${GREEN}Generating SLSA v1.0 provenance for version ${VERSION}${NC}"
echo " Commit: ${COMMIT}"
echo " Builder: ${BUILDER_ID}"
echo " Output: ${OUTPUT_DIR}"
# Function to generate provenance for a single artifact
generate_provenance() {
local artifact_path="$1"
local artifact_name
artifact_name=$(basename "$artifact_path")
# Compute SHA-256 digest
local sha256
sha256=$(sha256sum "$artifact_path" | cut -d' ' -f1)
# Determine component name from artifact
local component_name
component_name=$(echo "$artifact_name" | sed -E 's/stella-([^-]+).*/\1/')
local output_file="${OUTPUT_DIR}/${component_name}.slsa.intoto.jsonl"
echo " Generating provenance for: ${artifact_name}"
# Generate SLSA v1.0 provenance statement
cat > "$output_file" << EOF
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "${artifact_name}",
"digest": {
"sha256": "${sha256}"
}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "${BUILD_TYPE}",
"externalParameters": {
"version": "${VERSION}",
"repository": "${REPOSITORY_URI}",
"ref": "refs/tags/v${VERSION}"
},
"internalParameters": {},
"resolvedDependencies": [
{
"uri": "${REPOSITORY_URI}@refs/tags/v${VERSION}",
"digest": {
"gitCommit": "${COMMIT}"
}
}
]
},
"runDetails": {
"builder": {
"id": "${BUILDER_ID}",
"version": {
"stellaOps": "${VERSION}"
}
},
"metadata": {
"invocationId": "${INVOCATION_ID}",
"startedOn": "${STARTED_ON}",
"finishedOn": "${FINISHED_ON}"
},
"byproducts": []
}
}
}
EOF
echo -e " ${GREEN}Created: ${output_file}${NC}"
}
# Find and process artifacts
artifact_count=0
for artifact in "${ARTIFACTS_DIR}"/stella-*.tar.gz "${ARTIFACTS_DIR}"/stella-*.zip; do
if [[ -f "$artifact" ]]; then
generate_provenance "$artifact"
((artifact_count++))
fi
done
if [[ $artifact_count -eq 0 ]]; then
echo -e "${YELLOW}Warning: No artifacts found in ${ARTIFACTS_DIR}${NC}"
exit 0
fi
echo ""
echo -e "${GREEN}Generated ${artifact_count} provenance statement(s)${NC}"
echo "Files written to: ${OUTPUT_DIR}/"