Documentation
¶
Overview ¶
Package sandbox confines external plugin subprocesses. The gateway treats plugins as untrusted (they will eventually be fetched from a registry), so every plugin runs inside an OS sandbox that hides the gateway's secrets (state DB, WireGuard/Tailscale keys, the user's home directory) and, unless granted, the network.
Backends:
- linux: user+mount+pid(+net) namespaces with a deny-by-default mount tree (ModeNamespaces); Landlock when user namespaces are unavailable (ModeLandlock, degraded).
- darwin: seatbelt via sandbox-exec (ModeSeatbelt).
- other: none; plugins require an explicit sandbox = "off".
The linux backends re-exec /proc/self/exe to set the sandbox up in the child before exec'ing the plugin binary. Host binaries that spawn plugins MUST call Stage1 as the first statement of main() (test packages: from TestMain) — Command and Probe fail fast if the hook was never wired, instead of hanging the go-plugin handshake.
Index ¶
Constants ¶
const ( EnvBackend = "CLAWPATROL_SANDBOX_BACKEND" EnvStage1 = "CLAWPATROL_SANDBOX_STAGE1" EnvSpec = "CLAWPATROL_SANDBOX_SPEC" )
Env var names. EnvBackend forces a specific backend (tests, CI). EnvStage1 and EnvSpec drive the linux re-exec child and must never leak into the plugin's environment (stage-1 strips them).
Variables ¶
This section is empty.
Functions ¶
func BaseEnv ¶
BaseEnv is the minimal environment every plugin gets, sandboxed or not. Nothing from the gateway's own environment (secrets, CLAWPATROL_*, cloud credentials) is inherited; go-plugin's ClientConfig.SkipHostEnv must be set by the spawner.
func Command ¶
Command builds the wrapper *exec.Cmd that launches spec's plugin under mode. It sets cmd.Env (BaseEnv plus any backend control vars); go-plugin appends its handshake vars to it. It never touches Stdin/Stdout/Stderr — go-plugin owns those pipes.
func Stage1 ¶
func Stage1()
Stage1 is the env-gated re-exec entry point. Host binaries that spawn plugins must call it as the first statement of main() (test packages: from TestMain). In the parent it only records that the hook is wired. In the re-exec'd child (CLAWPATROL_SANDBOX_STAGE1 set) it sets the sandbox up and execs the plugin binary — it never returns. Setup failures print one "clawpatrol-sandbox:" line on stderr (stdout stays clean for the go-plugin handshake) and exit 87.
Types ¶
type Availability ¶
type Availability struct {
// Mode is the best working backend. Never ModeOff: when nothing
// works Probe returns an error instead.
Mode Mode
// Warning is non-empty when Mode is a degraded fallback; it
// spells out exactly what the fallback does not cover.
Warning string
// LandlockABI is the kernel's Landlock ABI version on linux
// (0 when unsupported). ABI >= 4 adds TCP bind/connect rules.
LandlockABI int
}
Availability is the result of probing this host for a backend.
func Probe ¶
func Probe() (Availability, error)
Probe detects the best available sandbox backend on this host. The result is cached per CLAWPATROL_SANDBOX_BACKEND value. A forced backend that fails its own probe is an error (it does not fall through to another backend).
type Mode ¶
type Mode string
Mode identifies a sandbox backend.
const ( // ModeOff runs the plugin unsandboxed (explicit operator opt-out). // Environment scrubbing still applies. ModeOff Mode = "off" // ModeNamespaces is the linux namespace backend. ModeNamespaces Mode = "namespaces" // ModeLandlock is the degraded linux fallback for hosts where // unprivileged user namespaces are blocked. ModeLandlock Mode = "landlock" // ModeSeatbelt is the macOS sandbox-exec backend. ModeSeatbelt Mode = "seatbelt" )
type Network ¶
type Network string
Network is the network capability granted to a plugin.
const ( // NetworkNone confines the plugin to its socket dir: the only // channel is the gRPC unix socket shared with the gateway. NetworkNone Network = "none" // NetworkOutbound leaves the plugin in the host network (tunnel // plugins are the upstream transport and need to dial out). NetworkOutbound Network = "outbound" )
type Spec ¶
type Spec struct {
// PluginName is the HCL block label, used in error text only.
PluginName string
// BinaryPath is the resolved plugin executable.
BinaryPath string
// SocketDir is the short-pathed directory holding the go-plugin
// unix socket. It is read-write inside the sandbox at the SAME
// absolute path, so the socket address the plugin prints on
// stdout resolves identically for the gateway.
SocketDir string
// TmpDir is the plugin's private writable scratch space (HOME and
// TMPDIR point here). Conventionally SocketDir/tmp.
TmpDir string
// Network is the granted network capability.
Network Network
// ReadPaths are extra recursive read-only grants. There is no
// write-grant equivalent: host writes require sandbox = "off".
ReadPaths []string
}
Spec describes one plugin launch. All paths must be absolute and symlink-resolved by the caller.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package sandboxtest holds test helpers for code that spawns sandboxed plugin subprocesses.
|
Package sandboxtest holds test helpers for code that spawns sandboxed plugin subprocesses. |