L4-5: Multiple disjoint policies -> cross-policy access denied. Policy A: python -> api.anthropic.com:443 Policy B: curl -> example.com:443 Python should NOT reach example.com (that's curl's policy).
(
sandbox: Callable[..., Sandbox],
)
| 525 | |
| 526 | |
| 527 | def test_l4_cross_policy_denied( |
| 528 | sandbox: Callable[..., Sandbox], |
| 529 | ) -> None: |
| 530 | """L4-5: Multiple disjoint policies -> cross-policy access denied. |
| 531 | |
| 532 | Policy A: python -> api.anthropic.com:443 |
| 533 | Policy B: curl -> example.com:443 |
| 534 | Python should NOT reach example.com (that's curl's policy). |
| 535 | """ |
| 536 | policy = _base_policy( |
| 537 | network_policies={ |
| 538 | "anthropic": sandbox_pb2.NetworkPolicyRule( |
| 539 | name="anthropic", |
| 540 | endpoints=[ |
| 541 | sandbox_pb2.NetworkEndpoint(host="api.anthropic.com", port=443), |
| 542 | ], |
| 543 | binaries=[ |
| 544 | sandbox_pb2.NetworkBinary(path="/sandbox/.uv/python/**/python*") |
| 545 | ], |
| 546 | ), |
| 547 | "other": sandbox_pb2.NetworkPolicyRule( |
| 548 | name="other", |
| 549 | endpoints=[ |
| 550 | sandbox_pb2.NetworkEndpoint(host="example.com", port=443), |
| 551 | ], |
| 552 | binaries=[sandbox_pb2.NetworkBinary(path="/usr/bin/curl")], |
| 553 | ), |
| 554 | }, |
| 555 | ) |
| 556 | spec = datamodel_pb2.SandboxSpec(policy=policy) |
| 557 | with sandbox(spec=spec, delete_on_exit=True) as sb: |
| 558 | # Python -> its own policy endpoint: allowed |
| 559 | result = sb.exec_python(_proxy_connect(), args=("api.anthropic.com", 443)) |
| 560 | assert result.exit_code == 0, result.stderr |
| 561 | assert "200" in result.stdout |
| 562 | |
| 563 | # Python -> curl's policy endpoint: denied |
| 564 | result = sb.exec_python(_proxy_connect(), args=("example.com", 443)) |
| 565 | assert result.exit_code == 0, result.stderr |
| 566 | assert "403" in result.stdout |
| 567 | |
| 568 | |
| 569 | def test_l4_non_connect_method_rejected( |
nothing calls this directly
no test coverage detected