import datetime as dt import json import os import tempfile import unittest from agent_egress_guard import AgentPolicy, Guard, PolicyError, policy_template from agent_egress_guard.cli import main TODAY = dt.date(2026, 10, 1) class FakeProvider: def __init__(self, table): self.table = table def lookup(self, host): h = host[4:] if host.startswith("www.") else host return self.table.get(h, {"found": False, "page_types": {}}) DB = { "vendor.example": {"found": True, "page_types": { "pricing": "https://vendor.example/pricing", "careers": "https://vendor.example/jobs", "signup": "https://vendor.example/start-trial", "checkout": "https://vendor.example/buy", "documentation": "https://vendor.example/docs"}}, "supplier.example": {"found": True, "page_types": {"checkout": "https://supplier.example/checkout"}}, } def pol(**web): base = {"agent": "research", "owner": "ops", "tier": 3, "review_by": "2027-01-01", "web": {"allow_page_types": ["pricing", "documentation"], "unclassified": "deny"}} base["web"].update(web) return AgentPolicy(base) class Policy(unittest.TestCase): def setUp(self): self.g = Guard(page_types=FakeProvider(DB)) def d(self, p, url, method="GET"): return p.check(self.g, url, method, today=TODAY) def test_allowed_read_type(self): v = self.d(pol(), "https://vendor.example/pricing") self.assertEqual(v.decision, "allow") self.assertEqual(v.extra.get("agent"), "research") def test_read_type_not_on_allow_list(self): v = self.d(pol(), "https://vendor.example/jobs") self.assertEqual((v.decision, v.rule), ("deny", "page_type_not_allowed")) def test_action_type_stays_denied(self): self.assertEqual(self.d(pol(), "https://vendor.example/start-trial").decision, "deny") def test_ask_owner(self): v = self.d(pol(on_deny="ask_owner"), "https://vendor.example/buy") self.assertEqual(v.decision, "approval_required") def test_high_value_host_never_routed_to_owner(self): v = self.d(pol(on_deny="ask_owner"), "http://169.254.169.254/latest/meta-data/") self.assertEqual(v.decision, "deny") def test_exception_with_approval(self): p = pol(exceptions=[{"page_type": "checkout", "domain": "supplier.example", "expires": "2027-03-31", "requires_approval": True}]) self.assertEqual(self.d(p, "https://supplier.example/checkout").decision, "approval_required") self.assertEqual(self.d(p, "https://vendor.example/buy").decision, "deny") def test_exception_without_approval(self): p = pol(exceptions=[{"page_type": "checkout", "domain": "supplier.example", "expires": "2027-03-31"}]) v = self.d(p, "https://supplier.example/checkout") self.assertEqual((v.decision, v.rule), ("allow", "exception")) def test_expired_exception_ignored(self): p = pol(exceptions=[{"page_type": "checkout", "domain": "supplier.example", "expires": "2026-01-01"}]) self.assertEqual(self.d(p, "https://supplier.example/checkout").decision, "deny") self.assertTrue(any("expired" in w for w in p.validate(TODAY))) def test_unclassified_denied(self): v = self.d(pol(), "https://unknown.example/some/page") self.assertEqual((v.decision, v.rule), ("deny", "unclassified")) def test_unclassified_allowed_domain(self): v = self.d(pol(allow_domains=["unknown.example"]), "https://www.unknown.example/page") self.assertEqual(v.decision, "allow") def test_unclassified_allow_reads(self): v = self.d(pol(unclassified="allow_reads"), "https://unknown.example/page") self.assertEqual(v.decision, "allow") def test_deny_domain_beats_everything(self): v = self.d(pol(deny_domains=["vendor.example"]), "https://vendor.example/pricing") self.assertEqual((v.decision, v.rule), ("deny", "deny_domain")) def test_deny_read_type(self): v = self.d(pol(allow_page_types=[], deny_page_types=["careers"]), "https://vendor.example/jobs") self.assertEqual((v.decision, v.rule), ("deny", "deny_page_type")) def test_invalid_policies(self): for web in ({"unclassified": "maybe"}, {"allow_page_types": ["nonsense"]}, {"allow_page_types": ["checkout"]}, {"on_deny": "shrug"}, {"exceptions": [{"page_type": "checkout"}]}): with self.assertRaises(PolicyError): pol(**web) def test_warnings(self): p = AgentPolicy({"web": {}, "tier": 4}) w = " ".join(p.validate(TODAY)) self.assertIn("no owner", w) self.assertIn("review_by", w) self.assertIn("tier 4", w) def test_template_is_valid(self): p = AgentPolicy(policy_template("a", "b", 3)) self.assertEqual([i for i in p.validate() if i.startswith("error")], []) self.assertEqual(p.unclassified, "deny") def test_cli(self): with tempfile.TemporaryDirectory() as t: f = os.path.join(t, "p.json") with open(f, "w") as fh: json.dump(policy_template("cli-agent", "me", 3), fh) self.assertEqual(main(["policy", "validate", f]), 0) self.assertEqual(main(["policy", "check", f, "https://example.com/login", "-X", "POST"]), 2) bad = os.path.join(t, "bad.json") with open(bad, "w") as fh: fh.write("{not json") self.assertEqual(main(["policy", "validate", bad]), 2) if __name__ == "__main__": unittest.main()