From 3006d59fd59c31807c85ee29a073b89e6d3cf7dc Mon Sep 17 00:00:00 2001 From: Dzmitry Prychyna Date: Mon, 17 Aug 2026 20:55:29 -0300 Subject: [PATCH] assurance: harden runtime capability boundary --- ...est_alpha4_network_release_architecture.py | 87 ++++++++++++ tools/alpha4_network_expression_airgap.py | 124 +++++++++++++++++- tools/alpha4_network_release_admission.py | 16 ++- .../alpha4_network_triangulated_expression.py | 2 +- 4 files changed, 219 insertions(+), 10 deletions(-) diff --git a/tests/test_alpha4_network_release_architecture.py b/tests/test_alpha4_network_release_architecture.py index 62721c4..e3041fa 100644 --- a/tests/test_alpha4_network_release_architecture.py +++ b/tests/test_alpha4_network_release_architecture.py @@ -249,4 +249,91 @@ def test_network_airgap_executes_generated_companion_under_restricted_runtime( evidence["assurance_dependencies"]["companion_file_access"] == "MATERIALIZED_PROFILE_TREE_READ_ONLY" ) + assert evidence["assurance_dependencies"]["companion_dynamic_builtins"] == "DENIED" + assert evidence["assurance_dependencies"]["companion_filesystem_method_aliasing"] == "DENIED" + assert ( + evidence["assurance_dependencies"]["companion_seed_loader_exec"] + == "EXACT_SEED_BASE_BYTES_ONLY" + ) + assert evidence["assurance_dependencies"]["runtime_capability_isolation"] == "PASS" + assert evidence["assurance_dependencies"]["process_isolation"] == "NOT_CLAIMED" assert evidence["status"] == "PASS" + + +def test_network_airgap_rejects_bound_filesystem_capability_alias() -> None: + import pytest + + from tools.alpha4_network_expression_airgap import ( + NetworkExpressionAirgapError, + _validate_companion_ast, + ) + + source = "from pathlib import Path\nprobe = Path('.').iterdir\n" + with pytest.raises( + NetworkExpressionAirgapError, + match="filesystem inspection forbidden", + ): + _validate_companion_ast( + source, + allowed_imports=frozenset({"pathlib"}), + allow_seed_loader=False, + ) + + +def test_network_airgap_denies_aliased_dynamic_builtin_at_runtime( + tmp_path, +) -> None: + import pytest + + from tools.alpha4_network_expression_airgap import ( + NetworkExpressionAirgapError, + execute, + ) + + subject = tmp_path / "network-subject.py" + subject.write_text( + "capability = getattr\ncapability((), 'missing')\n", + encoding="utf-8", + ) + + with pytest.raises( + NetworkExpressionAirgapError, + match="forbidden runtime capability", + ): + execute( + subject, + tmp_path, + allowed_imports=frozenset(), + allow_seed_loader=False, + ) + + +def test_network_airgap_denies_arbitrary_compile_exec_alias( + tmp_path, +) -> None: + import pytest + + from tools.alpha4_network_expression_airgap import ( + NetworkExpressionAirgapError, + execute, + ) + + subject = tmp_path / "network-compile-subject.py" + subject.write_text( + "compiler = compile\n" + "executor = exec\n" + "code = compiler('VALUE = 1\\n', 'not-seed.py', 'exec')\n" + "executor(code)\n", + encoding="utf-8", + ) + + with pytest.raises( + NetworkExpressionAirgapError, + match="compile path is not exact Seed base", + ): + execute( + subject, + tmp_path, + allowed_imports=frozenset(), + allow_seed_loader=True, + ) diff --git a/tools/alpha4_network_expression_airgap.py b/tools/alpha4_network_expression_airgap.py index 8b75ff8..5b93aa5 100644 --- a/tools/alpha4_network_expression_airgap.py +++ b/tools/alpha4_network_expression_airgap.py @@ -50,6 +50,43 @@ } ) +_FILESYSTEM_MUTATION_METHODS = frozenset( + { + "write_text", + "write_bytes", + "unlink", + "rename", + "replace", + "mkdir", + "touch", + "chmod", + "symlink_to", + "hardlink_to", + } +) + +_DENIED_RUNTIME_BUILTINS = frozenset( + { + "breakpoint", + "copyright", + "credits", + "delattr", + "dir", + "eval", + "exit", + "getattr", + "globals", + "help", + "input", + "license", + "locals", + "quit", + "setattr", + "type", + "vars", + } +) + class NetworkExpressionAirgapError(RuntimeError): pass @@ -106,9 +143,18 @@ def enclosing_function(node: ast.AST) -> str | None: ) elif isinstance(node, ast.Name) and node.id == "__builtins__": raise NetworkExpressionAirgapError("air-gap companion accesses __builtins__") - elif isinstance(node, ast.Attribute) and node.attr.startswith("_"): - raise NetworkExpressionAirgapError( - f"air-gap companion private attribute forbidden: {node.attr}" + elif isinstance(node, ast.Attribute): + if node.attr.startswith("_"): + raise NetworkExpressionAirgapError( + f"air-gap companion private attribute forbidden: {node.attr}" + ) + require( + node.attr not in _FILESYSTEM_INSPECTION_METHODS, + f"air-gap companion filesystem inspection forbidden: {node.attr}", + ) + require( + node.attr not in _FILESYSTEM_MUTATION_METHODS, + f"air-gap companion filesystem mutation forbidden: {node.attr}", ) elif isinstance(node, ast.Call) and isinstance(node.func, ast.Name): if node.func.id in { @@ -223,18 +269,78 @@ def guarded_import( raise ImportError(f"air-gap companion import forbidden: {name}") return original_import(name, globals, locals, fromlist, level) + original_compile = builtins.compile + original_exec = builtins.exec + approved_exec_codes: dict[int, object] = {} + expected_seed_base = ( + allowed_root / "base" / "seed" / "python" / "aset_seed_alpha4.py" + ).resolve() + + def denied(*args: object, **kwargs: object) -> object: + raise NetworkExpressionAirgapError( + "air-gap companion attempted forbidden runtime capability" + ) + + def guarded_compile( + source_value: object, + filename: object, + mode: object, + *args: object, + **kwargs: object, + ) -> object: + require( + allow_seed_loader, + "air-gap companion compile forbidden outside exact Seed base loader", + ) + require( + isinstance(source_value, (str, bytes)) and isinstance(filename, str) and mode == "exec", + "air-gap companion compile permitted only for exact Seed base loader", + ) + candidate = Path(filename).resolve() + require( + candidate == expected_seed_base, + "air-gap companion compile path is not exact Seed base", + ) + with original_io_open(candidate, "rb") as stream: + expected_bytes = stream.read() + actual_bytes = ( + source_value.encode("utf-8") if isinstance(source_value, str) else source_value + ) + require( + actual_bytes == expected_bytes, + "air-gap companion compiled Seed source bytes mismatch", + ) + code = original_compile( + source_value, + filename, + mode, + *args, + **kwargs, + ) + approved_exec_codes[id(code)] = code + return code + safe_builtins = dict(vars(builtins)) + for name in _DENIED_RUNTIME_BUILTINS: + if name in safe_builtins: + safe_builtins[name] = denied safe_builtins["__import__"] = guarded_import safe_builtins["open"] = guarded_open + safe_builtins["compile"] = guarded_compile def guarded_exec( code: object, globals_dict: dict[str, Any] | None = None, locals_dict: dict[str, Any] | None = None, ) -> None: + require( + allow_seed_loader and approved_exec_codes.get(id(code)) is code, + "air-gap companion exec permitted only for exact Seed base code", + ) + approved_exec_codes.pop(id(code), None) target_globals = {} if globals_dict is None else globals_dict - target_globals.setdefault("__builtins__", safe_builtins) - exec(code, target_globals, locals_dict) + target_globals["__builtins__"] = safe_builtins + original_exec(code, target_globals, locals_dict) safe_builtins["exec"] = guarded_exec namespace: dict[str, Any] = { @@ -689,6 +795,11 @@ def check_airgap(profiles_root: Path) -> dict[str, Any]: "triangulated_expression_checker": "NONE", "companion_import_surface": "RESTRICTED", "companion_file_access": "MATERIALIZED_PROFILE_TREE_READ_ONLY", + "companion_dynamic_builtins": "DENIED", + "companion_filesystem_method_aliasing": "DENIED", + "companion_seed_loader_exec": "EXACT_SEED_BASE_BYTES_ONLY", + "runtime_capability_isolation": "PASS", + "process_isolation": "NOT_CLAIMED", }, "profile_tree_digest": before, "inputs": { @@ -750,7 +861,8 @@ def main() -> int: f"{coverage['sensitivity_cases']}/26 PASS" ) print(f"ALPHA4_NETWORK_PYTHON_AIRGAP_GRAND_TOTAL={coverage['grand_total_cases']}/472 PASS") - print("ALPHA4_NETWORK_PYTHON_COMPANION_RUNTIME_ISOLATION=PASS") + print("ALPHA4_NETWORK_PYTHON_COMPANION_RUNTIME_CAPABILITY_ISOLATION=PASS") + print("ALPHA4_NETWORK_PYTHON_COMPANION_PROCESS_ISOLATION=NOT_CLAIMED") print("ALPHA4_NETWORK_PYTHON_SEED_BASE=EXACT") print("ALPHA4_NETWORK_PYTHON_SEMANTIC_SOURCE_DEPENDENCY=NONE") print("ALPHA4_NETWORK_PYTHON_GENERATOR_DEPENDENCY=NONE") diff --git a/tools/alpha4_network_release_admission.py b/tools/alpha4_network_release_admission.py index 73a9eb0..435628b 100644 --- a/tools/alpha4_network_release_admission.py +++ b/tools/alpha4_network_release_admission.py @@ -221,7 +221,12 @@ def check_admission( and dependencies.get("release_profile_generator") == "NONE" and dependencies.get("triangulated_expression_checker") == "NONE" and dependencies.get("companion_import_surface") == "RESTRICTED" - and dependencies.get("companion_file_access") == "MATERIALIZED_PROFILE_TREE_READ_ONLY", + and dependencies.get("companion_file_access") == "MATERIALIZED_PROFILE_TREE_READ_ONLY" + and dependencies.get("companion_dynamic_builtins") == "DENIED" + and dependencies.get("companion_filesystem_method_aliasing") == "DENIED" + and dependencies.get("companion_seed_loader_exec") == "EXACT_SEED_BASE_BYTES_ONLY" + and dependencies.get("runtime_capability_isolation") == "PASS" + and dependencies.get("process_isolation") == "NOT_CLAIMED", "Network Python air-gap independence boundary drift", ) @@ -316,7 +321,11 @@ def check_admission( "structural_cases": coverage["total_cases"], "identity_sensitivity_cases": coverage["sensitivity_cases"], "grand_total_cases": coverage["grand_total_cases"], - "runtime_isolation": "PASS", + "runtime_capability_isolation": "PASS", + "process_isolation": "NOT_CLAIMED", + "dynamic_builtins": "DENIED", + "filesystem_method_aliasing": "DENIED", + "seed_loader_exec": "EXACT_SEED_BASE_BYTES_ONLY", "status": "PASS", }, "public_assurance": { @@ -364,7 +373,8 @@ def main() -> int: print("ALPHA4_NETWORK_RELEASE_ADMISSION_PYTHON_AIRGAP=446/446 PASS") print("ALPHA4_NETWORK_RELEASE_ADMISSION_PYTHON_AIRGAP_IDENTITY_SENSITIVITY=26/26 PASS") print("ALPHA4_NETWORK_RELEASE_ADMISSION_PYTHON_AIRGAP_GRAND_TOTAL=472/472 PASS") - print("ALPHA4_NETWORK_RELEASE_ADMISSION_PYTHON_RUNTIME_ISOLATION=PASS") + print("ALPHA4_NETWORK_RELEASE_ADMISSION_PYTHON_RUNTIME_CAPABILITY_ISOLATION=PASS") + print("ALPHA4_NETWORK_RELEASE_ADMISSION_PYTHON_PROCESS_ISOLATION=NOT_CLAIMED") print("ALPHA4_NETWORK_RELEASE_ADMISSION_ARCHIVE_BINDING=EXACT") print("ALPHA4_NETWORK_PUBLIC_ASSURANCE_REPRESENTATIONS=OPERATIONAL,RELATIONAL,CAUSAL") print("ALPHA4_NETWORK_PUBLIC_POST_BUILD_FORMAL_ASSURANCE=PASS") diff --git a/tools/alpha4_network_triangulated_expression.py b/tools/alpha4_network_triangulated_expression.py index 407c98b..b1c7270 100644 --- a/tools/alpha4_network_triangulated_expression.py +++ b/tools/alpha4_network_triangulated_expression.py @@ -671,7 +671,7 @@ def print_evidence(evidence: dict[str, Any]) -> None: f"{federation_identity_guards}/{federation_identity_guards} PASS" ) print( - "ALPHA4_NETWORK_INTERFACE_VALIDATOR_INDEPENDENCE=" + "ALPHA4_NETWORK_INTERFACE_VALIDATOR_CROSSCHECK=" f"{interface_validator_cases}/{interface_validator_cases} PASS" ) print(