playground

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2026 License: MPL-2.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultMaxFiles      = 128
	DefaultMaxFileBytes  = 256 * 1024
	DefaultMaxTotalBytes = 2 * 1024 * 1024
)
View Source
const (
	SandboxWorkspacePath  = "/workspace"
	SandboxOutputPath     = "/out"
	SandboxGoRootPath     = "/goroot"
	SandboxGoModCachePath = "/gomodcache"
	SandboxGoCachePath    = "/cache"
	SandboxTmpPath        = "/tmp"
)

Fixed in-sandbox mount points. The build always runs against these paths after confinement, regardless of where the host staged the inputs.

View Source
const SandboxUnsupportedExitCode = 99

SandboxUnsupportedExitCode is the exit status the re-executed child uses to tell the parent that confinement could not be established here (e.g. the kernel denied a required mount inside the namespace). The parent maps this code back to ErrSandboxUnsupported so hosted execution fails closed cleanly instead of surfacing an opaque non-zero exit. It is outside the range the Go toolchain or the build itself returns.

Variables

View Source
var ErrSandboxUnsupported = errors.New("playground sandbox is not supported on this platform")

ErrSandboxUnsupported is returned when OS-level confinement is not available on this platform or kernel. Hosted execution must fail closed on this error, never fall back to running the build unconfined.

Functions

func ConfineToSandbox added in v0.6.0

func ConfineToSandbox(spec SandboxSpec) error

ConfineToSandbox is run by the re-executed child, already inside the new namespaces. It builds a minimal root that exposes only the toolchain, a throwaway module-cache overlay, the staged workspace, and the output directory, then pivot_roots into it so the host filesystem becomes unreachable. Finally it applies resource limits and no-new-privileges. Any failure is returned so the caller aborts; partial confinement never runs the build.

Some environments create the namespaces but then deny a required mount inside them (a container with a positive max_user_namespaces but a restrictive mount policy reports exactly this: "mount proc: operation not permitted"). Such a failure means the sandbox cannot be established here, not that the build is broken, so it is reported as ErrSandboxUnsupported and the child exits with SandboxUnsupportedExitCode so the parent fails closed cleanly.

func EncodeSandboxSpec added in v0.6.0

func EncodeSandboxSpec(spec SandboxSpec) (string, error)

EncodeSandboxSpec serializes a spec for handoff to the re-executed child.

func ExecutionTimeout

func ExecutionTimeout() time.Duration

func LaunchSandbox added in v0.6.0

func LaunchSandbox(spec SandboxSpec, childPath string, childArgs []string, env []string, stdout, stderr io.Writer, timeout time.Duration) error

LaunchSandbox runs childArgs (the re-executed gowdk build) inside fresh user, mount, PID, network, IPC, and UTS namespaces. The network namespace has no configured interface, so the child has no network. The wall-clock timeout kills the child; because it is PID 1 of its namespace, the kernel reaps the whole process tree with it.

func PolicyJSON

func PolicyJSON(policy Policy) ([]byte, error)

func RejectSecretEnvironment

func RejectSecretEnvironment(env []string) error

func SandboxEnvironment added in v0.6.0

func SandboxEnvironment() []string

SandboxEnvironment returns the environment the build runs with inside the confined root: the toolchain and caches point at the fixed in-sandbox paths, the module proxy and checksum database are disabled, and no host environment leaks in. It is deliberately built from constants, not os.Environ().

func SandboxSupported added in v0.6.0

func SandboxSupported() (bool, string)

SandboxSupported reports whether the kernel offers the namespaces this sandbox needs. It is intentionally conservative: a false result must make hosted execution fail closed rather than run unconfined.

Reading max_user_namespaces alone is not enough: containers (notably the CI runners) report a positive limit yet still deny the unprivileged clone via seccomp/AppArmor, so the value lies about what actually works. We therefore follow the cheap sysfs check with a real clone probe and only report support when the namespaces can genuinely be created.

func SanitizedEnvironment

func SanitizedEnvironment(cacheRoot string) []string

func SecretLikeEnvName

func SecretLikeEnvName(name string) bool

func SecretLikePathName

func SecretLikePathName(rel string) bool

func UnsafeExportDirectory

func UnsafeExportDirectory(rel string) bool

func UnsafeExportFile

func UnsafeExportFile(rel string) bool

Types

type ExportResult

type ExportResult struct {
	Archive string `json:"archive"`
	Files   []File `json:"files"`
}

func ExportArchive

func ExportArchive(sourceDir string, archivePath string, options Options) (ExportResult, error)

type File

type File struct {
	Path string `json:"path"`
	Size int64  `json:"size"`
}

func CollectFiles

func CollectFiles(sourceDir string, options Options) ([]File, error)

type Limits

type Limits struct {
	WallClockSeconds int   `json:"wallClockSeconds"`
	MaxFiles         int   `json:"maxFiles"`
	MaxFileBytes     int64 `json:"maxFileBytes"`
	MaxTotalBytes    int64 `json:"maxTotalBytes"`
	MaxOutputBytes   int64 `json:"maxOutputBytes"`
}

type Options

type Options struct {
	MaxFiles      int
	MaxFileBytes  int64
	MaxTotalBytes int64
}

type Policy

type Policy struct {
	HostedExecutionEnabled bool     `json:"hostedExecutionEnabled"`
	Workspace              string   `json:"workspace"`
	Network                string   `json:"network"`
	Filesystem             string   `json:"filesystem"`
	Persistence            string   `json:"persistence"`
	VersionPinning         string   `json:"versionPinning"`
	Export                 string   `json:"export"`
	Limits                 Limits   `json:"limits"`
	Environment            []string `json:"environment"`
	RequiredAbuseControls  []string `json:"requiredAbuseControls"`
}

func DefaultPolicy

func DefaultPolicy() Policy

type SandboxSpec added in v0.6.0

type SandboxSpec struct {
	// WorkspaceRoot is the staged, disposable project copy (writable inside).
	WorkspaceRoot string `json:"workspaceRoot"`
	// OutputDir receives build output (writable inside).
	OutputDir string `json:"outputDir"`
	// GoRoot is the host GOROOT exposed read-only so the toolchain can run.
	GoRoot string `json:"goRoot"`
	// GoModCache is the host module cache exposed through a throwaway writable
	// overlay so offline builds resolve cached modules without persisting writes.
	// Its lower layer is readable by the sandboxed build, so a hosted runner must
	// point this at a per-session cache holding only the submitted project's
	// dependencies, never a shared cache with other tenants' private modules.
	GoModCache string `json:"goModCache"`
	// MaxAddressSpaceBytes caps the virtual address space (RLIMIT_AS). Zero
	// leaves the limit unset.
	MaxAddressSpaceBytes uint64 `json:"maxAddressSpaceBytes"`
	// MaxCPUSeconds caps CPU time (RLIMIT_CPU). Zero leaves it unset.
	MaxCPUSeconds uint64 `json:"maxCPUSeconds"`
	// MaxFileSizeBytes caps any single written file (RLIMIT_FSIZE). Zero leaves
	// it unset.
	MaxFileSizeBytes uint64 `json:"maxFileSizeBytes"`
	// MaxOpenFiles caps open descriptors (RLIMIT_NOFILE). Zero leaves it unset.
	MaxOpenFiles uint64 `json:"maxOpenFiles"`
	// MaxProcesses caps processes for the sandboxed user (RLIMIT_NPROC). Zero
	// leaves it unset.
	MaxProcesses uint64 `json:"maxProcesses"`
	// MaxTmpfsBytes caps the size of each writable tmpfs mounted inside the
	// sandbox (the root, build cache, and /tmp). tmpfs is page-cache backed, so
	// without this a build could write until host memory is exhausted. Zero
	// leaves the tmpfs unbounded (host default). It is a per-mount cap, not an
	// aggregate one; total memory is the outer cgroup boundary's responsibility.
	MaxTmpfsBytes uint64 `json:"maxTmpfsBytes"`
}

SandboxSpec describes a confined build execution. All paths are absolute host paths; the sandbox remaps them to fixed locations inside the confined root.

func DecodeSandboxSpec added in v0.6.0

func DecodeSandboxSpec(encoded string) (SandboxSpec, error)

DecodeSandboxSpec parses a spec produced by EncodeSandboxSpec.

type Workspace

type Workspace struct {
	Root  string
	Files []File
}

func StageWorkspace

func StageWorkspace(sourceDir string, options Options) (Workspace, func() error, error)

Jump to

Keyboard shortcuts

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