#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "$0")" && pwd)" MODULE_ROOT="${ROOT}/.." cd "$MODULE_ROOT" export MODULE_ROOT command -v sha256sum >/dev/null || { echo "sha256sum required" >&2; exit 1; } command -v python >/dev/null || { echo "python required" >&2; exit 1; } sha256sum --check SHA256SUMS python - <<'PY' import base64, json, os, sys from pathlib import Path try: from cryptography.hazmat.primitives.asymmetric import ed25519 except Exception as exc: raise SystemExit(f"cryptography package required for DSSE verification: {exc}") root = Path(os.environ['MODULE_ROOT']).resolve() pub_b64 = (root / "kit" / "ed25519.pub").read_text().strip() pub = base64.urlsafe_b64decode(pub_b64 + "==") verifier = ed25519.Ed25519PublicKey.from_public_bytes(pub) def pae(payload_type: bytes, payload: bytes) -> bytes: parts = [b"DSSEv1", str(len(payload_type)).encode(), payload_type, str(len(payload)).encode(), payload] return b" ".join(parts) def verify(name: str, payload_path: Path, envelope_path: Path, payload_type: str): payload = payload_path.read_bytes() envelope = json.loads(envelope_path.read_text()) if envelope.get("payloadType") != payload_type: raise SystemExit(f"{name}: payloadType mismatch ({envelope.get('payloadType')} != {payload_type})") if not envelope.get("signatures"): raise SystemExit(f"{name}: missing signatures") sig_entry = envelope["signatures"][0] sig = base64.urlsafe_b64decode(sig_entry["sig"] + "==") decoded_payload = base64.urlsafe_b64decode(envelope["payload"] + "==") if decoded_payload != payload: raise SystemExit(f"{name}: payload body mismatch vs envelope") verifier.verify(sig, pae(payload_type.encode(), payload)) print(f"OK: {name}") targets = [ ("observer schema", root / "schemas" / "observer_event.schema.json", root / "schemas" / "observer_event.schema.json.dsse", "application/vnd.stellaops.zastava.schema+json;name=observer_event;version=1"), ("webhook schema", root / "schemas" / "webhook_admission.schema.json", root / "schemas" / "webhook_admission.schema.json.dsse", "application/vnd.stellaops.zastava.schema+json;name=webhook_admission;version=1"), ("thresholds", root / "thresholds.yaml", root / "thresholds.yaml.dsse", "application/vnd.stellaops.zastava.thresholds+yaml;version=1"), ("observer exports", root / "exports" / "observer_events.ndjson", root / "exports" / "observer_events.ndjson.dsse", "application/vnd.stellaops.zastava.observer-events+ndjson;version=1"), ("webhook exports", root / "exports" / "webhook_admissions.ndjson", root / "exports" / "webhook_admissions.ndjson.dsse", "application/vnd.stellaops.zastava.webhook-admissions+ndjson;version=1"), ] # Combined runtime format (optional - may not exist in all kits) combined_targets = [ ("combined runtime", root / "exports" / "combined.runtime.ndjson", root / "exports" / "combined.runtime.ndjson.dsse", "application/vnd.stellaops.combined.runtime+ndjson;version=1"), ] for name, payload_path, envelope_path, ptype in targets: verify(name, payload_path, envelope_path, ptype) # Verify combined format if present for name, payload_path, envelope_path, ptype in combined_targets: if payload_path.exists() and envelope_path.exists(): verify(name, payload_path, envelope_path, ptype) elif payload_path.exists() or envelope_path.exists(): print(f"WARNING: {name} - incomplete (payload and envelope must both exist)") else: print(f"SKIP: {name} (not present)") PY echo "OK: SHA256 + DSSE signatures verified"