#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """Exercise the fail-closed artifact execution policy gate.""" from __future__ import annotations import argparse import hashlib import json import subprocess import sys import tempfile from pathlib import Path BLOCKED_SHA256 = "4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63" def run(command: list[str], expected_decision: str) -> dict[str, object]: result = subprocess.run(command, check=False, capture_output=True, text=True) line = result.stdout.strip().splitlines()[-1] document = json.loads(line) if document.get("decision") != expected_decision: raise RuntimeError(f"unexpected decision: {document}") if expected_decision == "DENY" and result.returncode == 0: raise RuntimeError("denied input returned success") if expected_decision != "DENY" and result.returncode != 0: raise RuntimeError(f"eligible input failed: {result.stderr}") if document.get("execution_authorized") is not False: raise RuntimeError("policy gate must never grant execution authority") return document def without_option(command: list[str], option: str) -> list[str]: index = command.index(option) return command[:index] + command[index + 2 :] def write_manifest(path: Path, artifact: Path, eligible: bool) -> str: source_commit = "1" * 40 path.write_text( json.dumps( { "artifact": { "filename": artifact.name, "id": "execution-policy-test", "sha256": hashlib.sha256(artifact.read_bytes()).hexdigest(), "size": artifact.stat().st_size, "target": "test", "version": "1", }, "execution": { "authorized": False, "executed": False, "execution_eligible": eligible, "transferred": False, }, "schema_version": 1, "source": { "commit": source_commit, "dirty": False, "repository": "private-gitea-test", }, }, indent=2, sort_keys=True, ) + "\n", encoding="utf-8", ) return source_commit def write_runtime_profile( path: Path, artifact: Path, source_commit: str, *, decision: str = "READY_FOR_HARDENED_RUNTIME_DEPLOYMENT", firmware: str = "9.60", effect: str = "PAYLOAD_PROCESS_LOCAL", ) -> None: path.write_text( json.dumps( { "artifact": { "built": True, "filename": artifact.name, "id": "execution-policy-test", "sha256": hashlib.sha256(artifact.read_bytes()).hexdigest(), "size": artifact.stat().st_size, "source_commit": source_commit, }, "budgets": { "automatic_retry": False, "filesystem_write_budget": "controlled_artifact_directory_only", "maximum_runtime_ms": 2000, "payload_network_access": "none", "persistent_write_budget": "controlled_artifact_removable", }, "decision": decision, "deployment": { "installed": False, "ready_for_installation": True, "rollback_prepared": True, }, "effects": [{"classification": effect, "id": "test_effect"}], "execution_authorized": False, "expected_volatile_effects": ( ["test_effect"] if effect == "EXPECTED_VOLATILE_RUNTIME_EFFECT" else [] ), "execution": { "authorized": False, "executed": False, "execution_eligible": True, "transferred": False, }, "firmware": { "device_attested": False, "evidence": "jens_explicitly_confirmed_exact_9.60", "exact": firmware, }, "hard_blockers": [], "payload_manager": { "base_commit": "cfbc70f30f419b09bf2b52283f7409e2d3117ee1", "hardened_commit": "e23d94ff91233aa770e2342800c1467875bdef44", "installed": False, "release": "v0.3.1-chimera-controlled-phase07", "reproducible": True, "sha256": ( "8fecf8241a46246eddbd21e8bb4d875f5d76f1f4f4c6a11384df1f131aa5e5b1" ), "size": 99560, }, "loader": { "base_commit": "699e8bcff03e91e8d6ca6eba281af25c5a58d8c2", "hardened_commit": "197623058f509eddde18868dafcb92fdcac66464", "installed": False, "release": "v0.23-chimera-phase07", "reproducible": True, "sha256": ( "63e810982471eb40cae3a20aa9df9a0a02892f420e429874fae4e99aa400b561" ), "size": 397000, }, "profile": "controlled-ps5-runtime", "schema_version": 1, "sdk": { "commit": "d2e2e585740362976a39fdd5ccf390f199a7bc37", "release": "v0.41", }, }, indent=2, sort_keys=True, ) + "\n", encoding="utf-8", ) def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--root", type=Path, required=True) args = parser.parse_args() root = args.root.resolve() denylist_path = root / "manifests/artifact-denylist.json" denylist = json.loads(denylist_path.read_text(encoding="utf-8")) if [entry["sha256"] for entry in denylist["entries"]] != [BLOCKED_SHA256]: raise RuntimeError("permanent denylist hash changed or is absent") with tempfile.TemporaryDirectory() as directory: temporary = Path(directory) artifact = temporary / "test.elf" artifact.write_bytes(b"chimera-execution-policy-test\n") manifest = temporary / "manifest.json" runtime_profile = temporary / "runtime-profile.json" command = [ sys.executable, str(root / "tools/check_artifact_execution_policy.py"), "--manifest", str(manifest), "--denylist", str(denylist_path), "--artifact", str(artifact), "--runtime-profile", str(runtime_profile), "--firmware", "9.60", ] source_commit = write_manifest(manifest, artifact, eligible=False) write_runtime_profile( runtime_profile, artifact, source_commit, decision="BLOCKED_VERSION_OR_UNBOUNDED_EFFECT", ) denied = run(command, "DENY") if "MANIFEST_EXECUTION_INELIGIBLE" not in denied["reason_codes"]: raise RuntimeError("execution-ineligible manifest was not refused") source_commit = write_manifest(manifest, artifact, eligible=True) write_runtime_profile(runtime_profile, artifact, source_commit) run(command, "PASS_STATIC_DEPLOYMENT_ELIGIBILITY_GATE") no_artifact = without_option(command, "--artifact") denied = run(no_artifact, "DENY") if "ARTIFACT_BYTES_NOT_SUPPLIED" not in denied["reason_codes"]: raise RuntimeError("missing artifact bytes did not fail closed") no_profile = without_option(command, "--runtime-profile") denied = run(no_profile, "DENY") if "CONTROLLED_RUNTIME_PROFILE_REQUIRED" not in denied["reason_codes"]: raise RuntimeError("missing controlled runtime profile did not fail closed") write_runtime_profile( runtime_profile, artifact, source_commit, effect="UNBOUNDED_OR_UNKNOWN", ) denied = run(command, "DENY") if "RUNTIME_PROFILE_HARD_EFFECT" not in denied["reason_codes"]: raise RuntimeError("unbounded runtime effect did not fail closed") write_runtime_profile(runtime_profile, artifact, source_commit) document = json.loads(runtime_profile.read_text(encoding="utf-8")) document["expected_volatile_effects"] = ["not_the_classified_effect"] runtime_profile.write_text(json.dumps(document), encoding="utf-8") denied = run(command, "DENY") if ( "RUNTIME_PROFILE_VOLATILE_EFFECTS_MISMATCH" not in denied["reason_codes"] ): raise RuntimeError("volatile-effect mismatch did not fail closed") write_runtime_profile(runtime_profile, artifact, source_commit) document = json.loads(runtime_profile.read_text(encoding="utf-8")) del document["expected_volatile_effects"] runtime_profile.write_text(json.dumps(document), encoding="utf-8") denied = run(command, "DENY") if denied["reason_codes"] != ["INVALID_OR_INCOMPLETE_POLICY_INPUT"]: raise RuntimeError("missing volatile-effect declaration did not fail closed") write_runtime_profile(runtime_profile, artifact, source_commit) document = json.loads(runtime_profile.read_text(encoding="utf-8")) document["execution_authorized"] = True runtime_profile.write_text(json.dumps(document), encoding="utf-8") denied = run(command, "DENY") if ( "RUNTIME_PROFILE_EXECUTION_STATE_INVALID" not in denied["reason_codes"] ): raise RuntimeError("runtime authorization widening did not fail closed") write_runtime_profile(runtime_profile, artifact, source_commit) document = json.loads(runtime_profile.read_text(encoding="utf-8")) document["payload_manager"]["hardened_commit"] = "0" * 40 runtime_profile.write_text(json.dumps(document), encoding="utf-8") denied = run(command, "DENY") if "PAYLOAD_MANAGER_IDENTITY_MISMATCH" not in denied["reason_codes"]: raise RuntimeError("Payload Manager identity mismatch did not fail closed") write_runtime_profile( runtime_profile, artifact, source_commit, effect="NOT_A_CLASSIFICATION", ) denied = run(command, "DENY") if denied["reason_codes"] != ["INVALID_OR_INCOMPLETE_POLICY_INPUT"]: raise RuntimeError("unknown effect classification did not fail closed") write_runtime_profile(runtime_profile, artifact, source_commit) document = json.loads(runtime_profile.read_text(encoding="utf-8")) document["profile"] = "controlled-ps5-lifecycle-v1" runtime_profile.write_text(json.dumps(document), encoding="utf-8") denied = run(command, "DENY") if denied["reason_codes"] != ["INVALID_OR_INCOMPLETE_POLICY_INPUT"]: raise RuntimeError("wrong runtime profile name did not fail closed") write_runtime_profile(runtime_profile, artifact, source_commit) document = json.loads(manifest.read_text(encoding="utf-8")) document["execution"]["transferred"] = True manifest.write_text(json.dumps(document), encoding="utf-8") denied = run(command, "DENY") if "MANIFEST_EXECUTION_STATE_INVALID" not in denied["reason_codes"]: raise RuntimeError("manifest transfer claim did not fail closed") source_commit = write_manifest(manifest, artifact, eligible=True) write_runtime_profile(runtime_profile, artifact, source_commit) mismatched_firmware = command.copy() mismatched_firmware[-1] = "9.40" denied = run(mismatched_firmware, "DENY") if "FIRMWARE_MISMATCH" not in denied["reason_codes"]: raise RuntimeError("firmware mismatch did not fail closed") document = json.loads(manifest.read_text(encoding="utf-8")) document["artifact"]["sha256"] = BLOCKED_SHA256 manifest.write_text(json.dumps(document), encoding="utf-8") denied = run(no_artifact, "DENY") if "ARTIFACT_PERMANENTLY_DENYLISTED" not in denied["reason_codes"]: raise RuntimeError("denylisted hash was not refused") del document["execution"]["execution_eligible"] manifest.write_text(json.dumps(document), encoding="utf-8") denied = run(no_artifact, "DENY") if denied["reason_codes"] != ["INVALID_OR_INCOMPLETE_POLICY_INPUT"]: raise RuntimeError("missing eligibility did not fail closed") artifact.write_bytes(b"changed\n") source_commit = write_manifest(manifest, artifact, eligible=True) write_runtime_profile(runtime_profile, artifact, source_commit) artifact.write_bytes(b"changed-again\n") denied = run(command, "DENY") if "ARTIFACT_DIGEST_MISMATCH" not in denied["reason_codes"]: raise RuntimeError("changed bytes were not refused") print("artifact execution policy gate passed all refusal tests") return 0 if __name__ == "__main__": raise SystemExit(main())