Download tools/render_report.py from Devseis/Arx: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/spaces/Devseis/Arx/resolve/main/tools/render_report.py
- Command line
-
hf download hf://spaces/Devseis/Arx/tools/render_report.py
-
curl -L -o render_report.py https://huggingface.co/spaces/Devseis/Arx/resolve/main/tools/render_report.py
3.89 kB
| #!/usr/bin/env python3 | |
| """Render audit evidence (JSON) as the text report printed by the collectors. | |
| Usage: | |
| python3 tools/render_report.py audit-macos-host-20261007.json | |
| python3 tools/render_report.py synthetic/out/evidence.jsonl --index 3 | |
| Useful for synthetic records (which have no printed report) and for checking that | |
| collector output and evidence stay in sync. Standard library only. | |
| """ | |
| import argparse | |
| import json | |
| from datetime import datetime | |
| LINE = "=" * 60 | |
| SECTIONS = [("baseline", None), ("gdpr", "GDPR TECHNICAL CONTROLS"), ("aiact", "EU AI ACT CONTROLS"), ("org", "ORGANISATIONAL CONTROLS")] | |
| LAYOUT = { | |
| "windows": {"title": "WINDOWS ENDPOINT SECURITY BASELINE - AUDIT", "results": "COMPLIANCE RESULTS", | |
| "end": "END OF READ-ONLY AUDIT", "blank_before_sections": True, | |
| "fields": [("Hostname", "hostname"), ("Operating System", "os_name"), ("OS Version", "os_version"), ("Build", "build"), | |
| ("Serial Number", "serial_number"), ("Execution User", None), ("Audit Date", None), ("Audit Mode", None)]}, | |
| "linux": {"title": "LINUX ENDPOINT SECURITY BASELINE - AUDIT", "results": "LINUX ENDPOINT SECURITY BASELINE - RESULTS", | |
| "end": "END OF LINUX ENDPOINT SECURITY BASELINE AUDIT", "blank_before_sections": False, | |
| "fields": [("Hostname", "hostname"), ("Operating System", "os_name"), ("OS Version", "os_version"), ("Kernel", "kernel"), | |
| ("Serial Number", "serial_number"), ("Execution User", None), ("Audit Date", None), ("Audit Mode", None)]}, | |
| "macos": {"title": "macOS ENDPOINT SECURITY BASELINE - AUDIT", "results": "COMPLIANCE RESULTS", | |
| "end": "END OF AUDIT", "blank_before_sections": False, | |
| "fields": [("Hostname", "hostname"), ("Operating System", "os_name"), ("OS Version", "os_version"), ("Build", "build"), | |
| ("Serial Number", "serial_number"), ("Execution User", None), ("Audit Date", None), ("Audit Mode", None)]}, | |
| } | |
| def audit_date(record, os_family): | |
| started = datetime.fromisoformat(record["audit"]["started_at"]) | |
| text = started.strftime("%Y-%m-%d %H:%M:%S") | |
| # Linux/macOS collectors print the time zone abbreviation, which the ISO offset cannot recover exactly. | |
| return text if os_family == "windows" else f"{text} {record.get('_tz', started.strftime('%z'))}" | |
| def render(record): | |
| os_family = record["host"]["os_family"] | |
| layout = LAYOUT[os_family] | |
| out = [LINE, f" {layout['title']}", LINE] | |
| for label, key in layout["fields"]: | |
| if key: | |
| value = record["host"].get(key, "") | |
| elif label == "Execution User": | |
| value = record["audit"]["execution_user"] | |
| elif label == "Audit Date": | |
| value = audit_date(record, os_family) | |
| else: | |
| value = record["audit"]["mode"] | |
| out.append(f"{label:<16}: {value}") | |
| out.append(LINE) | |
| for section, title in SECTIONS: | |
| if layout["blank_before_sections"]: | |
| out.append("") | |
| out += [LINE, f" {title or layout['results']}", LINE] | |
| for result in record["results"]: | |
| if result["section"] == section: | |
| out += [result["name"], result["status"]] | |
| out += [LINE, f" {layout['end']}", LINE] | |
| return "\n".join(out) | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) | |
| parser.add_argument("path") | |
| parser.add_argument("--index", type=int, default=0, help="record number in a .jsonl file (0-based)") | |
| args = parser.parse_args() | |
| with open(args.path, encoding="utf-8-sig") as handle: | |
| if args.path.endswith(".jsonl"): | |
| record = json.loads(handle.readlines()[args.index]) | |
| else: | |
| record = json.load(handle) | |
| print(render(record)) | |
| if __name__ == "__main__": | |
| main() | |