up
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

This commit is contained in:
StellaOps Bot
2025-12-14 18:33:02 +02:00
parent d233fa3529
commit 2e70c9fdb6
51 changed files with 5958 additions and 75 deletions

View File

@@ -0,0 +1,73 @@
# AOC Backfill Release Plan (DEVOPS-STORE-AOC-19-005-REL)
Scope: Release/offline-kit packaging for Concelier AOC backfill operations.
## Prerequisites
- Dataset hash from dev rehearsal (AOC-19-005 dev outputs)
- AOC guard tests passing (DEVOPS-AOC-19-001/002/003 - DONE)
- Supersedes rollout plan reviewed (ops/devops/aoc/supersedes-rollout.md)
## Artefacts
- Backfill runner bundle:
- `aoc-backfill-runner.tar.gz` - CLI tool + scripts
- `aoc-backfill-runner.sbom.json` - SPDX SBOM
- `aoc-backfill-runner.dsse.json` - Cosign attestation
- Dataset bundle:
- `aoc-dataset-{hash}.tar.gz` - Seeded dataset
- `aoc-dataset-{hash}.manifest.json` - Manifest with checksums
- `aoc-dataset-{hash}.provenance.json` - SLSA provenance
- Offline kit slice:
- All above + SHA256SUMS + verification scripts
## Packaging Script
```bash
# Production (CI with secrets)
./ops/devops/aoc/package-backfill-release.sh
# Development (dev key)
COSIGN_ALLOW_DEV_KEY=1 COSIGN_PASSWORD=stellaops-dev \
DATASET_HASH=dev-rehearsal-placeholder \
./ops/devops/aoc/package-backfill-release.sh
```
## Pipeline Outline
1) Build backfill runner from `src/Aoc/StellaOps.Aoc.Cli/`
2) Generate SBOM with syft
3) Sign with cosign (dev key fallback)
4) Package dataset (when hash available)
5) Create offline bundle with checksums
6) Verification:
- `stella aoc verify --dry-run`
- `cosign verify-blob` for all bundles
- `sha256sum --check`
7) Publish to release bucket + offline kit
## Runbook
1) Validate AOC guard tests pass in CI
2) Run dev rehearsal with test dataset
3) Capture dataset hash from rehearsal
4) Execute packaging script with production key
5) Verify all signatures and checksums
6) Upload to release bucket
7) Include in offline kit manifest
## CI Workflow
`.gitea/workflows/aoc-backfill-release.yml`
## Verification
```bash
# Verify bundle signatures
cosign verify-blob \
--key tools/cosign/cosign.dev.pub \
--bundle out/aoc/aoc-backfill-runner.dsse.json \
out/aoc/aoc-backfill-runner.tar.gz
# Verify checksums
cd out/aoc && sha256sum -c SHA256SUMS
```
## Owners
- DevOps Guild (pipeline + packaging)
- Concelier Storage Guild (dataset + backfill logic)
- Platform Security (signing policy)

View File

@@ -0,0 +1,175 @@
#!/usr/bin/env bash
# Package AOC backfill release for offline kit
# Usage: ./package-backfill-release.sh
# Dev mode: COSIGN_ALLOW_DEV_KEY=1 COSIGN_PASSWORD=stellaops-dev DATASET_HASH=dev ./package-backfill-release.sh
set -euo pipefail
ROOT=$(cd "$(dirname "$0")/../../.." && pwd)
OUT_DIR="${OUT_DIR:-$ROOT/out/aoc}"
CREATED="${CREATED:-$(date -u +%Y-%m-%dT%H:%M:%SZ)}"
DATASET_HASH="${DATASET_HASH:-}"
mkdir -p "$OUT_DIR"
echo "==> AOC Backfill Release Packaging"
echo " Output: $OUT_DIR"
echo " Dataset hash: ${DATASET_HASH:-<pending>}"
# Key resolution (same pattern as advisory-ai packaging)
resolve_key() {
if [[ -n "${COSIGN_KEY_FILE:-}" && -f "$COSIGN_KEY_FILE" ]]; then
echo "$COSIGN_KEY_FILE"
elif [[ -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 (non-production)" >&2
echo "$ROOT/tools/cosign/cosign.dev.key"
else
echo "[error] No signing key available. Set COSIGN_PRIVATE_KEY_B64 or COSIGN_ALLOW_DEV_KEY=1" >&2
return 1
fi
}
# Build AOC CLI if not already built
AOC_CLI_PROJECT="$ROOT/src/Aoc/StellaOps.Aoc.Cli/StellaOps.Aoc.Cli.csproj"
AOC_CLI_OUT="$OUT_DIR/cli"
if [[ -f "$AOC_CLI_PROJECT" ]]; then
echo "==> Building AOC CLI..."
dotnet publish "$AOC_CLI_PROJECT" \
-c Release \
-o "$AOC_CLI_OUT" \
--no-restore 2>/dev/null || echo "[info] Build skipped (may need restore)"
else
echo "[info] AOC CLI project not found; using placeholder"
mkdir -p "$AOC_CLI_OUT"
echo "AOC CLI placeholder - build from src/Aoc/StellaOps.Aoc.Cli/" > "$AOC_CLI_OUT/README.txt"
fi
# Create backfill runner bundle
echo "==> Creating backfill runner bundle..."
RUNNER_TAR="$OUT_DIR/aoc-backfill-runner.tar.gz"
tar -czf "$RUNNER_TAR" -C "$AOC_CLI_OUT" .
# Compute hash
sha256() {
sha256sum "$1" | awk '{print $1}'
}
RUNNER_HASH=$(sha256 "$RUNNER_TAR")
# Generate manifest
echo "==> Generating manifest..."
MANIFEST="$OUT_DIR/aoc-backfill-runner.manifest.json"
cat > "$MANIFEST" <<EOF
{
"schemaVersion": "1.0.0",
"created": "$CREATED",
"runner": {
"path": "aoc-backfill-runner.tar.gz",
"sha256": "$RUNNER_HASH",
"size": $(stat -c%s "$RUNNER_TAR" 2>/dev/null || stat -f%z "$RUNNER_TAR")
},
"dataset": {
"hash": "${DATASET_HASH:-pending}",
"status": "$( [[ -n "$DATASET_HASH" ]] && echo "available" || echo "pending-dev-rehearsal" )"
},
"signing": {
"mode": "$( [[ "${COSIGN_ALLOW_DEV_KEY:-0}" == "1" ]] && echo "development" || echo "production" )"
}
}
EOF
# Sign with cosign if available
KEY_FILE=$(resolve_key) || true
COSIGN="${COSIGN:-$ROOT/tools/cosign/cosign}"
DSSE_OUT="$OUT_DIR/aoc-backfill-runner.dsse.json"
if [[ -n "${KEY_FILE:-}" ]]; then
COSIGN_CMD="${COSIGN:-cosign}"
if command -v cosign &>/dev/null; then
COSIGN_CMD="cosign"
fi
echo "==> Signing bundle..."
COSIGN_PASSWORD="${COSIGN_PASSWORD:-}" "$COSIGN_CMD" sign-blob \
--key "$KEY_FILE" \
--bundle "$DSSE_OUT" \
--tlog-upload=false \
--yes \
"$RUNNER_TAR" 2>/dev/null || echo "[info] DSSE signing skipped"
fi
# Generate SBOM placeholder
echo "==> Generating SBOM..."
SBOM="$OUT_DIR/aoc-backfill-runner.sbom.json"
cat > "$SBOM" <<EOF
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "aoc-backfill-runner",
"documentNamespace": "https://stella-ops.org/sbom/aoc-backfill-runner/$CREATED",
"creationInfo": {
"created": "$CREATED",
"creators": ["Tool: stellaops-aoc-packager"]
},
"packages": [
{
"name": "StellaOps.Aoc.Cli",
"SPDXID": "SPDXRef-Package-aoc-cli",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false
}
]
}
EOF
# Generate provenance
echo "==> Generating provenance..."
PROVENANCE="$OUT_DIR/aoc-backfill-runner.provenance.json"
cat > "$PROVENANCE" <<EOF
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "aoc-backfill-runner.tar.gz",
"digest": {"sha256": "$RUNNER_HASH"}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://stella-ops.org/aoc-backfill-release/v1",
"internalParameters": {
"created": "$CREATED",
"datasetHash": "${DATASET_HASH:-pending}"
}
},
"runDetails": {
"builder": {"id": "https://stella-ops.org/aoc-backfill-release"}
}
}
}
EOF
# Generate checksums
echo "==> Generating checksums..."
cd "$OUT_DIR"
sha256sum aoc-backfill-runner.tar.gz aoc-backfill-runner.manifest.json aoc-backfill-runner.sbom.json > SHA256SUMS
# Cleanup temp key
[[ -f "$OUT_DIR/.cosign.key" ]] && rm -f "$OUT_DIR/.cosign.key"
echo "==> AOC backfill packaging complete"
echo " Runner: $RUNNER_TAR"
echo " Manifest: $MANIFEST"
echo " SBOM: $SBOM"
echo " Provenance: $PROVENANCE"
echo " Checksums: $OUT_DIR/SHA256SUMS"
[[ -f "$DSSE_OUT" ]] && echo " DSSE: $DSSE_OUT"