⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Protonk/PolicyWitness

Repository files navigation

PolicyWitness

Read the user guide for more detail

PolicyWitness is a macOS sandbox witness harness for verifying sandbox policies with observable evidence. Sandbox outcomes are easy to misread without clear attribution and consistent output. PolicyWitness ties each result to a specific runner instance and emits a stable JSON envelope so you can audit, diff, and automate tests without guesswork.

Flow

Specimens -> Runs -> Steps -> Evidence

PolicyWitness operates on specimen, packages of SBPL + entitlements and probe plans. The controller launches a fresh runner for each specimen. The runner starts unsandboxed, loads libsandbox, applies the provided policy once, and then executes the probe plan step by step inside the sandbox. Each step performs an explicit attempt, records rc plus errno or kr, and also runs sandbox_check with the same operation and filter so you can compare predicted vs observed outcomes. The runner returns a single JSON result and exits.

Each step may include multiple evidence channels:

  • A: in-band attempt result (rc/errno/kr)
  • B: deterministic side effects (for example SBPL send-signal)
  • C: out-of-band unified-log correlation (best-effort)
  • D: sandbox_check prediction and "am I sandboxed" confirmation

Runner modes

PolicyWitness supports three runner modes. All three return the same JSON envelope and speak the same NSXPC protocol; they differ only in how the runner process is supplied and registered.

  • debuggable: built-in XPC service embedded in PolicyWitness.app; no install step.
  • byoxpc: user-supplied .xpc bundle (optionally self-signed) installed with policy-witness runner install --kind byoxpc.
  • machme: user-supplied binary registered as a Mach service with policy-witness runner install --kind machme.

PolicyWitness treats entitlements as a first-class input alongside SBPL. Register an externally signed runner with the entitlements your probes require, then apply a per-specimen SBPL policy on top to test temporary restrictions or entitlements + SBPL combinations in a single run.

Instrumentation

Instrumentation ports are part of the debuggable runner, allowing closer inspection.

  • dyld_env: report expected DYLD_* env vars (com.apple.security.cs.allow-dyld-environment-variables); set via an external runner with policy-witness runner install --env KEY=VALUE.
  • dylib_load: load a dylib and optionally call a symbol (com.apple.security.cs.disable-library-validation)
  • debug_wait: pause before sandbox apply for debugger attach (com.apple.security.get-task-allow)
  • execmem_probe: attempt RWX mmap and report success/failure (com.apple.security.cs.allow-unsigned-executable-memory)

What Ships

This repo builds a single distributable app bundle:

  • PolicyWitness.app
    • Contents/MacOS/policy-witness (Rust controller)
    • Contents/MacOS/pw-runner-client (Swift NSXPCConnection wrapper)
    • Contents/MacOS/sandbox-log-observer (Rust unified-log capture helper)
    • Contents/XPCServices/PWRunner.xpc (Swift runner, debuggable mode; one specimen per process)
    • Contents/Resources/Evidence/* (generated manifests: hashes/entitlements, symbols.json)

Where To Learn