1.0.0 — 2026-08-28
Extracted from the Axonn umbrella; first public release
This library was an application inside a larger umbrella project. It is now its own repository and
its own Hex package, with its own lockfile, config, CI and isolation harness. The extraction
preserved history (git subtree split, 143 commits) rather than re-creating the tree.
What changed for a consumer, as opposed to for the umbrella:
storage_rootnow defaults to/var/lib/ex_sandbox/sandboxes, was/var/lib/axonn/sandboxes. ⚠️ For an existing deployment this is a data migration, not a cosmetic rename — sandbox storage moves. Setconfig :ex_sandbox, :beam, storage_root: "/var/lib/axonn/sandboxes"to keep the old path.- The verdict socket's default prefix is
ex-sandbox-, wasaxonn-. - The dependency tree is
:telemetryand nothing else, enforced bytest/dependency_tree_test.exs, and the Elixir floor is~> 1.14rather than the platform's version. - The conformance suite's credentials group reports
capability_unavailablehere rather than passing, because this package has no data store to probe (012-FR-001). A consumer with a database instantiates the same suite with its own probe. The identifiers are explained in docs/requirement-ids.md.
No public function, callback, struct field or telemetry event changed in the move.
ExSandbox.Mechanism gained an optional callback, and the gate changed shape
ExSandbox.Mechanism.constructed_capabilities/0 declares the capabilities a
mechanism builds for whatever it runs — the opposite claim from
ExSandbox.Mechanism.required_capabilities/0, which says what it needs from
the host. ExSandbox's private ensure_capable/2 now subtracts the second list from the
first and asks the host probe only about the remainder.
⚠️ This is a change to a refusal, which is why it is a major version. The callback is optional and a mechanism that omits it is gated exactly as before, so nothing in the tree breaks — but a mechanism that declares one is now admitted on a host where it was previously refused, and a gate that admits more than it used to is a behavioural change to the thing this library exists to do. It is stated here rather than in the additive column.
The claim is not verified by the behaviour. ExSandbox.Conformance is what
establishes it, by observing a breach being stopped; until a mechanism is run
through the suite, what backs its list is whatever tests accompany it.
ExSandbox.Mechanism.Docker
A mechanism backed by a container runtime, for hosts whose own kernel cannot
construct the confinement ExSandbox.Mechanism.Beam requires — every macOS
host, where all five gating capabilities report unavailable and Beam is
therefore refused before it is reached.
It declares :resource_limits, :filesystem_confinement and
:network_restriction as constructed, each backed by an observed breach in
test/mechanism/. It deliberately claims neither
:disk_quota — MEASURED accepted-and-ignored on overlayfs — nor
:privilege_separation; both omissions are stated reductions and are documented
on the module.
ExSandbox.Sandbox gained workspace_path
An absolute host directory the sandbox's contents live in, supplied by the host
and made reachable from inside by whatever means the mechanism has. Additive:
nil means "no workspace", which a mechanism must read as mount nothing
rather than as mount somewhere sensible.