from __future__ import annotations import json import os import tempfile import unittest from datetime import datetime, timedelta, timezone from pathlib import Path from unittest import mock import aios_isolated_writer_policy as writer_policy import isolated_writer_path_policy as path_policy from isolated_writer_authz import AuthorizationError, _validate_grant TARGET = "deploy/systemd/aios-codex-review-test-worker.service" BRANCH = "patch/codex-review-test-worker-20260724" AUDIENCE = "aios-codex-review-worker-writer.service" VALID_UNIT = """\ [Unit] Description=AIOS Codex Review/Test Worker After=network-online.target Wants=network-online.target [Service] Type=simple User=aiman Group=gitops WorkingDirectory=/usr/libexec/aios-codex-review-test-worker/current Environment=AIOS_CODEX_WORKER_MODE=shadow Environment=AIOS_TASK_PLANE_EXECUTION_ENABLED=false Environment=PYTHONDONTWRITEBYTECODE=1 ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test Restart=on-failure RestartSec=2 NoNewPrivileges=true PrivateTmp=true PrivateDevices=true ProtectSystem=strict ProtectHome=true ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true LockPersonality=true RestrictSUIDSGID=true RestrictRealtime=true MemoryDenyWriteExecute=true RuntimeDirectory=aios-codex-review-test-worker StateDirectory=aios-codex-review-test-worker CacheDirectory=aios-codex-review-test-worker ReadOnlyPaths=/data/aios-gitops/repo.git ReadOnlyPaths=/usr/libexec/aios-codex-review-test-worker ReadWritePaths=/run/aios-codex-review-test-worker ReadWritePaths=/var/lib/aios-codex-review-test-worker ReadWritePaths=/var/cache/aios-codex-review-test-worker UMask=0077 [Install] WantedBy=multi-user.target """ def document(*, paths=None, **updates): value = { "schema_version": 1, "policy_id": "codex-review-worker-path-policy-v1", "audience": AUDIENCE, "repository_identity": "aios/aios", "allowed_branch": BRANCH, "allowed_operations": { "commit_file.atomic": { "exact_paths": paths or [TARGET], "max_content_bytes": 32768, "content_profile": "systemd-codex-review-worker-v1", } }, } value.update(updates) return value class ExactPathPolicyTests(unittest.TestCase): def setUp(self): self.saved = dict(os.environ) self.temp = tempfile.TemporaryDirectory() self.root = Path(self.temp.name) self.policy_dir = self.root / "policies" self.policy_dir.mkdir(mode=0o750) self.policy_file = self.policy_dir / "writer.json" self.workspace = self.root / "workspace" self.workspace.mkdir(mode=0o700) os.environ.update( { "AIOS_GITOPS_ISOLATED_WRITER_ENFORCEMENT": "required", "AIOS_GITOPS_SERVICE_AUDIENCE": AUDIENCE, "AIOS_GITOPS_REPOSITORY_IDENTITY": "aios/aios", "AIOS_GITOPS_ALLOWED_BRANCH": BRANCH, } ) def tearDown(self): path_policy.clear_path_policy_cache() os.environ.clear() os.environ.update(self.saved) self.temp.cleanup() def write_policy(self, value=None): payload = document() if value is None else value raw = ( json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n" ) self.policy_file.write_text(raw, encoding="utf-8") self.policy_file.chmod(0o640) return path_policy.load_path_policy( self.policy_file, expected_owner_uid=os.getuid(), expected_group_gid=os.getgid(), ) def configured(self, loaded): return mock.patch.object( path_policy, "configured_path_policy", return_value=loaded, ) def test_exact_systemd_path_and_exact_token_path_are_allowed(self): loaded = self.write_policy() with self.configured(loaded): self.assertEqual(TARGET, writer_policy.validate_path(TARGET, self.workspace)) writer_policy.validate_content_for_path(TARGET, VALID_UNIT) def test_token_path_cannot_expand_service_policy(self): loaded = self.write_policy(document(paths=["deploy/systemd/other.service"])) with self.configured(loaded), self.assertRaisesRegex( PermissionError, "isolated_writer_service_path_rejected" ): writer_policy.validate_path(TARGET, self.workspace) def test_service_policy_cannot_expand_token_path(self): now = datetime.now(timezone.utc) grant = { "schema_version": 2, "audience": AUDIENCE, "source_cidrs": ["127.0.0.1/32"], "created_at": (now - timedelta(seconds=5)).isoformat(), "not_before": (now - timedelta(seconds=2)).isoformat(), "expires_at": (now + timedelta(minutes=5)).isoformat(), "revoked": False, "allowed_operations": ["commit_file.atomic"], "allowed_branch": BRANCH, "allowed_paths": ["deploy/systemd/other.service"], "approved_base_oid": "a" * 40, } with mock.patch( "isolated_writer_authz._git_is_ancestor", return_value=True ), self.assertRaisesRegex(AuthorizationError, "writer_token_path_rejected"): _validate_grant( grant, audience=AUDIENCE, source_ip="127.0.0.1", operation="commit_file.atomic", branch=BRANCH, path=TARGET, workspace=self.workspace, current_time=now, ) def test_other_service_file_is_rejected(self): loaded = self.write_policy() with self.configured(loaded), self.assertRaisesRegex( PermissionError, "isolated_writer_service_path_rejected" ): writer_policy.validate_path( "deploy/systemd/other.service", self.workspace ) def test_path_traversal_is_rejected(self): for value in ("deploy/systemd/../x", "../deploy/systemd/x"): with self.subTest(value=value), self.assertRaises(PermissionError): writer_policy.validate_path(value, self.workspace) def test_url_encoded_traversal_is_rejected(self): with self.assertRaises(PermissionError): writer_policy.validate_path( "deploy/systemd/%2e%2e/x", self.workspace ) def test_symlink_policy_file_is_rejected(self): self.write_policy() link = self.policy_dir / "link.json" link.symlink_to(self.policy_file) with self.assertRaisesRegex( path_policy.PathPolicyError, "isolated_writer_path_policy_symlink_rejected" ): path_policy.load_path_policy( link, expected_owner_uid=os.getuid(), expected_group_gid=os.getgid(), ) def test_world_writable_policy_file_is_rejected(self): self.write_policy() self.policy_file.chmod(0o646) with self.assertRaisesRegex( path_policy.PathPolicyError, "isolated_writer_path_policy_permissions_rejected", ): path_policy.load_path_policy( self.policy_file, expected_owner_uid=os.getuid(), expected_group_gid=os.getgid(), ) def test_unknown_policy_field_is_rejected(self): value = document() value["unexpected"] = True with self.assertRaisesRegex( path_policy.PathPolicyError, "isolated_writer_path_policy_fields_rejected", ): self.write_policy(value) def test_audience_mismatch_is_rejected(self): loaded = self.write_policy() os.environ["AIOS_GITOPS_PATH_POLICY_FILE"] = str(self.policy_file) os.environ["AIOS_GITOPS_SERVICE_AUDIENCE"] = "other.service" path_policy.clear_path_policy_cache() with mock.patch.object( path_policy, "load_path_policy", return_value=loaded ), self.assertRaisesRegex( path_policy.PathPolicyError, "isolated_writer_path_policy_audience_rejected", ): path_policy.configured_path_policy() def test_branch_mismatch_is_rejected(self): loaded = self.write_policy() os.environ["AIOS_GITOPS_PATH_POLICY_FILE"] = str(self.policy_file) os.environ["AIOS_GITOPS_ALLOWED_BRANCH"] = "patch/other" path_policy.clear_path_policy_cache() with mock.patch.object( path_policy, "load_path_policy", return_value=loaded ), self.assertRaisesRegex( path_policy.PathPolicyError, "isolated_writer_path_policy_branch_rejected", ): path_policy.configured_path_policy() def assert_profile_rejected(self, content): loaded = self.write_policy() with self.configured(loaded), self.assertRaisesRegex( PermissionError, "isolated_writer_systemd_profile_rejected" ): writer_policy.validate_content_for_path(TARGET, content) def test_disallowed_execution_and_credential_directives_are_rejected(self): directives = ( "ExecStartPre=/usr/bin/id", "ExecStartPost=/usr/bin/id", "ExecReload=/usr/bin/id", "ExecStop=/usr/bin/id", "ExecStopPost=/usr/bin/id", "ExecCondition=/usr/bin/true", "EnvironmentFile=/run/worker.env", "PassEnvironment=PATH", "LoadCredential=worker:/run/worker", "SetCredential=worker:value", "ImportCredential=worker", "StandardInput=socket", "StandardOutput=socket", ) for directive in directives: with self.subTest(directive=directive): self.assert_profile_rejected( VALID_UNIT.replace( "Restart=on-failure", f"Restart=on-failure\n{directive}", ) ) def test_disallowed_namespace_and_capability_directives_are_rejected(self): directives = ( "RootDirectory=/srv/worker", "RootImage=/srv/worker.raw", "ReadWritePaths=/", "BindPaths=/etc:/etc", "BindReadOnlyPaths=/etc:/etc", "TemporaryFileSystem=/etc", "CapabilityBoundingSet=CAP_SYS_ADMIN", "AmbientCapabilities=CAP_SYS_ADMIN", "DeviceAllow=/dev/sda rw", "SupplementaryGroups=docker", "Sockets=unsafe.socket", ) for directive in directives: with self.subTest(directive=directive): self.assert_profile_rejected( VALID_UNIT.replace( "Restart=on-failure", f"Restart=on-failure\n{directive}", ) ) def test_duplicate_single_directives_and_sections_are_rejected(self): bad_values = ( VALID_UNIT.replace("User=aiman", "User=aiman\nUser=aiman"), VALID_UNIT.replace( "ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test", "ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test\n" "ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test", ), VALID_UNIT + "\n[Service]\nType=simple\n", ) for value in bad_values: with self.subTest(value=value): self.assert_profile_rejected(value) def test_empty_reset_continuation_crlf_nul_and_long_lines_are_rejected(self): bad_values = ( VALID_UNIT.replace( "ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test", "ExecStart=", ), VALID_UNIT.replace( "Restart=on-failure", "Restart=on-failure\n continuation-injection", ), VALID_UNIT.replace("\n", "\r\n"), VALID_UNIT.replace("Restart=on-failure", "Restart=on-failure\x00"), VALID_UNIT.replace( "Description=AIOS Codex Review/Test Worker", "Description=" + ("A" * 4097), ), ) for value in bad_values: with self.subTest(kind=repr(value[:80])): self.assert_profile_rejected(value) def test_unknown_environment_and_production_execution_are_rejected(self): bad_values = ( VALID_UNIT.replace( "Environment=PYTHONDONTWRITEBYTECODE=1", "Environment=UNKNOWN_KEY=value", ), VALID_UNIT.replace( "AIOS_TASK_PLANE_EXECUTION_ENABLED=false", "AIOS_TASK_PLANE_EXECUTION_ENABLED=true", ), VALID_UNIT.replace( "Environment=PYTHONDONTWRITEBYTECODE=1", "Environment=Authorization: Bearer placeholder", ), ) for value in bad_values: with self.subTest(value=value): self.assert_profile_rejected(value) def test_identity_working_directory_and_path_prefix_bypasses_are_rejected(self): bad_values = ( VALID_UNIT.replace("User=aiman", "User=root"), VALID_UNIT.replace( "/usr/libexec/aios-codex-review-test-worker/current", "/data/aios-gitops/worktrees/worker", ), VALID_UNIT.replace( "ReadWritePaths=/run/aios-codex-review-test-worker", "ReadWritePaths=/etc", ), VALID_UNIT.replace( "ReadOnlyPaths=/data/aios-gitops/repo.git", "ReadOnlyPaths=/data", ), ) for value in bad_values: with self.subTest(value=value): self.assert_profile_rejected(value) def test_unknown_section_directive_and_unicode_lookalike_are_rejected(self): bad_values = ( VALID_UNIT.replace("[Install]", "[Socket]"), VALID_UNIT.replace( "Restart=on-failure", "Restart=on-failure\nProtectClock=true", ), VALID_UNIT.replace("ExecStart=", "\u0415xecStart="), ) for value in bad_values: with self.subTest(value=value): self.assert_profile_rejected(value) def test_invalid_unicode_surrogate_and_missing_final_newline_are_rejected(self): for value in (VALID_UNIT + "\ud800", VALID_UNIT.rstrip("\n")): with self.subTest(value=repr(value[-30:])): self.assert_profile_rejected(value) def test_writer_request_cannot_modify_policy_file(self): with self.assertRaises(PermissionError): writer_policy.validate_path( "etc/aios-gitops/writer-path-policies/codex-review-worker.json", self.workspace, ) def test_coarse_file_and_commit_endpoints_remain_forbidden(self): for endpoint in ("/api/file", "/api/commit"): with self.subTest(endpoint=endpoint), self.assertRaisesRegex( PermissionError, "isolated_writer_operation_forbidden" ): writer_policy.validate_endpoint( "POST", endpoint, self.workspace, self.root ) if __name__ == "__main__": unittest.main()