up the blokcing tasks
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Risk Bundle CI / risk-bundle-build (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Risk Bundle CI / risk-bundle-offline-kit (push) Has been cancelled
Risk Bundle CI / publish-checksums (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Risk Bundle CI / risk-bundle-build (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Risk Bundle CI / risk-bundle-offline-kit (push) Has been cancelled
Risk Bundle CI / publish-checksums (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Mirror Thin Bundle Sign & Verify / mirror-sign (push) Has been cancelled
This commit is contained in:
278
ops/devops/risk-bundle/build-bundle.sh
Normal file
278
ops/devops/risk-bundle/build-bundle.sh
Normal file
@@ -0,0 +1,278 @@
|
||||
#!/usr/bin/env bash
|
||||
# Risk Bundle Builder Script
|
||||
# RISK-BUNDLE-69-002: CI/offline kit pipeline integration
|
||||
#
|
||||
# Usage: build-bundle.sh --output <dir> [--fixtures-only] [--include-osv]
|
||||
#
|
||||
# This script builds a risk bundle for offline kit distribution.
|
||||
# In --fixtures-only mode, it generates a deterministic fixture bundle
|
||||
# suitable for CI testing without requiring live provider data.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
|
||||
# Defaults
|
||||
OUTPUT_DIR=""
|
||||
FIXTURES_ONLY=false
|
||||
INCLUDE_OSV=false
|
||||
BUNDLE_ID=""
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--output)
|
||||
OUTPUT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
--fixtures-only)
|
||||
FIXTURES_ONLY=true
|
||||
shift
|
||||
;;
|
||||
--include-osv)
|
||||
INCLUDE_OSV=true
|
||||
shift
|
||||
;;
|
||||
--bundle-id)
|
||||
BUNDLE_ID="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: build-bundle.sh --output <dir> [--fixtures-only] [--include-osv] [--bundle-id <id>]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --output <dir> Output directory for bundle artifacts (required)"
|
||||
echo " --fixtures-only Use fixture data instead of live provider downloads"
|
||||
echo " --include-osv Include OSV providers (larger bundle)"
|
||||
echo " --bundle-id <id> Custom bundle ID (default: auto-generated)"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate required arguments
|
||||
if [[ -z "$OUTPUT_DIR" ]]; then
|
||||
echo "Error: --output is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate bundle ID if not provided
|
||||
if [[ -z "$BUNDLE_ID" ]]; then
|
||||
BUNDLE_ID="risk-bundle-$(date -u +%Y%m%d-%H%M%S)"
|
||||
fi
|
||||
|
||||
echo "=== Risk Bundle Builder ==="
|
||||
echo "Output directory: $OUTPUT_DIR"
|
||||
echo "Bundle ID: $BUNDLE_ID"
|
||||
echo "Fixtures only: $FIXTURES_ONLY"
|
||||
echo "Include OSV: $INCLUDE_OSV"
|
||||
|
||||
# Create output directory
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Create temporary working directory
|
||||
WORK_DIR=$(mktemp -d)
|
||||
trap "rm -rf $WORK_DIR" EXIT
|
||||
|
||||
echo ""
|
||||
echo "=== Preparing provider data ==="
|
||||
|
||||
# Provider directories
|
||||
mkdir -p "$WORK_DIR/providers/cisa-kev"
|
||||
mkdir -p "$WORK_DIR/providers/first-epss"
|
||||
mkdir -p "$WORK_DIR/manifests"
|
||||
mkdir -p "$WORK_DIR/signatures"
|
||||
|
||||
# Fixed timestamp for deterministic builds (2024-01-01 00:00:00 UTC)
|
||||
FIXED_TIMESTAMP="2024-01-01T00:00:00Z"
|
||||
FIXED_EPOCH=1704067200
|
||||
|
||||
if [[ "$FIXTURES_ONLY" == "true" ]]; then
|
||||
echo "Using fixture data..."
|
||||
|
||||
# Create CISA KEV fixture (mandatory provider)
|
||||
cat > "$WORK_DIR/providers/cisa-kev/snapshot" <<'EOF'
|
||||
{
|
||||
"catalogVersion": "2024.12.11",
|
||||
"dateReleased": "2024-12-11T00:00:00Z",
|
||||
"count": 3,
|
||||
"vulnerabilities": [
|
||||
{
|
||||
"cveID": "CVE-2024-0001",
|
||||
"vendorProject": "Example Vendor",
|
||||
"product": "Example Product",
|
||||
"vulnerabilityName": "Example Vulnerability 1",
|
||||
"dateAdded": "2024-01-15",
|
||||
"shortDescription": "Test vulnerability for CI fixtures",
|
||||
"requiredAction": "Apply updates per vendor instructions",
|
||||
"dueDate": "2024-02-05",
|
||||
"knownRansomwareCampaignUse": "Unknown"
|
||||
},
|
||||
{
|
||||
"cveID": "CVE-2024-0002",
|
||||
"vendorProject": "Another Vendor",
|
||||
"product": "Another Product",
|
||||
"vulnerabilityName": "Example Vulnerability 2",
|
||||
"dateAdded": "2024-02-01",
|
||||
"shortDescription": "Another test vulnerability",
|
||||
"requiredAction": "Apply updates per vendor instructions",
|
||||
"dueDate": "2024-02-22",
|
||||
"knownRansomwareCampaignUse": "Known"
|
||||
},
|
||||
{
|
||||
"cveID": "CVE-2024-0003",
|
||||
"vendorProject": "Third Vendor",
|
||||
"product": "Third Product",
|
||||
"vulnerabilityName": "Example Vulnerability 3",
|
||||
"dateAdded": "2024-03-01",
|
||||
"shortDescription": "Third test vulnerability",
|
||||
"requiredAction": "Apply updates per vendor instructions",
|
||||
"dueDate": "2024-03-22",
|
||||
"knownRansomwareCampaignUse": "Unknown"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Create FIRST EPSS fixture (optional provider)
|
||||
cat > "$WORK_DIR/providers/first-epss/snapshot" <<'EOF'
|
||||
{
|
||||
"model_version": "v2024.01.01",
|
||||
"score_date": "2024-12-11",
|
||||
"scores": [
|
||||
{"cve": "CVE-2024-0001", "epss": 0.00043, "percentile": 0.08},
|
||||
{"cve": "CVE-2024-0002", "epss": 0.00156, "percentile": 0.45},
|
||||
{"cve": "CVE-2024-0003", "epss": 0.00089, "percentile": 0.21}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# Include OSV if requested
|
||||
if [[ "$INCLUDE_OSV" == "true" ]]; then
|
||||
mkdir -p "$WORK_DIR/providers/osv"
|
||||
cat > "$WORK_DIR/providers/osv/snapshot" <<'EOF'
|
||||
{
|
||||
"source": "osv",
|
||||
"updated": "2024-12-11T00:00:00Z",
|
||||
"advisories": [
|
||||
{"id": "GHSA-test-0001", "modified": "2024-01-15T00:00:00Z", "aliases": ["CVE-2024-0001"]},
|
||||
{"id": "GHSA-test-0002", "modified": "2024-02-01T00:00:00Z", "aliases": ["CVE-2024-0002"]}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
else
|
||||
echo "Live provider download not yet implemented"
|
||||
echo "Use --fixtures-only for CI testing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Computing hashes ==="
|
||||
|
||||
# Compute hashes for each provider file
|
||||
CISA_HASH=$(sha256sum "$WORK_DIR/providers/cisa-kev/snapshot" | cut -d' ' -f1)
|
||||
EPSS_HASH=$(sha256sum "$WORK_DIR/providers/first-epss/snapshot" | cut -d' ' -f1)
|
||||
|
||||
echo "cisa-kev hash: $CISA_HASH"
|
||||
echo "first-epss hash: $EPSS_HASH"
|
||||
|
||||
PROVIDERS_JSON="[
|
||||
{\"providerId\": \"cisa-kev\", \"digest\": \"sha256:$CISA_HASH\", \"snapshotDate\": \"$FIXED_TIMESTAMP\", \"optional\": false},
|
||||
{\"providerId\": \"first-epss\", \"digest\": \"sha256:$EPSS_HASH\", \"snapshotDate\": \"$FIXED_TIMESTAMP\", \"optional\": true}"
|
||||
|
||||
if [[ "$INCLUDE_OSV" == "true" ]]; then
|
||||
OSV_HASH=$(sha256sum "$WORK_DIR/providers/osv/snapshot" | cut -d' ' -f1)
|
||||
echo "osv hash: $OSV_HASH"
|
||||
PROVIDERS_JSON="$PROVIDERS_JSON,
|
||||
{\"providerId\": \"osv\", \"digest\": \"sha256:$OSV_HASH\", \"snapshotDate\": \"$FIXED_TIMESTAMP\", \"optional\": true}"
|
||||
fi
|
||||
|
||||
PROVIDERS_JSON="$PROVIDERS_JSON
|
||||
]"
|
||||
|
||||
# Compute inputs hash (hash of all provider hashes sorted)
|
||||
INPUTS_HASH=$(echo -n "$CISA_HASH$EPSS_HASH" | sha256sum | cut -d' ' -f1)
|
||||
echo "inputs hash: $INPUTS_HASH"
|
||||
|
||||
echo ""
|
||||
echo "=== Creating manifest ==="
|
||||
|
||||
# Create provider manifest
|
||||
cat > "$WORK_DIR/manifests/provider-manifest.json" <<EOF
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"bundleId": "$BUNDLE_ID",
|
||||
"createdAt": "$FIXED_TIMESTAMP",
|
||||
"inputsHash": "sha256:$INPUTS_HASH",
|
||||
"providers": $PROVIDERS_JSON
|
||||
}
|
||||
EOF
|
||||
|
||||
MANIFEST_HASH=$(sha256sum "$WORK_DIR/manifests/provider-manifest.json" | cut -d' ' -f1)
|
||||
echo "manifest hash: $MANIFEST_HASH"
|
||||
|
||||
# Create DSSE signature for manifest (using HMAC with test key for fixtures)
|
||||
if [[ "$FIXTURES_ONLY" == "true" ]]; then
|
||||
# Create stub DSSE envelope for fixtures
|
||||
MANIFEST_B64=$(base64 -w0 "$WORK_DIR/manifests/provider-manifest.json" 2>/dev/null || base64 "$WORK_DIR/manifests/provider-manifest.json")
|
||||
cat > "$WORK_DIR/signatures/provider-manifest.dsse" <<EOF
|
||||
{
|
||||
"payloadType": "application/vnd.stellaops.risk-bundle.manifest+json",
|
||||
"payload": "$MANIFEST_B64",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "risk-bundle-hmac-fixtures",
|
||||
"sig": "fixture-signature-for-ci-testing"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Building tar.gz bundle ==="
|
||||
|
||||
# Create the tar archive with deterministic ordering and timestamps
|
||||
cd "$WORK_DIR"
|
||||
|
||||
# Create file list in deterministic order
|
||||
find . -type f | sort > /tmp/bundle-files.txt
|
||||
|
||||
# Create tar with fixed mtime
|
||||
tar --mtime="@$FIXED_EPOCH" \
|
||||
--sort=name \
|
||||
--owner=0 --group=0 \
|
||||
--numeric-owner \
|
||||
-cvf "$OUTPUT_DIR/risk-bundle.tar" \
|
||||
-T /tmp/bundle-files.txt
|
||||
|
||||
# Compress with gzip (deterministic)
|
||||
gzip -n -9 < "$OUTPUT_DIR/risk-bundle.tar" > "$OUTPUT_DIR/risk-bundle.tar.gz"
|
||||
rm "$OUTPUT_DIR/risk-bundle.tar"
|
||||
|
||||
# Copy manifest to output for easy access
|
||||
cp "$WORK_DIR/manifests/provider-manifest.json" "$OUTPUT_DIR/manifest.json"
|
||||
|
||||
# Compute bundle hash
|
||||
BUNDLE_HASH=$(sha256sum "$OUTPUT_DIR/risk-bundle.tar.gz" | cut -d' ' -f1)
|
||||
|
||||
echo ""
|
||||
echo "=== Build complete ==="
|
||||
echo "Bundle: $OUTPUT_DIR/risk-bundle.tar.gz"
|
||||
echo "Bundle hash: $BUNDLE_HASH"
|
||||
echo "Manifest: $OUTPUT_DIR/manifest.json"
|
||||
echo "Manifest hash: $MANIFEST_HASH"
|
||||
|
||||
# Create checksum file
|
||||
echo "$BUNDLE_HASH risk-bundle.tar.gz" > "$OUTPUT_DIR/risk-bundle.tar.gz.sha256"
|
||||
|
||||
echo ""
|
||||
echo "=== Artifacts ==="
|
||||
ls -la "$OUTPUT_DIR"
|
||||
Reference in New Issue
Block a user