A Go implementation of process sandboxing with network and filesystem restrictions.
Fence wraps commands in a sandbox that blocks network access by default and restricts filesystem operations based on configurable rules. It's most useful for running semi-trusted code (package installs, build scripts, CI jobs, unfamiliar repos) with controlled side effects, and it can also complement AI coding agents as defense-in-depth.
- Network Isolation: All network access blocked by default
- Domain Allowlisting: Configure which domains are allowed
- Filesystem Restrictions: Control read/write access to paths
- Command Blocking: Block dangerous commands (e.g.,
shutdown,rm -rf) with configurable deny/allow lists - Violation Monitoring: Real-time logging of blocked requests and sandbox denials
- Cross-Platform: macOS (sandbox-exec) and Linux (bubblewrap)
- HTTP/SOCKS5 Proxies: Built-in filtering proxies for domain control
You can use Fence as a Go package or CLI tool.
At the moment, we only support macOS and Linux. For Windows users, we recommend using WSL.
curl -fsSL https://raw.githubusercontent.com/Use-Tusk/fence/main/install.sh | shTo install a specific version:
curl -fsSL https://raw.githubusercontent.com/Use-Tusk/fence/main/install.sh | sh -s -- v0.1.0If you have Go installed:
go install github.com/Use-Tusk/fence/cmd/fence@latestBuild from source
git clone https://github.com/Use-Tusk/fence
cd fence
go build -o fence ./cmd/fenceAdditional requirements for Linux:
bubblewrap(for sandboxing)socat(for network bridging)bpftrace(optional, for filesystem violation visibility with when monitoring with-m)
# This will be blocked (no domains allowed by default)
fence curl https://example.com
# Run with shell expansion
fence -c "echo hello && ls"
# Enable debug logging
fence -d curl https://example.comFor a more detailed introduction, see the Quickstart Guide.
fence [flags] -- [command...]
Flags:
-c string Run command string directly (like sh -c)
-d, --debug Enable debug logging (shows sandbox command, proxy activity, filter rules)
-m, --monitor Monitor mode (shows blocked requests and violations only)
-p, --port Expose port for inbound connections (can be repeated)
-s, --settings Path to settings file (default: ~/.fence.json)
-v, --version Show version information
-h, --help Help for fence
# Block all network (default behavior)
fence curl https://example.com
# Output: curl: (56) CONNECT tunnel failed, response 403
# Use a custom config
fence --settings ./my-config.json npm install
# Block specific commands (via config file)
# ~/.fence.json: {"command": {"deny": ["git push", "npm publish"]}}
fence -c "git push" # blocked
fence -c "git status" # allowed
# Run a shell command
fence -c "git clone https://github.com/user/repo && cd repo && npm install"
# Debug mode shows proxy activity
fence -d wget https://example.com
# Monitor mode shows violations/blocked requests only
fence -m npm install
# Expose a port for inbound connections
fence -p 3000 -c "npm run dev"package main
import (
"fmt"
"github.com/Use-Tusk/fence/pkg/fence"
)
func main() {
// Check if platform supports sandboxing (macOS/Linux)
if !fence.IsSupported() {
fmt.Println("Sandboxing not supported on this platform")
return
}
// Create config
cfg := &fence.Config{
Network: fence.NetworkConfig{
AllowedDomains: []string{"api.example.com"},
},
Filesystem: fence.FilesystemConfig{
AllowWrite: []string{"."},
},
Command: fence.CommandConfig{
Deny: []string{"git push", "npm publish"},
},
}
// Create manager (debug=false, monitor=false)
manager := fence.NewManager(cfg, false, false)
defer manager.Cleanup()
// Initialize (starts proxies)
if err := manager.Initialize(); err != nil {
panic(err)
}
// Wrap a command
wrapped, err := manager.WrapCommand("curl https://api.example.com/data")
if err != nil {
panic(err)
}
fmt.Println("Sandboxed command:", wrapped)
}Portions of this project are derived from Anthropic's sandbox-runtime (Apache-2.0). This repository contains modifications and additional original work.