Repository navigation
Expand file tree
/
Copy pathbundle.py
More file actions
63 lines (52 loc) · 2.46 KB
/
Copy pathbundle.py
File metadata and controls
63 lines (52 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Assemble the signed evidence bundle for a published number.
Every artifact behind the headline is independently verifiable: the results, the
redacted traces, one offline-verified receipt per blocked attack case, the JWKS
snapshot, each arm's policy config, and a SHA-256 manifest. verify.sh re-runs
verification through @axiorank/audit-verify and the Python verifier, so a reader
trusts the bytes, not us.
"""
from __future__ import annotations
import hashlib
import json
import os
from pathlib import Path
VERIFY_SH = """#!/usr/bin/env bash
# Re-verify every receipt in this bundle offline. No AxioRank account needed.
set -euo pipefail
for r in receipts/*.json; do
npx -y @axiorank/audit-verify "$r" --jwks jwks.json
done
echo "all receipts verified"
"""
def _sha256_file(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def build_bundle(out_dir: str, *, results: dict, receipts: list[dict], jwks: dict,
arm_policies: dict, traces_dir: str | None = None) -> None:
out = Path(out_dir)
(out / "receipts").mkdir(parents=True, exist_ok=True)
(out / "results.json").write_text(json.dumps(results, indent=2))
(out / "jwks.json").write_text(json.dumps(jwks, indent=2))
(out / "arm-policies.json").write_text(json.dumps(arm_policies, indent=2))
for i, r in enumerate(receipts):
(out / "receipts" / f"receipt-{i + 1}.json").write_text(json.dumps(r, indent=2))
if traces_dir and Path(traces_dir).exists():
# Traces are redacted to AgentDojo-public content only before bundling.
(out / "TRACES_NOTE.txt").write_text(f"Redacted traces copied from {traces_dir}\n")
(out / "verify.sh").write_text(VERIFY_SH)
manifest = {
"files": {
str(p.relative_to(out)): _sha256_file(p)
for p in sorted(out.rglob("*"))
if p.is_file() and p.name != "manifest.json"
}
}
(out / "manifest.json").write_text(json.dumps(manifest, indent=2))
print(f"wrote bundle to {out} ({len(manifest['files'])} files)")
if __name__ == "__main__":
out_dir = os.environ.get("BUNDLE_OUT", "bundles/latest")
results = json.load(open("results/results.json"))
receipts = json.load(open("results/verified_receipts.json"))
jwks = json.load(open("results/jwks.json"))
arm_policies = json.load(open("results/arm_policies.json"))
build_bundle(out_dir, results=results, receipts=receipts, jwks=jwks, arm_policies=arm_policies,
traces_dir="traces")