@@ -23,6 +23,7 @@ protects your working directory automatically.
2323| Kernel | Shared | Shared | Separate guest |
2424| Filesystem isolation | Landlock + seccomp COW | Overlay | Block-level |
2525| Network isolation | Landlock + seccomp notif | Network namespace | TAP device |
26+ | HTTP-level ACL | Method + host + path rules | N/A | N/A |
2627| Syscall filtering | seccomp-bpf | seccomp | N/A |
2728| Resource limits | seccomp notif + SIGSTOP | cgroup v2 | VM config |
2829
@@ -102,6 +103,19 @@ sandlock run -m 512M -P 20 -t 30 -- ./compute.sh
102103# Domain-based network isolation
103104sandlock run --net-allow-host api.openai.com -r /usr -r /lib -r /etc -- python3 agent.py
104105
106+ # HTTP-level ACL (method + host + path rules via transparent proxy)
107+ sandlock run \
108+ --http-allow " GET docs.python.org/*" \
109+ --http-allow " POST api.openai.com/v1/chat/completions" \
110+ --http-deny " * */admin/*" \
111+ -r /usr -r /lib -r /etc -- python3 agent.py
112+
113+ # HTTPS MITM with user-provided CA (enables ACL on port 443)
114+ sandlock run \
115+ --http-allow " POST api.openai.com/v1/*" \
116+ --https-ca ca.pem --https-key ca-key.pem \
117+ -r /usr -r /lib -r /etc -- python3 agent.py
118+
105119# TCP port restrictions (Landlock)
106120sandlock run --net-bind 8080 --net-connect 443 -r /usr -r /lib -r /etc -- python3 server.py
107121
@@ -151,6 +165,14 @@ result = Sandbox(policy).run(["python3", "-c", "print('hello')"])
151165assert result.success
152166assert b " hello" in result.stdout
153167
168+ # HTTP ACL: only allow specific API calls
169+ agent_policy = Policy(
170+ fs_readable = [" /usr" , " /lib" , " /etc" ],
171+ http_allow = [" POST api.openai.com/v1/chat/completions" ],
172+ http_deny = [" * */admin/*" ],
173+ )
174+ result = Sandbox(agent_policy).run([" python3" , " agent.py" ])
175+
154176# Confine the current process (Landlock filesystem only, irreversible)
155177confine(Policy(fs_readable = [" /usr" , " /lib" ], fs_writable = [" /tmp" ]))
156178
@@ -259,6 +281,14 @@ let policy = Policy::builder()
259281let result = Sandbox :: run (& policy , & [" echo" , " hello" ]). await ? ;
260282assert! (result . success ());
261283
284+ // HTTP ACL: restrict API access at the HTTP level
285+ let policy = Policy :: builder ()
286+ . fs_read (" /usr" ). fs_read (" /lib" ). fs_read (" /etc" )
287+ . http_allow (" POST api.openai.com/v1/chat/completions" )
288+ . http_deny (" * */admin/*" )
289+ . build ()? ;
290+ let result = Sandbox :: run (& policy , & [" python3" , " agent.py" ]). await ? ;
291+
262292// Confine the current process (Landlock filesystem only, irreversible)
263293let policy = Policy :: builder ()
264294 . fs_read (" /usr" ). fs_read (" /lib" )
@@ -342,7 +372,7 @@ The async notification supervisor (tokio) handles intercepted syscalls:
342372| ---| ---|
343373| ` clone/fork/vfork ` | Process count enforcement |
344374| ` mmap/munmap/brk/mremap ` | Memory limit tracking |
345- | ` connect/sendto/sendmsg ` | IP allowlist + on-behalf execution |
375+ | ` connect/sendto/sendmsg ` | IP allowlist + on-behalf execution + HTTP ACL redirect |
346376| ` bind ` | On-behalf bind + port remapping |
347377| ` openat ` | /proc virtualization, COW interception |
348378| ` unlinkat/mkdirat/renameat2 ` | COW write interception |
@@ -469,6 +499,13 @@ Policy(
469499 net_bind = [8080 ], # TCP bind ports (Landlock ABI v4+)
470500 net_connect = [443 ], # TCP connect ports
471501
502+ # HTTP ACL (transparent proxy)
503+ http_allow = [" POST api.openai.com/v1/*" ], # Allow rules (METHOD host/path)
504+ http_deny = [" * */admin/*" ], # Deny rules (checked first)
505+ http_ports = [80 ], # Ports to intercept (default: [80])
506+ https_ca = " ca.pem" , # CA cert for HTTPS MITM (adds port 443)
507+ https_key = " ca-key.pem" , # CA key for HTTPS MITM
508+
472509 # Socket restrictions
473510 no_raw_sockets = True , # Block SOCK_RAW (default)
474511 no_udp = False , # Block SOCK_DGRAM
0 commit comments