Skip to content

Releases: ysinghc/sandbox

Sandbox Engine v0.14.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 00:10

Session workspaces (#23): a sandbox's /workspace can now outlive the VM that
wrote it, under a strict, creator-controlled TTL. This is the first release in
which "the assistant remembers things between calls" is a property of the engine
rather than of the model's context window.

Added

  • Session volumes (#23): sandbox_spec_t.session_key gives a sandbox a
    persistent /workspace; ttl_seconds sets its lifetime. Volumes are a
    pre-formatted sparse ext4 image built with the template and cloned per session
    (reflink where the filesystem supports it, sparse extent copy otherwise), keyed
    by sha256(session_key) in SANDBOX_WORKSPACE_ROOT, created in a staging
    directory and rename()d into place. A session is exclusive-use: a lease
    prevents two VMs writing one image, and a session_key create bypasses the warm
    pool because Firecracker cannot swap a block device after restore.
  • TTL policy (D5): expires_at = created_at + clamp(ttl, 60 s, platform max),
    default 7 days, maximum 30 days (SANDBOX_WORKSPACE_MAX_TTL). Absolute from
    creation, never extended automatically. A reaper thread expires sessions on a
    timer (SANDBOX_REAP_INTERVAL_SECONDS, default 60 s) and also collects
    abandoned staging directories.
  • Renewal: sandbox_session_renew(key, extra_seconds, &expires_at) and
    sandbox-cli renew --session-key KEY [--extra SECONDS], plus
    sandbox::renew_session() in the C++ SDK. Keyed by session, not by sandbox, so
    a quiet conversation can be kept alive with nothing running. extra_seconds is
    added to now, clamped to the platform maximum, never shortened; a past
    deadline returns SANDBOX_ERR_SESSION_EXPIRED (the volume is already gone), an
    unknown key SANDBOX_ERR_SESSION_UNKNOWN, and a session already at the maximum
    SANDBOX_ERR_SESSION_LIMIT.
  • Durable teardown: the engine asks the guest to sync() before it SIGKILLs
    the VMM (reserved SANDBOX_CONTROL=flush on the vsock control channel,
    acknowledged with SANDBOX-FLUSH-OK, bounded by SANDBOX_FLUSH_MS). Without
    it, a page written by the workload was still in the guest's page cache when the
    VM died, and the next sandbox of the same session simply did not see the file.
  • In-guest persistence evidence: the guest agent appends a checksum of each
    injection to /workspace/.sandbox-probe and reports mounted=, lines=,
    first= and last= on the serial console, so the privileged e2e test proves
    persistence from inside the guest instead of reading back a file the host wrote.
  • Workspace metrics and docs/WORKSPACE_DISK.md (including the deviations
    from the original D7 design and why they were made).

Fixed

  • ext4 corruption after restore (f1a2ba7): the guest mounted /workspace
    before the template snapshot was captured, so every restore resumed a mounted
    ext4 whose backing file had been replaced — the guest then reported
    EXT4-fs error (device vdb): checksumming directory block 0. The volume is now
    mounted by the agent on first use after each restore, which also makes
    "a clone is byte-identical to its base" true by construction and lets ext4
    replay the journal of a sandbox killed mid-write.
  • Leaked jail bind mount (976299b): jail_cleanup() never unmounted
    /workspace.ext4, so removing the jail hit EBUSY, the jail survived, and
    later creates failed at [jailer] step 6 failed: errno=2. Unmount added, and
    bind failures now name the source, the destination and whether the source
    exists.
  • Latency probe segfault: the generated probe in scripts/benchmark.sh built
    its sandbox_spec_t on the stack without initialising it; the new pointer field
    turned that into a wild dereference. Zero-initialised, and the contract is now
    stated in docs/API.md.
  • Network test flake: the broker port was hard-coded to 8080 (a genuinely busy
    port) and the drop verdict failed if any frame arrived, including a
    retransmission from the previous connection. The port is now chosen per run and
    the verdict is keyed to the connection under test.
  • Test isolation: the privileged suite now clears its test root before a run.
    Re-runs on the same runner were inheriting the previous run's session volumes
    (durable by design), which surfaced as a "new volume starts empty" failure.

Changed

  • SANDBOX_BROKER_PORT (default 8080) is the single source of truth for the
    port guests may reach on the host: the egress rules and the broker listener both
    derive from it, so moving the broker off a busy port is now one variable instead
    of two values that silently disagree.
  • sandbox_spec_t grew two fields. Callers must zero-initialise it
    (sandbox_spec_t spec = {0};); an uninitialised session_key is a crash, not a
    default. All in-tree callers already did.

Verified

  • Privileged e2e (self-hosted, KVM): all 7 suites pass, including the session
    persistence test (create → write in guest → destroy → re-create → the file is
    still there, with the pre-destroy line first) and tests/e2e/smoke.sh.
  • Restore latency on the reference host: 38.49 ms cold (provisioned),
    55.76 ms average over five provisioned restores, budget 250 ms.

Artifacts: per architecture (x86_64, aarch64) — staged install tree, bare-binary archive, individual binaries and shared libraries, and SHA-256 checksums. Both built natively from this tag.

Verified on the privileged runner: all 7 privileged suites pass with zero skips, in-guest persistence across destroy/re-create, cold restore 38.49 ms / provisioned 55.76 ms against a 250 ms budget.

Upgrade note: 0.13.0 templates still load, but have no workspace — rebuild to use session_key. sandbox_spec_t grew two fields: zero-initialise it (= {0}).

Sandbox Engine v0.13.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 21:40

Full Changelog: v0.12.0...v0.13.0

Sandbox Engine v0.12.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 10:21

Sandbox Engine 0.12.0

Fast, isolated Firecracker microVM sandboxes for untrusted code — pooled,
snapshotted, and restored in milliseconds. This is the first packaged release.

Download

Platform Artifact
Linux x86_64 sandbox-engine-0.12.0-linux-x86_64.tar.gz
Linux aarch64 sandbox-engine-0.12.0-linux-aarch64.tar.gz

Each tarball ships a .sha256 alongside it:

eccb63fdd40921abdec37f7704858b458fd3a7bf44d32018449a151a1a3158c9  sandbox-engine-0.12.0-linux-x86_64.tar.gz
e04d0aa8877cf421b5773be89f8f3b6a6619a3d1b6e1d81a4393ef40456166c2  sandbox-engine-0.12.0-linux-aarch64.tar.gz

Install

The tarball mirrors the filesystem layout (usr/local/..., var/lib/...,
etc/...), so for a default install extract it over /:

sudo tar -C / -xzf sandbox-engine-0.12.0-linux-$(uname -m).tar.gz

It installs:

  • /usr/local/bin/{sandboxd,sandbox-broker,sandbox-cli}
  • /usr/local/lib/{libsandbox.so,libsandbox++.so}
  • /usr/local/include/{libsandbox.h,libsandbox.hpp}
  • /usr/local/lib/systemd/system/sandboxd.service
  • /usr/local/share/doc/sandbox-engine/ (README, docs, LICENSE)
  • /var/lib/sandbox-engine/{config,config/engine.conf,jail,snapshots}
  • /etc/sandbox-engine/credentials.conf.example
  • /var/run/sandbox-engine/

Prefer cmake --install if you are building from source; see the README.

Note: a Rust toolchain, Firecracker, guest assets, and the runtime host
preparation (KVM, userfaultfd, cgroup v2) are not bundled — see
docs/DEPLOYMENT.md.

Requirements

  • Linux x86_64 or aarch64 with KVM and userfaultfd
  • root for the daemon
  • a firecracker binary (FIRECRACKER_BIN, default /usr/local/bin/firecracker)
  • a guest kernel and rootfs
  • runtime libraries: protobuf, libseccomp, libcurl, libnftables (optional),
    libsystemd (optional)

Quick start

sudo sandbox-cli verify --template e2e      # after stamping a template
sudo systemctl enable --now sandboxd
sudo sandbox-broker &
sudo sandbox-cli run --template e2e --memory 512

Highlights

  • Snapshot/restore with userfaultfd demand paging and a warm VM pool.
  • Jailed Firecracker processes (chroot + seccomp + uid drop + no_new_privs)
    with per-VM cgroup v2 limits.
  • Credential broker: allow-listed, token-validated HTTPS proxying with secrets
    injected on the host.
  • Asynchronous Create with per-session/uid concurrency caps.
  • Snapshot integrity via SHA-256 and a manifest header guard; sandbox-cli verify.
  • Structured logging plus /health, /ready, and /metrics.
  • C and C++ client libraries and a CLI.

Known limitations

Seccomp filter not yet validated against a real Firecracker syscall trace;
no hierarchical config; credentials.conf mode not enforced at load; privilege
separation, vsock payload authentication, per-tenant quotas, and long-horizon
features tracked as issues on the project board.

Full changelog: CHANGELOG.md
Docs: docs/
License: GNU GPL v2 (GPL-2.0-only)