Some checks failed
LNM Migration CI / build-runner (push) Has been cancelled
Ledger OpenAPI CI / deprecation-check (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Airgap Sealed CI Smoke / sealed-smoke (push) Has been cancelled
Ledger Packs CI / build-pack (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Ledger OpenAPI CI / validate-oas (push) Has been cancelled
Ledger OpenAPI CI / check-wellknown (push) Has been cancelled
Ledger Packs CI / verify-pack (push) Has been cancelled
LNM Migration CI / validate-metrics (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
129 lines
3.7 KiB
Bash
129 lines
3.7 KiB
Bash
#!/usr/bin/env bash
|
|
# Build Findings Ledger export pack
|
|
# Usage: ./build-pack.sh [--snapshot-id <id>] [--sign] [--output <dir>]
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT=$(cd "$(dirname "$0")/../../.." && pwd)
|
|
OUT_DIR="${OUT_DIR:-$ROOT/out/ledger/packs}"
|
|
SNAPSHOT_ID="${SNAPSHOT_ID:-$(date +%Y%m%d%H%M%S)}"
|
|
CREATED="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
SIGN=0
|
|
|
|
# Parse args
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--snapshot-id) SNAPSHOT_ID="$2"; shift 2 ;;
|
|
--output) OUT_DIR="$2"; shift 2 ;;
|
|
--sign) SIGN=1; shift ;;
|
|
*) shift ;;
|
|
esac
|
|
done
|
|
|
|
mkdir -p "$OUT_DIR/staging"
|
|
|
|
echo "==> Building Ledger Pack"
|
|
echo " Snapshot ID: $SNAPSHOT_ID"
|
|
echo " Output: $OUT_DIR"
|
|
|
|
# Key resolution for signing
|
|
resolve_key() {
|
|
if [[ -n "${COSIGN_PRIVATE_KEY_B64:-}" ]]; then
|
|
local tmp_key="$OUT_DIR/.cosign.key"
|
|
echo "$COSIGN_PRIVATE_KEY_B64" | base64 -d > "$tmp_key"
|
|
chmod 600 "$tmp_key"
|
|
echo "$tmp_key"
|
|
elif [[ -f "$ROOT/tools/cosign/cosign.key" ]]; then
|
|
echo "$ROOT/tools/cosign/cosign.key"
|
|
elif [[ "${COSIGN_ALLOW_DEV_KEY:-0}" == "1" && -f "$ROOT/tools/cosign/cosign.dev.key" ]]; then
|
|
echo "[info] Using development key" >&2
|
|
echo "$ROOT/tools/cosign/cosign.dev.key"
|
|
else
|
|
echo ""
|
|
fi
|
|
}
|
|
|
|
# Create pack structure
|
|
STAGE="$OUT_DIR/staging/$SNAPSHOT_ID"
|
|
mkdir -p "$STAGE/findings" "$STAGE/metadata" "$STAGE/signatures"
|
|
|
|
# Create placeholder data (replace with actual Ledger export)
|
|
cat > "$STAGE/findings/findings.ndjson" <<EOF
|
|
{"id": "placeholder-1", "type": "infrastructure-ready", "created": "$CREATED"}
|
|
EOF
|
|
|
|
cat > "$STAGE/metadata/snapshot.json" <<EOF
|
|
{
|
|
"snapshotId": "$SNAPSHOT_ID",
|
|
"created": "$CREATED",
|
|
"format": "ledger-pack-v1",
|
|
"status": "infrastructure-ready",
|
|
"note": "Replace with actual Ledger snapshot export"
|
|
}
|
|
EOF
|
|
|
|
# Generate manifest
|
|
sha256() { sha256sum "$1" | awk '{print $1}'; }
|
|
|
|
cat > "$STAGE/manifest.json" <<EOF
|
|
{
|
|
"schemaVersion": "1.0.0",
|
|
"packId": "$SNAPSHOT_ID",
|
|
"created": "$CREATED",
|
|
"format": "ledger-pack-v1",
|
|
"contents": {
|
|
"findings": {"path": "findings/findings.ndjson", "format": "ndjson"},
|
|
"metadata": {"path": "metadata/snapshot.json", "format": "json"}
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Generate provenance
|
|
cat > "$STAGE/provenance.json" <<EOF
|
|
{
|
|
"_type": "https://in-toto.io/Statement/v1",
|
|
"subject": [{"name": "snapshot-$SNAPSHOT_ID.pack.tar.gz", "digest": {"sha256": "pending"}}],
|
|
"predicateType": "https://slsa.dev/provenance/v1",
|
|
"predicate": {
|
|
"buildDefinition": {
|
|
"buildType": "https://stella-ops.org/ledger-pack/v1",
|
|
"internalParameters": {"snapshotId": "$SNAPSHOT_ID", "created": "$CREATED"}
|
|
},
|
|
"runDetails": {"builder": {"id": "https://stella-ops.org/ledger-pack-builder"}}
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Create pack tarball
|
|
PACK_TAR="$OUT_DIR/snapshot-$SNAPSHOT_ID.pack.tar.gz"
|
|
tar -czf "$PACK_TAR" -C "$STAGE" .
|
|
|
|
# Update provenance with actual hash
|
|
PACK_HASH=$(sha256 "$PACK_TAR")
|
|
sed -i "s/\"sha256\": \"pending\"/\"sha256\": \"$PACK_HASH\"/" "$STAGE/provenance.json" 2>/dev/null || \
|
|
sed -i '' "s/\"sha256\": \"pending\"/\"sha256\": \"$PACK_HASH\"/" "$STAGE/provenance.json"
|
|
|
|
# Generate checksums
|
|
cd "$OUT_DIR"
|
|
sha256sum "snapshot-$SNAPSHOT_ID.pack.tar.gz" > "snapshot-$SNAPSHOT_ID.SHA256SUMS"
|
|
|
|
# Sign if requested
|
|
if [[ $SIGN -eq 1 ]]; then
|
|
KEY_FILE=$(resolve_key)
|
|
if [[ -n "$KEY_FILE" ]] && command -v cosign &>/dev/null; then
|
|
echo "==> Signing pack..."
|
|
COSIGN_PASSWORD="${COSIGN_PASSWORD:-}" cosign sign-blob \
|
|
--key "$KEY_FILE" \
|
|
--bundle "$OUT_DIR/snapshot-$SNAPSHOT_ID.dsse.json" \
|
|
--tlog-upload=false --yes "$PACK_TAR" 2>/dev/null || echo "[info] Signing skipped"
|
|
fi
|
|
fi
|
|
|
|
# Cleanup
|
|
rm -rf "$OUT_DIR/staging"
|
|
[[ -f "$OUT_DIR/.cosign.key" ]] && rm -f "$OUT_DIR/.cosign.key"
|
|
|
|
echo "==> Pack build complete"
|
|
echo " Pack: $PACK_TAR"
|
|
echo " Checksums: $OUT_DIR/snapshot-$SNAPSHOT_ID.SHA256SUMS"
|