Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Console CI / console-ci (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
VEX Proof Bundles / verify-bundles (push) Has been cancelled
- Introduced sample proof bundle configuration files for testing, including `sample-proof-bundle-config.dsse.json`, `sample-proof-bundle.dsse.json`, and `sample-proof-bundle.json`. - Implemented a verification script `test_verify_sample.sh` to validate proof bundles against specified schemas and catalogs. - Updated existing proof bundle configurations with new metadata, including versioning, created timestamps, and justification details. - Enhanced evidence entries with expiration dates and hashes for better integrity checks. - Ensured all new configurations adhere to the defined schema for consistency and reliability in testing.
100 lines
3.2 KiB
Bash
100 lines
3.2 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Offline verifier for Export Center bundles (EC10)
|
|
# Usage: VERIFY_FIXTURE=1 ./verify-export-kit.sh [kit_dir]
|
|
|
|
kit_dir="${1:-src/ExportCenter/__fixtures/export-kit}"
|
|
|
|
for f in manifest.json manifest.sha256 provenance.json manifest.dsse; do
|
|
if [[ ! -f "${kit_dir}/${f}" ]]; then
|
|
echo "missing ${kit_dir}/${f}" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
manifest_sha="$(sha256sum "${kit_dir}/manifest.json" | awk '{print $1}')"
|
|
expected_sha="$(awk '{print $1}' "${kit_dir}/manifest.sha256")"
|
|
|
|
if [[ "${manifest_sha}" != "${expected_sha}" ]]; then
|
|
echo "manifest hash mismatch: expected ${expected_sha} got ${manifest_sha}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
python - <<'PY' "${kit_dir}" "${manifest_sha}"
|
|
import base64, hashlib, json, sys, pathlib
|
|
|
|
kit = pathlib.Path(sys.argv[1])
|
|
manifest_sha = sys.argv[2]
|
|
manifest = json.loads(kit.joinpath("manifest.json").read_text())
|
|
|
|
errors = []
|
|
selectors = manifest.get("selectors", {})
|
|
tenants = selectors.get("tenants", [])
|
|
tenant = manifest.get("tenant")
|
|
|
|
if tenant and tenants and tenant not in tenants and "*" not in tenants[0]:
|
|
errors.append(f"tenant {tenant} not included in selectors.tenants {tenants}")
|
|
|
|
digests = []
|
|
for item in manifest.get("contents", []):
|
|
digest = item.get("digest", "")
|
|
if not digest.startswith("sha256:"):
|
|
errors.append(f"invalid digest format for {item.get('path')}")
|
|
continue
|
|
digests.append(digest.split("sha256:")[1])
|
|
|
|
rerun_calc = hashlib.sha256("\n".join(sorted(digests)).encode()).hexdigest()
|
|
rerun_expected = manifest.get("rerunHash")
|
|
if rerun_expected != f"sha256:{rerun_calc}":
|
|
errors.append(f"rerunHash mismatch: expected sha256:{rerun_calc} got {rerun_expected}")
|
|
|
|
annotations = manifest["integrity"]["oci"]["annotations"]
|
|
manifest_digest_hex = annotations["io.stellaops.export.manifest-digest"].split("sha256:")[1]
|
|
digest_hdr = manifest["integrity"]["httpHeaders"]["Digest"]
|
|
expected_hdr = "sha-256=" + base64.b64encode(bytes.fromhex(manifest_digest_hex)).decode()
|
|
if digest_hdr != expected_hdr:
|
|
errors.append("Digest header does not match manifest digest annotation")
|
|
|
|
log_meta = manifest.get("attestations", {}).get("log")
|
|
if not log_meta:
|
|
errors.append("attestation log metadata missing")
|
|
|
|
if not manifest.get("quotas"):
|
|
errors.append("quotas/backpressure block missing")
|
|
|
|
if len(set(tenants)) > 1 and not manifest.get("approval", {}).get("required"):
|
|
errors.append("cross-tenant approval required but not present")
|
|
|
|
if errors:
|
|
for err in errors:
|
|
print(err)
|
|
sys.exit(1)
|
|
|
|
print("manifest checks ok")
|
|
PY
|
|
|
|
python - <<'PY' "${kit_dir}" "${manifest_sha}"
|
|
import json, sys, pathlib
|
|
|
|
kit = pathlib.Path(sys.argv[1])
|
|
manifest_sha = sys.argv[2]
|
|
prov = json.loads(kit.joinpath("provenance.json").read_text())
|
|
|
|
manifest_subject = prov["subject"][0]["digest"]["sha256"]
|
|
if manifest_subject != manifest_sha:
|
|
print(f"provenance manifest digest mismatch: {manifest_subject} vs {manifest_sha}")
|
|
sys.exit(1)
|
|
|
|
log = prov["predicate"]["environment"]["logs"]
|
|
required = ["kind", "logId", "logIndex", "entryDigest", "timestamp"]
|
|
missing = [k for k in required if k not in log]
|
|
if missing:
|
|
print(f"provenance log metadata missing keys: {missing}")
|
|
sys.exit(1)
|
|
|
|
print("provenance checks ok")
|
|
PY
|
|
|
|
echo "verify-export-kit: PASS"
|