from __future__ import annotations import json import shutil import subprocess import sys from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[1] CANARY = ROOT / "scripts" / "run_leo_negative_permissions_canary.py" @pytest.mark.skipif(shutil.which("docker") is None, reason="Docker is required") def test_leo_negative_permissions_canary_runs_real_postgres_lifecycle(tmp_path: Path) -> None: output = tmp_path / "negative-permissions.json" completed = subprocess.run( [sys.executable, str(CANARY), "--output", str(output)], cwd=ROOT, text=True, capture_output=True, check=False, timeout=120, ) assert completed.returncode == 0, completed.stderr or completed.stdout receipt = json.loads(output.read_text(encoding="utf-8")) assert receipt["passed"] is True assert receipt["current_tier"] == "T2_runtime" assert receipt["identity_policy"] == { "exact_handle_required": True, "participant_handle": "m3taversal", "reviewer_handle": "m3taversal", } assert receipt["scope"] == { "canonical_production_rows_contacted": False, "container_network": "none", "database": "teleo_canonical", "principal": "sa-observatory-read-adapter@teleo-501523.iam", "production_contacted": False, } assert receipt["summary"] == { "allowed_expected": 3, "allowed_passed": 3, "denied_expected": 16, "denied_passed": 16, } operations = {operation["id"]: operation for operation in receipt["operations"]} assert set(operations) == { "session_read_only_defaults", "canonical_retrieval", "proposal_ledger_retrieval", "canonical_insert_default_read_only", "canonical_insert_acl_after_read_only_override", "canonical_update_acl_after_read_only_override", "canonical_delete_acl_after_read_only_override", "canonical_truncate_acl_after_read_only_override", "staging_insert_acl_after_read_only_override", "fake_approval_gate_call", "apply_assert_gate_call", "apply_finish_gate_call", "protected_schema_ddl_after_read_only_override", "outside_allowlist_retrieval", "create_role_escalation", "grant_apply_role_escalation", "set_apply_role_escalation", "alter_role_createdb_escalation", "claim_table_ownership_escalation", } assert all(operation["passed"] for operation in operations.values()) assert receipt["fingerprint"]["before"]["participant_handle"] == "m3taversal" assert receipt["fingerprint"]["after"]["participant_handle"] == "m3taversal" assert receipt["fingerprint"]["unchanged"] is True assert receipt["fingerprint"]["before_sha256"] == receipt["fingerprint"]["after_sha256"] assert receipt["cleanup"]["passed"] is True assert receipt["cleanup"]["exact_name_orphans"] == [] assert receipt["cleanup"]["label_scoped_orphans"] == [] assert receipt["cleanup"]["temporary_workdir_exists"] is False