Documentation
¶
Overview ¶
Package arapuca provides Go bindings for the arapuca process sandbox library via cgo. It wraps the C API to provide idiomatic Go types for sandboxed subprocess management.
Arapuca enforces OS-level isolation (Landlock, seccomp BPF, cgroups v2, network namespaces on Linux; sandbox-exec on macOS) on untrusted subprocesses.
Thread safety: arapuca_last_error() uses thread-local storage. All cgo call sequences that check errors use runtime.LockOSThread() to prevent Go's goroutine scheduler from moving the goroutine to a different OS thread between the call and the error check.
Index ¶
- func DiskUsageMB(path string) uint64
- func EnableSelfExecMode()
- func ImagePull(_, _ string) (string, error)
- func LandlockABIVersion() int
- func MakeSocketDir() (string, error)
- func MakeTmpDir(taskID string) (string, error)
- func MicroVmAvailable() bool
- func NetNSAvailable() bool
- func WrapperPath() string
- type AllowedHost
- type Config
- type MicroVmIsolation
- type Process
- type Profile
- type ResourceUsage
- type Sandbox
- type SeccompProfileKind
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DiskUsageMB ¶
DiskUsageMB returns the disk usage of a directory in MB.
func EnableSelfExecMode ¶ added in v0.2.1
func EnableSelfExecMode()
EnableSelfExecMode configures the library to use the current executable as the sandbox wrapper binary, eliminating the need for a separate arapuca binary. Must be called before any call to Launch; if called after, only subsequent launches are affected.
func LandlockABIVersion ¶
func LandlockABIVersion() int
LandlockABIVersion probes the kernel's Landlock ABI version. Returns 0 if Landlock is unavailable.
func MakeSocketDir ¶
MakeSocketDir creates a temporary directory with mode 0700 and a random suffix for per-agent Unix sockets. The caller is responsible for removing the directory when done.
func MakeTmpDir ¶
MakeTmpDir creates a temporary directory for the given task with a random suffix. The caller is responsible for removing it.
func MicroVmAvailable ¶ added in v0.2.0
func MicroVmAvailable() bool
MicroVmAvailable always returns false without the microvm build tag.
func NetNSAvailable ¶
func NetNSAvailable() bool
NetNSAvailable probes whether network namespace isolation works.
func WrapperPath ¶
func WrapperPath() string
WrapperPath returns the path to the arapuca binary, or empty string if not found.
Types ¶
type AllowedHost ¶ added in v0.2.3
type AllowedHost struct {
Host string // Exact hostname or ".suffix" for wildcard matching.
Port uint16 // TCP port (1-65535).
}
AllowedHost specifies an outbound host:port that the CONNECT proxy will allow connections to from inside the network namespace sandbox. Use a leading dot in Host for suffix matching (e.g. ".googleapis.com" matches any subdomain). Port must be 1-65535.
When AllowedHosts is non-empty on Config, the library automatically enables UseNetNS and forks a CONNECT proxy that permits only the listed destinations.
type Config ¶
type Config struct {
Profile Profile
SocketDir string // Per-agent socket directory.
TaskID string // Task identifier.
Phase string // Current phase (opaque to arapuca).
WorkDir string // Working directory (empty = inherit).
Stdin *os.File // Redirect stdin (nil = inherit).
Stdout *os.File // Redirect stdout (nil = inherit).
Stderr *os.File // Redirect stderr (nil = inherit).
NetworkProxySocket string // Path to network proxy Unix socket.
AllowedHosts []AllowedHost // Outbound allowlist for CONNECT proxy.
Env map[string]string // Caller-supplied env vars for subprocess.
}
Config holds the full configuration for launching a sandboxed process.
type MicroVmIsolation ¶ added in v0.2.0
type MicroVmIsolation struct {
Distro string // Distro name (e.g. "fedora", "centos"). Mutually exclusive with ImagePath.
Version string // Distro version (e.g. "42", "9"). Mutually exclusive with ImagePath.
ImagePath string // Explicit qcow2 path. Mutually exclusive with Distro/Version.
CPUs uint32 // Number of vCPUs (must be > 0).
MemMB uint32 // Memory in MB (must be > 0).
}
MicroVmIsolation configures micro-VM isolation via libkrun. Set either Distro+Version or ImagePath, not both. Requires building with -tags microvm against a microvm-enabled libarapuca.a (make install INSTALL_FEATURES=microvm).
type Process ¶
type Process struct {
// contains filtered or unexported fields
}
Process represents a running sandboxed subprocess.
func (*Process) Cleanup ¶
func (p *Process) Cleanup()
Cleanup releases the subprocess's resources (temp directory, cgroup). Must only be called after Wait() returns. Safe to call multiple times.
func (*Process) OOMCount ¶
OOMCount reads the OOM kill count from the subprocess's cgroup. Must be called before Cleanup().
func (*Process) ResourceStats ¶
func (p *Process) ResourceStats() ResourceUsage
ResourceStats reads resource usage from the subprocess's cgroup. Must be called before Cleanup(). Returns zero values if cgroups are unavailable.
type Profile ¶
type Profile struct {
ReadPaths []string // Allowed read-only paths.
WritePaths []string // Allowed read-write paths.
MaxMemoryMB uint64 // Memory limit in MB (0 = no limit).
MaxCPUPct uint32 // CPU percentage (0 = no limit; 200 = 2 cores).
MaxPIDs uint32 // Max processes (0 = no limit).
MaxFileSizeMB uint64 // Max file size in MB (0 = no limit).
MaxOpenFiles uint64 // Max open file descriptors (0 = no limit, RLIMIT_NOFILE).
AllowExec bool // Allow execve on binaries in read AND write paths. Required for shebang scripts (e.g. Python handlers). Caution: with WritePaths, this creates a write-then-exec surface.
CgroupBestEffort bool // When true, launch without cgroup limits if controllers aren't delegated (applies rlimit fallbacks). When false (default), missing controllers cause a hard failure.
UseNetNS bool // Use network namespace isolation.
UsePidNS bool // Use PID namespace isolation (process appears as PID 1).
DnsCapture bool // Capture DNS queries as audit events (requires UseNetNS).
SeccompProfile SeccompProfileKind // Seccomp profile: SeccompProfileDefault (strict), SeccompProfileStrict, or SeccompProfileBaseline (for Bun/Claude Code).
Isolation *MicroVmIsolation // Micro-VM isolation (nil = process-level sandbox).
}
Profile defines the restrictions applied to a sandboxed subprocess.
type ResourceUsage ¶
type ResourceUsage struct {
MemoryCurrentBytes int64
MemoryPeakBytes int64
CPUUsageSeconds float64
PIDCount int64
IOReadBytes int64
IOWriteBytes int64
}
ResourceUsage holds cgroup v2 resource usage statistics.
type Sandbox ¶
type Sandbox struct {
// contains filtered or unexported fields
}
Sandbox wraps the arapuca sandbox handle. It is the entry point for launching sandboxed subprocesses. Create with New().
func (*Sandbox) CgroupsAvailable ¶
CgroupsAvailable reports whether cgroups v2 resource limits are available on this system.
func (*Sandbox) Close ¶
func (s *Sandbox) Close()
Close releases the sandbox handle. Safe to call multiple times.
func (*Sandbox) Launch ¶
func (s *Sandbox) Launch(ctx context.Context, cfg Config, cmd string, args []string, extraFiles []*os.File) (*Process, error)
Launch starts a sandboxed subprocess. The subprocess is isolated according to the Config's Profile. Extra file descriptors in extraFiles are inherited by the subprocess at FD positions 3, 4, ...
The returned Process must be waited on and cleaned up.
Context cancellation: if ctx is cancelled, the subprocess is killed via SIGKILL to the process group.
type SeccompProfileKind ¶ added in v0.2.2
type SeccompProfileKind string
SeccompProfileKind is the seccomp enforcement level for the sandbox.
const ( // SeccompProfileDefault uses the library default (currently Strict). SeccompProfileDefault SeccompProfileKind = "" // SeccompProfileStrict blocks AF_INET/AF_INET6, memfd_create, io_uring, // and other advanced syscalls. Suitable for untrusted code. SeccompProfileStrict SeccompProfileKind = "strict" // SeccompProfileBaseline blocks only sandbox-escape syscalls (ptrace, // mount, namespace ops, kernel modules, bpf). Suitable for // trusted-but-isolated applications such as Claude Code (Bun runtime) // that need full POSIX syscall access. Relies on Landlock + netns for // actual confinement. SeccompProfileBaseline SeccompProfileKind = "baseline" )