File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -9,8 +9,8 @@ This roadmap tracks the progress of the Sandforge Agent Sandbox based on [ARCHIT
99- [x] ** 1.2 Core API Contracts** : Define ` SandboxSpec ` , ` ExecRequest ` , and ` SandboxBackend ` interfaces.
1010- [ ] ** 1.3 Policy Engine** :
1111 - [x] Filesystem path validation (whitelist logic) [ #1 ] ( https://github.com/yanurag-dev/sandforge/issues/1 ) .
12- - [ ] Network mode enforcement (Offline/Fetch/Full) [ #2 ] ( https://github.com/yanurag-dev/sandforge/issues/2 ) .
13- - [ ] Resource limit validation (CPU/Memory/Disk) [ #2 ] ( https://github.com/yanurag-dev/sandforge/issues/2 ) .
12+ - [x ] Network mode enforcement (Offline/Fetch/Full) [ #2 ] ( https://github.com/yanurag-dev/sandforge/issues/2 ) .
13+ - [x ] Resource limit validation (CPU/Memory/Disk) [ #2 ] ( https://github.com/yanurag-dev/sandforge/issues/2 ) .
1414 - [ ] Command family filtering [ #3 ] ( https://github.com/yanurag-dev/sandforge/issues/3 ) .
1515- [ ] ** 1.4 Testing** : Unit tests for policy enforcement.
1616
Original file line number Diff line number Diff line change @@ -9,13 +9,19 @@ import (
99)
1010
1111var (
12- ErrForbiddenHostPath = errors .New ("requested host path is forbidden by policy" )
13- ErrPathNotAbs = errors .New ("host path must be an absolute path" )
12+ ErrForbiddenHostPath = errors .New ("requested host path is forbidden by policy" )
13+ ErrPathNotAbs = errors .New ("host path must be an absolute path" )
14+ ErrResourceLimitExceeded = errors .New ("requested resource exceeds policy limits" )
15+ ErrInvalidNetworkMode = errors .New ("requested network mode is not allowed" )
1416)
1517
1618type Engine struct {
1719 AllowedHostPrefixes []string
1820 BlockedHostPatterns []string
21+ MaxCPU int
22+ MaxMemoryMb int
23+ MaxDiskGb int
24+ AllowedNetworkModes []string
1925}
2026
2127func (e * Engine ) EvaluateMount (mount api.WorkspaceMount ) error {
@@ -59,3 +65,28 @@ func (e *Engine) EvaluateMount(mount api.WorkspaceMount) error {
5965 }
6066 return nil
6167}
68+
69+ func (e * Engine ) EvaluateSandbox (spec api.SandboxSpec ) error {
70+ if spec .CPU > e .MaxCPU {
71+ return ErrResourceLimitExceeded
72+ }
73+ if spec .MemoryMb > e .MaxMemoryMb {
74+ return ErrResourceLimitExceeded
75+ }
76+ if spec .DiskGb > e .MaxDiskGb {
77+ return ErrResourceLimitExceeded
78+ }
79+
80+ allowed := false
81+ for _ , mode := range e .AllowedNetworkModes {
82+ if spec .NetworkMode == mode {
83+ allowed = true
84+ break
85+ }
86+ }
87+
88+ if ! allowed {
89+ return ErrInvalidNetworkMode
90+ }
91+ return nil
92+ }
Original file line number Diff line number Diff line change @@ -115,3 +115,72 @@ func TestEvaluateMount(t *testing.T) {
115115 })
116116 }
117117}
118+
119+ func TestEvaluateSandbox (t * testing.T ) {
120+ engine := & Engine {
121+ MaxCPU : 2 ,
122+ MaxMemoryMb : 2048 ,
123+ MaxDiskGb : 10 ,
124+ AllowedNetworkModes : []string {"offline" , "fetch" },
125+ }
126+
127+ tests := []struct {
128+ name string
129+ spec api.SandboxSpec
130+ wantError error
131+ }{
132+ {
133+ name : "Valid spec" ,
134+ spec : api.SandboxSpec {
135+ CPU : 1 ,
136+ MemoryMb : 1024 ,
137+ DiskGb : 5 ,
138+ NetworkMode : "offline" ,
139+ },
140+ wantError : nil ,
141+ },
142+ {
143+ name : "CPU limit exceeded" ,
144+ spec : api.SandboxSpec {
145+ CPU : 4 ,
146+ },
147+ wantError : ErrResourceLimitExceeded ,
148+ },
149+ {
150+ name : "Memory limit exceeded" ,
151+ spec : api.SandboxSpec {
152+ CPU : 1 ,
153+ MemoryMb : 4096 ,
154+ },
155+ wantError : ErrResourceLimitExceeded ,
156+ },
157+ {
158+ name : "Disk limit exceeded" ,
159+ spec : api.SandboxSpec {
160+ CPU : 1 ,
161+ MemoryMb : 1024 ,
162+ DiskGb : 20 ,
163+ },
164+ wantError : ErrResourceLimitExceeded ,
165+ },
166+ {
167+ name : "Forbidden network mode" ,
168+ spec : api.SandboxSpec {
169+ CPU : 1 ,
170+ MemoryMb : 1024 ,
171+ DiskGb : 5 ,
172+ NetworkMode : "full" ,
173+ },
174+ wantError : ErrInvalidNetworkMode ,
175+ },
176+ }
177+
178+ for _ , tt := range tests {
179+ t .Run (tt .name , func (t * testing.T ) {
180+ err := engine .EvaluateSandbox (tt .spec )
181+ if err != tt .wantError {
182+ t .Errorf ("EvaluateSandbox() error = %v, wantError %v" , err , tt .wantError )
183+ }
184+ })
185+ }
186+ }
You can’t perform that action at this time.
0 commit comments