feat(sandbox): add network_via_proxy_only and allow_direct_dns policy fields (#370)

* feat(sandbox): add network_via_proxy_only and allow_direct_dns policy fields

Config surface for network lockdown: network_via_proxy_only confines a
sandboxed package manager's outbound network to the PMG proxy;
allow_direct_dns is its escape hatch re-opening direct DNS. Both follow
the existing pointer-bool inheritance pattern in MergeWithParent. Lint
warns when allow_direct_dns is set without network_via_proxy_only, where
it has no effect.

The fields are declared and inherited but unread; enforcement lands with
the ExecutionContext plumbing and Seatbelt lockdown translation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PqMU5GNBbQvQct9nxek1VS

* fix(sandbox): deep-copy new pointer flags in profile resolution

expandPolicyPaths re-points the older pointer booleans so callers cannot
corrupt the registry-cached policy; the new NetworkViaProxyOnly and
AllowDirectDNS fields need the same isolation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PqMU5GNBbQvQct9nxek1VS

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Abhisek Datta
2026-07-10 19:28:39 +05:30
committed by GitHub
co-authored by Claude Fable 5
parent e6b5157a2a
commit 22d6eabb6b
6 changed files with 196 additions and 0 deletions
+18
View File
@@ -38,6 +38,16 @@ type SandboxPolicy struct {
// AllowNetworkBind allows binding to localhost (127.0.0.1 / ::1) for listening.
AllowNetworkBind *bool `yaml:"allow_network_bind" json:"allow_network_bind"`
// NetworkViaProxyOnly confines all outbound network access to the PMG
// proxy. Requires the proxy flow; drivers fail closed without a running
// proxy.
NetworkViaProxyOnly *bool `yaml:"network_via_proxy_only" json:"network_via_proxy_only"`
// AllowDirectDNS re-opens direct DNS (mDNSResponder) under
// NetworkViaProxyOnly. No effect otherwise. Default false: the proxy
// resolves names and direct DNS is an exfiltration channel.
AllowDirectDNS *bool `yaml:"allow_direct_dns" json:"allow_direct_dns"`
}
// FilesystemPolicy defines allowed and denied filesystem access patterns.
@@ -162,6 +172,14 @@ func (child *SandboxPolicy) MergeWithParent(parent *SandboxPolicy) {
if child.AllowNetworkBind == nil {
child.AllowNetworkBind = utils.PtrTo(utils.SafelyGetValue(parent.AllowNetworkBind))
}
if child.NetworkViaProxyOnly == nil {
child.NetworkViaProxyOnly = utils.PtrTo(utils.SafelyGetValue(parent.NetworkViaProxyOnly))
}
if child.AllowDirectDNS == nil {
child.AllowDirectDNS = utils.PtrTo(utils.SafelyGetValue(parent.AllowDirectDNS))
}
}
// unionStringSlices returns a new slice containing all unique elements from both slices.