test: Add policy test

This commit is contained in:
Abhisek Datta
2026-01-09 15:00:24 +05:30
parent 66b9279924
commit e72c1d6324
2 changed files with 96 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
# Sandbox
Design goal for sandbox in PMG context is to protect against unknown supply chain attacks using principles of least privilege.
We do not want to re-invent sandbox and likely rely on OS native sandbox primitives. This is at the cost of developer experience,
where we have to work within the limitations of the sandbox implementations that we use.
## Policy
PMG defines its own policy model. The design goal is simplicity and ease of use. Sandbox implementations are expected to translate
the policy model into their own native policy format. Rules for policy are:
- Deny by default unless explicitly allowed
- Deny rules have higher priority than allow rules
- Policy profile allows binding package managers to a specific sandbox policy
- Package manager must have a sandbox profile when sandbox is enabled
- Package manager specific sandbox profile may be disabled to skip sandbox for the package manager
## Enforcement
The sandbox implementation currently only support `block` mode. This means, any policy violation will block the execution of the
package manager command.
## References
- https://github.com/anthropic-experimental/sandbox-runtime
- https://geminicli.com/docs/cli/sandbox/
- https://github.com/containers/bubblewrap
+69
View File
@@ -1,9 +1,11 @@
package sandbox
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"go.yaml.in/yaml/v3"
)
func TestNewDefaultProfileRegistry(t *testing.T) {
@@ -21,3 +23,70 @@ func TestNewDefaultProfileRegistry(t *testing.T) {
assert.NoError(t, err)
assert.NotNil(t, pypiRestrictive)
}
func TestLoadCustomProfile(t *testing.T) {
cases := []struct {
name string
policy *SandboxPolicy
assert func(t *testing.T, policy *SandboxPolicy, err error)
}{
{
name: "valid policy",
policy: &SandboxPolicy{
Name: "test",
Description: "test",
PackageManagers: []string{"npm"},
// At least some rules are required for a policy to be valid
Filesystem: FilesystemPolicy{
AllowRead: []string{"/tmp"},
AllowWrite: []string{"/tmp"},
DenyRead: []string{"/private/var"},
DenyWrite: []string{"/private/var"},
},
},
assert: func(t *testing.T, policy *SandboxPolicy, err error) {
assert.NoError(t, err)
assert.NotNil(t, policy)
assert.Equal(t, "test", policy.Name)
assert.Equal(t, "test", policy.Description)
assert.Equal(t, []string{"npm"}, policy.PackageManagers)
assert.Equal(t, FilesystemPolicy{
AllowRead: []string{"/tmp"},
AllowWrite: []string{"/tmp"},
DenyRead: []string{"/private/var"},
DenyWrite: []string{"/private/var"},
}, policy.Filesystem)
},
},
{
name: "invalid policy without any rules",
policy: &SandboxPolicy{
Name: "test",
Description: "test",
PackageManagers: []string{"npm"},
},
assert: func(t *testing.T, policy *SandboxPolicy, err error) {
assert.Error(t, err)
assert.Nil(t, policy)
},
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
registry, err := newDefaultProfileRegistry()
assert.NoError(t, err)
assert.NotNil(t, registry)
tempFile, err := os.CreateTemp(t.TempDir(), "sandbox-policy-*.yml")
assert.NoError(t, err)
defer tempFile.Close()
err = yaml.NewEncoder(tempFile).Encode(c.policy)
assert.NoError(t, err)
policy, err := registry.LoadCustomProfile(tempFile.Name())
c.assert(t, policy, err)
})
}
}