Skip to content

Clarify sandbox-exec deprecation timeline and provide a replacement for non-App-Store process sandboxing #737

@SCKelemen

Description

@SCKelemen

Problem

sandbox-exec(1) is the only documented mechanism for applying Seatbelt
(TrustedBSD MAC) policies to arbitrary user-space processes on macOS without
enrolling in the App Store or using Xcode entitlements. Apple marks it as
deprecated:

$ sandbox-exec -f /dev/null /usr/bin/true
WARNING: sandbox-exec is deprecated. Consider adopting the App Sandbox instead.

Despite the deprecation banner, there is no published replacement that covers
the use case of server-side / CLI process sandboxing:

  • App Sandbox requires code signing with the
    com.apple.security.app-sandbox entitlement and an Xcode project. It is
    designed for GUI apps distributed through the Mac App Store, not for
    headless server processes compiled with go build.
  • Endpoint Security framework provides observation and authorization
    callbacks but does not offer a declarative sandbox profile that restricts
    a child process at exec time.
  • System Extensions are distribution-gated and inappropriate for
    per-process isolation of containers.

We use sandbox-exec in containerd-shim-darwin to enforce filesystem,
network, and process restrictions on darwin-native container workloads. Our
enforcement bound is documented and tested:
containerd-shim-darwin/SECURITY.md
covers 40/42 blocked escape vectors (95.2%).

Use case

darwin-k8s runs trusted darwin/arm64 Go binaries as native macOS processes
under a Seatbelt profile applied via sandbox-exec -f <profile> <binary>.
This provides:

  • Filesystem allow/deny by path pattern
  • Network socket deny (bind, connect, listen)
  • Process-exec restriction (only the container binary can exec)
  • Signal restriction (only self)
  • Mach service restriction (subset of mach-lookup allowed)

We need answers to three questions:

  1. Will sandbox-exec be removed in a specific future macOS version?
    (So we can plan migration timing.)
  2. Is there a non-deprecated equivalent for applying Seatbelt policies to
    processes that are not signed with App Sandbox entitlements? (E.g., a
    documented sandbox_init_with_parameters C API, or a new framework.)
  3. Will Apple Containerization eventually offer a "lite" isolation mode
    that sandboxes a darwin/arm64 process without spinning up a Linux VM?
    (This would let us retire sandbox-exec entirely in favor of the
    framework.)

Reproducer

$ /usr/bin/sandbox-exec -f ./containerd-shim-darwin/test/profiles/deny-default.sb \
    ./containerd-shim-darwin/test/hello/hello
WARNING: sandbox-exec is deprecated. Consider adopting the App Sandbox instead.
Hello from sandbox

The binary runs correctly under the profile, but the deprecation warning is
emitted to stderr on every invocation (macOS 15 Sequoia, Apple Silicon).

Our test suite (containerd-shim-darwin/test/security_test.sh) asserts the
enforcement bound: 40 of 42 escape vectors blocked, with the remaining 2
(raw socket() fd creation and Mach IPC for Go runtime) documented as
Darwin kernel limits that sandbox-exec cannot address.

Proposed resolution

Any of the following would unblock us:

  1. Publish a supported C API (e.g., sandbox_init_with_parameters or
    equivalent) that accepts a Seatbelt profile and applies it to a child
    process, without requiring App Sandbox entitlements.
  2. Add a native-process sandboxing mode to Apple Containerization — a
    DarwinProcess or NativeContainer type that applies a security policy
    to a darwin/arm64 binary without the overhead of a Linux VM.
  3. Document the deprecation timeline so integrators can plan migration
    (even if the replacement is "use VMs for everything").

Workarounds we've tried

  1. Continue using sandbox-exec despite deprecation — works on macOS 15.
    Risk: Apple removes it without warning in a future release.
  2. Fall back to Linux VMs for all workloads — eliminates the native
    darwin path entirely. Increases startup latency from <5ms to ~800ms and
    adds 128MB+ RAM overhead per pod. Defeats the purpose of running
    darwin/arm64 binaries natively.
  3. setrlimit + taskpolicy -b without sandbox — provides resource
    limits but zero filesystem/network/process isolation. Unacceptable for
    any security-conscious deployment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions