Align Docker and Prime network policy modes#2124
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 08c9a63641
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| @model_validator(mode="after") | ||
| def _validate_network_policy(self) -> Self: | ||
| if self.allow != ["*"] and self.block: |
There was a problem hiding this comment.
Normalize deny-all before rejecting mixed policies
When a runtime uses the new block = ["*"] framework-only mode and a task also requests framework-only networking with network_allow=[], with_task_network_policy() merges them into allow=[], block=["*"] and this validator raises before the rollout starts, even though the policies are compatible and should be represented as an allowlist. Please normalize or special-case the deny-all wildcard before applying the allow/block mutual-exclusion check.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 860ec75954
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| urlsplit(url)._replace(path="", query="", fragment="").geturl() | ||
| for url in routes | ||
| ] | ||
| deny_all = self.config.block == ["*"] |
There was a problem hiding this comment.
Normalize wildcard blocks before applying Docker policy
When the evaluator config uses block=["*"] and a task adds any network_block, with_task_network_policy() merges them into a list like ["bad.com", "*"]; this exact equality is then false, so Docker leaves * in NetworkPolicy.block. Since the proxy now checks blocks before framework routes, the wildcard blocks the interception/MCP URLs instead of lowering to framework-only access, so those otherwise redundant task block entries make the rollout unable to reach the model or tools.
Useful? React with 👍 / 👎.
ApprovabilityVerdict: Needs human review This PR modifies network policy validation logic that controls sandbox network access. Multiple unresolved review comments identify potential bugs where edge cases could cause rollout failures or framework routes to be incorrectly blocked. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6716d9626
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for host in normalized_hosts: | ||
| with contextlib.suppress(ValueError): | ||
| route_addresses.append(ip_address(host)) |
There was a problem hiding this comment.
Resolve framework hostnames before CIDR deny checks
When a Prime denylist contains a CIDR such as 0.0.0.0/0 or a range covering the tunnel endpoint, this only adds an address when the framework route URL already uses an IP literal. Interception and MCP routes are normally hostnames, so blocked_framework remains false and set_network(deny=...) can block the resolved framework endpoint instead of lowering to the framework-only allowlist promised by this change.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a6716d9. Configure here.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 23e0ab53ae
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Overview
Align Docker and Prime execution-time network policy modes while preserving framework access for explicit framework-only policies.
Details
Empty allowlists and blocklists containing
*normalize to a stable framework-only state. Framework-only access takes precedence during task/runtime composition, so later allow or deny entries cannot widen it.Docker keeps framework routes as privileged proxy routes. Prime uses its normal allowlist path for framework-only and concrete allowlist modes, automatically adding framework hosts. Ordinary Prime denylists are passed through unchanged because the Prime API accepts either allow or deny rules, not exceptions combining both.
Non-empty concrete allowlists and ordinary blocklists remain mutually exclusive. Runtime and task policy documentation describes the shared composition and runtime-specific framework-route behavior.
Note
Medium Risk
Changes validation and merging of egress policies used during agent execution; misconfiguration now fails earlier, and Prime denylist behavior can block framework hosts where Docker would exempt them.
Overview
Centralizes Docker and Prime execution-time egress rules in
NetworkPolicyConfig: emptyallowor anyblockentry containing*normalizes to framework-only (allow=[],block=["*"]), and non-empty concreteallowplusblockare rejected at validation time.Task/runtime merging (
with_task_network_policy) treats framework-only policy as absorbing—either side can force interception/MCP-only access and composition cannot widen past that.Prime skips
validate_egress_listswhen the normalized policy is framework-only; at agent start it deduplicates framework route hostnames and still maps allowlist modes by folding those hosts into the allow list (deny-only configs pass through unchanged, including the possibility of blocking a framework host).Docs and field notes in
evaluation.md,REFERENCE.md, andTaskDatadescribe the shared mutually exclusive modes and the runtime-specific difference (Docker privileged proxy routes vs Prime host-level deny/allow).Reviewed by Cursor Bugbot for commit b7e93ab. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Align Docker and Prime network policy modes with consistent normalization and composition rules
NetworkPolicyConfigin base.py that normalizes framework-only cases (empty allow or'*'in block) toallow=[], block=['*']and enforces mutual exclusivity between non-empty concrete allowlists and blocklists.NetworkPolicyConfig.with_task_network_policyso that if either side is framework-only, the composed result is always framework-only; otherwise allowlists and blocklists are merged.PrimeRuntime.prepare_executionin prime.py to deduplicate route hostnames before validation and align allow/deny policy construction with the normalized model.NetworkPolicyConfiginstances with both a non-empty concrete allowlist and a non-empty blocklist will now raise aValueErrorat instantiation.Macroscope summarized b7e93ab.