Skip to documentation
Documentation navigation

Documentation navigation

Documentation / guides

Platform Levels and Guarantees

Read achieved isolation levels and per-property guarantees without making false cross-platform promises.

developer

Sandboxing has two capability reports. Executor.Level() is a coarse achieved tier. Executor.Guarantees() and Executor.GuaranteeBits() are the per-property facts that matter when a caller needs a specific boundary. Both are observations from compilation, not the values requested in the profile.

Levels are coarse

ValueInterpretation
LevelNoneNo OS isolation level is claimed. This is the honest level for acknowledged Unconfined execution and the zero value.
LevelDegradedA backend enforces a sound subset of the requested policy, but one or more features are narrowed or unavailable.
LevelFullThe selected backend reaches the supported full policy shape for that host and still reports any individual limitations.

The word “full” is scoped to the backend’s policy vocabulary. It does not mean identical primitives on Linux, macOS, and Windows, nor does it override CompileReport details.

Guarantees are independent bits

Guarantees expands the bitmask into named booleans:

GuaranteeWhat it claims
GuaranteeProcessBoundary (ProcessBoundary)A process boundary is enforced by the backend.
GuaranteeWriteBoundary (WriteBoundary)Writes are limited to the compiled writable authority.
GuaranteeReadBoundary (ReadBoundary)Reads and execution are limited on the relevant axes.
GuaranteeEnvScrub (EnvScrub)The child receives the assembled allowlisted environment rather than the parent environment.
GuaranteeNetworkBoundary (NetworkBoundary)Egress is restricted by an enforcement mechanism.
GuaranteeAddressNetwork (AddressNetwork)Address classes such as loopback/private/metadata are enforced, not merely ports.
GuaranteeResourceLimits (ResourceLimits)The compiled resource limits are attached to an enforcing scope.
GuaranteeTargetNetwork (TargetNetwork)A route/proxy can enforce the authenticated target set.

The profile stores RequiredGuarantees for restricted axes. Executor construction compares that mask with the backend’s achieved bits and fails closed if a required bit is missing. A backend may also report a narrowed feature through its report without a guarantee bit.

Native backends differ

Host/backendBoundary shapeHonest limitation to keep in mind
Linux Rung 1Re-exec plus user, mount, PID, and network namespaces, mount view, nftables, Landlock, Seccomp, and cgroup where available.Requires sandbox.Init() before any other main work. Host probing decides whether Rung 1 is available.
Linux Rung 2Re-exec, Landlock filesystem rules, Seccomp, TCP-port network rules, and optional cgroup limits.It is LevelDegraded; port rules cannot express address-scoped policy, and DNS-over-TCP is resolver-dependent.
macOS/usr/bin/sandbox-exec Seatbelt profiles.A supervised process may report LifetimeContainmentBestEffort; do not infer a kernel process-tree proof from Seatbelt alone.
WindowsThe selected restricted-token or elevated/broker backend, depending on setup and WindowsSandboxMode.Setup state, host version, runtime baseline, and backend mode affect which guarantees can be claimed. A TTY request can be rejected when a selected backend has no terminal wiring.
Other hostsNo production OS backend is selected for Sandboxed.Construction returns ErrSandboxUnavailable; acknowledged Unconfined remains a separate explicit choice.

Linux’s Rung 2 port boundary is intentionally not described as an address boundary. Linux Rung 1’s in-namespace nftables can enforce address predicates. macOS and Windows do not inherit either description just because they also have a Network field.

Inspect before choosing a policy

package example

import (
	"fmt"

	"github.com/looprig/sandbox"
)

func explain(executor *sandbox.Executor) error {
	if executor.Level() == sandbox.LevelNone {
		return fmt.Errorf("no isolation level claimed")
	}
	guarantees := executor.Guarantees()
	fmt.Printf("level=%d read=%t write=%t network=%t limits=%t\\n",
		executor.Level(), guarantees.ReadBoundary, guarantees.WriteBoundary,
		guarantees.NetworkBoundary, guarantees.ResourceLimits)
	for _, entry := range executor.Report().Entries {
		fmt.Printf("%s: %s (%s)\\n", entry.Feature, entry.Status, entry.Detail)
	}
	return nil
}

Use this report to decide whether your operation can proceed, not merely to decorate logs. For example, a caller requiring address-scoped egress should require GuaranteeAddressNetwork and reject a LevelDegraded executor that only has GuaranteeNetworkBoundary.

Source

Proof

← back to documentation