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
+50
View File
@@ -3,7 +3,9 @@ package sandbox
import (
"testing"
"github.com/safedep/dry/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// cleanPolicy returns a minimally-valid policy with no lint issues.
@@ -230,3 +232,51 @@ func TestLintProfile_OrderingErrorsBeforeWarnsBeforeInfo(t *testing.T) {
}
}
}
func TestLintProfile_AllowDirectDNSWithoutLockdown(t *testing.T) {
tests := []struct {
name string
allowDirectDNS *bool
networkViaProxyOnly *bool
wantWarn bool
}{
{
name: "allow_direct_dns without lockdown warns",
allowDirectDNS: utils.PtrTo(true),
wantWarn: true,
},
{
name: "allow_direct_dns with lockdown is clean",
allowDirectDNS: utils.PtrTo(true),
networkViaProxyOnly: utils.PtrTo(true),
wantWarn: false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
policy := cleanPolicy()
policy.AllowDirectDNS = tc.allowDirectDNS
policy.NetworkViaProxyOnly = tc.networkViaProxyOnly
var found *LintIssue
for _, i := range LintProfile(policy) {
if i.Code == "allow-direct-dns-without-lockdown" {
issue := i
found = &issue
break
}
}
if !tc.wantWarn {
assert.Nil(t, found)
return
}
require.NotNil(t, found)
assert.Equal(t, LintLevelWarn, found.Level)
assert.Equal(t, "allow_direct_dns", found.Field)
assert.Equal(t, "allow_direct_dns has no effect unless network_via_proxy_only is true", found.Message)
})
}
}