sandbox

package
v0.149.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CapabilityFailureHelp added in v0.145.0

func CapabilityFailureHelp() string

CapabilityFailureHelp describes the platform-specific outer operation that may prevent the sandbox from starting. Callers use it only after reporting the exact failed operation and underlying OS error.

func CheckCapability added in v0.119.0

func CheckCapability() (bool, string)

CheckCapability reports whether the current system can run sandboxed agents. Returns (true, "") if capable, or (false, helpMessage) with fix instructions.

func DenyInit added in v0.9.3

func DenyInit(args []string)

DenyInit is called early in main when the binary is re-exec'd as a sandbox wrapper. It runs as root (UID 0) inside the user namespace so it can:

  1. Mount tmpfs over denied paths to hide their contents
  2. Apply write isolation: make HOME read-only, then bind writable sub-mounts
  3. Install seccomp filter to prevent agent from undoing isolation

After setup, it spawns the agent in a nested user namespace (CLONE_NEWUSER for UID drop) + PID namespace (CLONE_NEWPID for PID isolation). The wrapper itself is NOT in a PID namespace — this keeps host /proc valid so Go can write uid_map for the nested CLONE_NEWUSER without remounting /proc.

Args format: --uid UID --gid GID [--log PATH] [--net-relay-fd FD] [--proxy-port PORT] [--local-port PORT...] [--deny PATH...] [--home PATH] [--writable PATH...] [--mount-ro PATH...] [--overlay-prefix PREFIX...] [--rlimit RESOURCE=VALUE...] -- CMD ARGS...

func ValidateProtectedWriteTargets added in v0.148.0

func ValidateProtectedWriteTargets(targets []string) error

ValidateProtectedWriteTargets checks host-supplied targets syntactically so callers can refuse bad input before spawning anything. It is not enforcement: the platform policy builder re-checks every target against the exact rules it emits.

Types

type Config

type Config struct {
	Mounts       []Mount
	Deny         []string      // paths to mask (e.g. ~/.ssh) — deny read+write
	DenyRename   []string      // pin directory entries without denying writes to descendants
	DenyWrite    []string      // paths to deny writes only (e.g. ./egg.yaml) — read allowed
	NetworkNeed  NetworkNeed   // granular network access required by the agent
	NetworkMode  string        // ""/"enforce" or "observe" for domain decisions
	Domains      []string      // domain allowlist for proxy filtering
	ProxyPort    int           // local domain-filtering proxy port (0 = no proxy)
	LocalPorts   []int         // host loopback ports forwarded into a Linux network namespace
	CPULimit     time.Duration // RLIMIT_CPU (0 = backend default)
	MemLimit     uint64        // RLIMIT_AS in bytes (0 = backend default)
	MaxFDs       uint32        // RLIMIT_NOFILE (0 = backend default)
	PidLimit     uint32        // cgroup pids.max (0 = no limit)
	SessionID    string        // unique ID for cgroup naming
	UserHome     string        // per-user home override (empty = os.UserHomeDir)
	Trace        bool          // wrap command with strace (Linux only)
	AllowSockets []string      // Unix socket paths to allow outbound connections (macOS Seatbelt)
	// ProtectedWriteTargets are host-owned absolute paths (e.g. controller
	// state) that no effective writable rule may reach. The final policy is
	// refused with ProtectedWriteTargetError on any overlap, and backends that
	// cannot verify their final policy refuse a nonempty set. Empty = no contract.
	ProtectedWriteTargets []string

	// RoostPolicyPaths lists configured policy files whose absence must be checked.
	RoostPolicyPaths []string
}

Config holds sandbox creation parameters.

type DomainProxy added in v0.20.0

type DomainProxy struct {
	// contains filtered or unexported fields
}

DomainProxy is an HTTP CONNECT proxy that only allows connections to whitelisted domains.

func StartPolicyProxy added in v0.145.0

func StartPolicyProxy(need NetworkNeed, domains []string) (*DomainProxy, error)

StartPolicyProxy starts the host-side HTTP CONNECT endpoint needed by a network-isolated sandbox. Local-only policies use explicit loopback port forwarding instead. On Linux, NetworkFull keeps the route-less namespace but permits any CONNECT destination through the inherited relay. On macOS it preserves the existing unrestricted Seatbelt network policy.

func StartPolicyProxyWithMode added in v0.145.0

func StartPolicyProxyWithMode(need NetworkNeed, domains []string, mode string) (*DomainProxy, error)

StartPolicyProxyWithMode applies the resolved domain-policy mode. Observe still forces all traffic through the inherited proxy path, but records rather than refuses CONNECT destinations outside the declared domain set.

func StartProxy added in v0.20.0

func StartProxy(domains []string) (*DomainProxy, error)

StartProxy starts an enforcing HTTP CONNECT proxy on localhost with the given domain allowlist. Supports exact domains ("api.anthropic.com") and wildcards ("*.anthropic.com").

func StartProxyWithOptions added in v0.144.0

func StartProxyWithOptions(opts ProxyOptions) (*DomainProxy, error)

StartProxyWithOptions starts a proxy with explicit options.

func (*DomainProxy) Close added in v0.20.0

func (p *DomainProxy) Close()

Close stops the proxy.

func (*DomainProxy) Events added in v0.144.0

func (p *DomainProxy) Events() []EgressEvent

Events returns a copy of the observed outbound connection attempts, oldest first.

func (*DomainProxy) Observing added in v0.144.0

func (p *DomainProxy) Observing() bool

Observing reports whether the proxy logs violations instead of refusing them.

func (*DomainProxy) Port added in v0.20.0

func (p *DomainProxy) Port() int

Port returns the port the proxy is listening on.

func (*DomainProxy) ServeHTTP added in v0.20.0

func (p *DomainProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles HTTP CONNECT requests for the proxy.

type EgressEvent added in v0.144.0

type EgressEvent struct {
	Host    string // as requested, including port
	Matched bool   // matched the domain allowlist
	Blocked bool   // actually refused (false in observe mode even when unmatched)
}

EgressEvent is one observed outbound connection attempt. The proxy is the only component that knows what a sandboxed agent actually contacted, so these are evidence, not just logs.

type EnforcementError added in v0.8.4

type EnforcementError struct {
	Gaps     []string
	Platform string
}

EnforcementError is returned when the system cannot enforce the requested sandbox config.

func (*EnforcementError) Error added in v0.8.4

func (e *EnforcementError) Error() string

type Level

type Level int

Level defines the isolation level for a sandbox.

const (
	Strict     Level = iota // No network, minimal fs, short TTL
	Standard                // No network, mounted dirs only
	Network                 // Network allowed, mounted dirs only
	Privileged              // Full access (for trusted skills)
)

func ParseLevel

func ParseLevel(s string) Level

ParseLevel converts a string to a Level.

func (Level) String

func (l Level) String() string

type Mount

type Mount struct {
	Source   string
	Target   string
	ReadOnly bool
	UseRegex bool // macOS: emit regex rule instead of subpath (covers adjacent files like ~/.claude.json)
}

Mount describes a filesystem mount for the sandbox.

type NetworkNeed added in v0.9.8

type NetworkNeed int

NetworkNeed describes how much network access an agent requires.

const (
	NetworkNone  NetworkNeed = iota // fully isolated
	NetworkLocal                    // explicit host-loopback TCP forwards only
	NetworkHTTPS                    // domain-filtered TCP through HTTP CONNECT
	NetworkFull                     // any destination supported by the platform transport
)

func NetworkNeedFromDomains added in v0.20.0

func NetworkNeedFromDomains(domains []string) NetworkNeed

NetworkNeedFromDomains derives NetworkNeed from a domain list.

func (NetworkNeed) String added in v0.9.8

func (n NetworkNeed) String() string

type ProtectedWriteTargetError added in v0.148.0

type ProtectedWriteTargetError struct {
	Target string // protected target as resolved for the emitted policy ("" when not target-specific)
	Rule   string // exact emitted policy rule that conflicts ("" when not rule-specific)
	Reason string
}

ProtectedWriteTargetError reports that the final sandbox policy cannot keep a host-protected write target unwritable, or that the platform cannot enforce the protected-target contract at all. It is additive to EnforcementError: New returns it unchanged so callers can tell a policy conflict apart from missing OS isolation. It is never produced for an empty protected set.

func (*ProtectedWriteTargetError) Error added in v0.148.0

func (e *ProtectedWriteTargetError) Error() string

type ProxyOptions added in v0.144.0

type ProxyOptions struct {
	Domains []string
	// Observe records what enforce mode would have refused without refusing it.
	// This is the migration path for tightening egress on existing deployments.
	Observe bool
	// MaxConnections bounds simultaneous CONNECT tunnels. Zero uses the safe
	// default; negative values are rejected.
	MaxConnections int
}

ProxyOptions configures a DomainProxy.

type Sandbox

type Sandbox interface {
	Exec(ctx context.Context, name string, args []string) (*exec.Cmd, error)
	PostStart(pid int) error // attach parent-managed resources after process starts
	Destroy() error
	DiagLog() string  // path to sandbox diagnostic log, or ""
	TraceLog() string // path to strace output log, or ""
}

Sandbox provides isolated execution of commands.

func New

func New(cfg Config) (Sandbox, error)

New creates a platform-appropriate sandbox. Returns EnforcementError if the platform cannot enforce the requested isolation — no silent fallback.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL