- Fixed Linux
--allow-hostDNS reachability for intercepted sandboxes by adding a host-side DNS forwarder and nftables redirection for guest DNS queries (#94, initial contribution by @nemtsov). - Improved Linux interception reliability by binding proxy services to the sandbox gateway IP, applying secret-related allowed hosts before firewall setup, and falling back across configured DNS resolvers when an upstream fails.
- Added custom secret placeholder support across
matchlock runand the Go, Python, and TypeScript SDKs, including--secret-placeholder,--secret-file, and builder helpers for caller-defined in-VM placeholder values. - Fixed overlay rootfs preparation to avoid shadowing merged-
/usrlayouts when injecting the guest init binary.
Added Basic Auth secret placeholder replacement including unpadded credentials.
- Added guest kernel selection across the CLI and Go, Python, and TypeScript SDKs via kernel refs, including
file:///absolute/pathand OCI image references. - Added
matchlock kernel lsandmatchlock kernel rmfor inspecting and cleaning cached guest kernels, backed by persistent kernel cache metadata. - Expanded kernel acceptance and SDK coverage, and bumped the default pinned guest kernel to
6.19.8.
Use non-snapshot mode deb/rpm package for formal releases
- Added Linux package-based installation via upstream
.deband.rpmrelease artifacts, plus a cross-platform install script. - Fixed interactive PTY resize handling for
matchlock exec -itby forwardingSIGWINCHto the guest and serializing relay writes to avoid stdin/resize races by @sosso. - Added VM log read/follow support across the CLI, RPC, and Go/Python/TypeScript SDKs.
- Fixed TypeScript SDK npm release workflow to use Node 24 for trusted publishing compatibility in GitHub Actions.
- Added
matchlock diagnosefor host preflight checks, with Linux and macOS-specific requirement validation. - Hardened
matchlock setup linuxto fail fast by default on required setup errors; use--best-effortto continue past failures. - Removed legacy macOS initramfs support from the Darwin VM path and from diagnose output.
- Fixed
host_fsFUSE rename cache handling so files/directories stay readable after atomictmp+renameworkflows (includinggit checkout/git statuspatterns) (#80 by @sosso). - Fixed intermittent macOS
VZErrorDomain Code=1VM startup failures in interception mode by retaining Darwin console file handles for VM lifetime, and suppressed spuriousclose host-net: file already closedcleanup noise.
- Added fractional CPU support across CLI and SDK create flows (
cpusnow accepts values like0.5). - Hardened CPU validation before VM creation: CPU count must be finite, greater than zero, and not exceed host CPU capacity.
- Added Python SDK port-forward parity with Go/TypeScript:
Sandbox.with_port_forward(...)andSandbox.with_port_forward_addresses(...)Client.port_forward(...)andClient.port_forward_with_addresses(...)- create-time auto-application of configured port-forwards
- Added Docker-style
matchlock run -d/--detachsupport for starting long-lived sandboxes in background mode with VM ID output.
- added entrypoint support for sdkk
- added missing
with_privilegedfor python sdk - added example of running both claude code and docker in the sandbox
matchlock volume cp <src> <dest>- Added Go SDK
exec_pipeandexec_ttysupport (stdin piping + interactive PTY shell), plus a new interactive terminal example atexamples/go/exec_modes. - Added Python and TypeScript SDK support for
exec_pipeand interactiveexec_ttyexecution modes.
- File operations over SDK rpc now no longer relies on vfs.
- Also fixed all the examples that were broken due to previous breaking changes
- Added
--no-networkto disable sandbox network egress, with matching support in Go, Python, and TypeScript SDKs (#62). - Added Go SDK callback-based network interception hooks.
- Reduced
MemoryProviderdirectory bookkeeping overhead by using a singledirsmode map, preventingdirs/dirModesdesyncs in VFS (#67 by @comunidadio). - Made workspace/VFS opt-in for
run: no workspace is mounted by default, andguest-fusedstarts only when a workspace is explicitly configured with VFS mounts. - Tightened VFS startup validation to fail fast on invalid configurations (for example,
vfs.workspacewithout mounts, mounts withoutvfs.workspace, or mount paths outside workspace). - Changed CLI volume behavior to require explicit
--workspacewhen using--volume/-v, with clear startup-time errors for invalid combinations. - Added raw ext4 disk mounts for
runvia--disk host_path:guest_mount[:ro], including multiple--diskentries in one sandbox. - Added named volume support for raw disks:
matchlock volume create <name> [--size MB]matchlock volume lsmatchlock run --disk @<name>:<guest_mount>[:ro]
- Hardened extra-disk reliability by treating in-guest disk mount failures as fatal at boot, propagating read-only mount mode, and issuing a best-effort guest
syncbefore VM shutdown. - Fixed close-time context handling so zero graceful-shutdown no longer creates an immediately expired timeout during sandbox cleanup.
- Reworked image/runtime storage to an OCI layer-aware model: shared EROFS layer blobs in metadata DB plus overlay-root boot with a per-VM writable upper disk (replacing monolithic rootfs images).
- Manual tidy-up (full local reset):
matchlock kill --allmatchlock prunerm -rf ~/.matchlockrm -rf ~/.cache/matchlock
- Fixed TypeScript SDK npm provenance metadata by setting
repository.url/repository.directoryinsdk/typescript/package.json.
-
Added a TypeScript SDK with Go/Python feature parity, tests, release/test GitHub Actions, and examples.
-
Changed CLI
-v host:guestdefault to isolatedoverlaysnapshot mounts, with:host_fsas the explicit direct host mount mode on both Linux and macOS (#41).
- Added port forward support with
matchlock run -p LOCAL_PORT:REMOTE_PORT ... - Updated default working directory semantics for
run/exec: when--workdiris not set, Matchlock now uses the imageWORKDIRfirst, then falls back to workspace path (#40). - Fixed Alpine/musl
gitfailures in/workspace(unable to get current working directory) by returning full stat metadata for FUSEmkdir/createentries and hardening workspace mount readiness checks (observed on macOS) (#43). - Fixed nested guest volume mount paths (for example
-v host:.host/example) so intermediate directories are synthesized and mounts resolve correctly (#42). - Added configurable guest network MTU (CLI
--mtuand SDKNetworkMTU) to mitigate path-MTU/TLS handshake issues on some VM networking paths. - Refactored guest runtime startup to a unified
guest-initbinary that dispatches init/agent/fused roles, replacing separate guest binaries and simplifying rootfs injection. - Stabilised FUSE inode propagation for workspace paths to eliminate intermittent Alpine/musl
getcwdfailures duringgit initin/workspace(#43). - Added configurable guest hostname support (CLI
--hostnameand Go/Python SDKs), with safe defaults and deterministic/etc/hostname+/etc/hostssetup in guest init (#48 by @comunidadio. - Added
--add-host host:ipsupport (including Go SDKAddHost) to inject custom host-to-IP mappings into guest/etc/hosts(#52).
- Added support for vfs interception #7
- Added non-secret environment variable support across CLI and SDKs (#34):
matchlock run -e/--env,--env-file, persisted visibility viaget/inspect, plus Go/Python SDK create-timeenvsupport. - Mount path validation and normalization fixes for #32 and #33 (#35).
- VM lifecycle revamp: append-only lifecycle records in SQLite, reconciliation flow, and new
gc/inspectcommands. - Metadata migration to SQLite for VM state, subnet allocations, and image metadata.
- Fixed
matchlock listhang when stalerunningVMs (dead PID) are encountered. - Breaking change: legacy filesystem-only VM metadata under
~/.matchlock/vms/<id>/is not auto-backfilled intostate.db; pre-migration VMs may not appear inlist/kill/rm/pruneuntil migrated or cleaned up.- Quick cleanup after upgrade:
matchlock gc --force(best-effort host resource cleanup)matchlock prune(remove stopped/crashed VMs known to DB)- If legacy dirs still remain, remove them manually:
rm -rf ~/.matchlock/vms/<id>
- Quick cleanup after upgrade:
- Added end-to-end context cancellation support across the entire matchlock stack.
- Added init=/init kernel arg for Linux backend and prevent /sbin/init overwrites for systemd compatibility
- Intoroduced standalone
-ipipe mode to allow stdio based communication with the Agent running inside the sandbox - Added examples of launching docker container inside the sandbox
- Added examples of launching agent from local ACP client over ACP protocol
- Image extraction now uses pure Go instead of shelling out to
tar**, preserving file ownership (uid/gid), permissions (including setuid/setgid/sticky bits) and symlinks when building ext4 rootfs images. This fixes symlink loop crashes (e.g. Playwright/Chromium images) by replacing symlink directories with real ones during extraction. - Added example of browser usage using playwright driven by agent running in mcp code mode to cover the use cases of #6
- User and entrypoint overrides — Added
--user(-u) flag torunandexecto run as a specific user (uid, uid:gid, or username), and--entrypointflag to override the image's ENTRYPOINT. Commands are now composed from OCI image config (ENTRYPOINT + CMD) when no explicit command is given, matching Docker behavior. - VFS chmod support — Added
Chmodoperation across all VFS providers and the guest FUSE daemon, enabling proper file permission management inside sandboxes. - Image config improvements — OCI image config (USER, ENTRYPOINT, CMD, WORKDIR, ENV) is now properly extracted, cached, and merged through both the Go and Python SDKs, with in-guest user resolution via
/etc/passwd.
- Fix concurrent sandbox launches failing with port conflict — The transparent proxy (Linux) no longer binds to hardcoded ports 18080/18443/18081. Proxy listeners now use OS-assigned ephemeral ports (port 0), with actual ports read back and passed to nftables rules. This allows multiple matchlock instances to run simultaneously without
bind: address already in useerrors. - Fixing
matchlock image rmas per #19
- Split
matchlock buildintobuildandpull—matchlock buildis now exclusively for Dockerfile builds (using BuildKit-in-VM). Image pulling has moved to the newmatchlock pullcommand. The-fflag now defaults toDockerfile, somatchlock build -t myapp:latest .works without specifying-f.
matchlock rmnow errors when VM ID is not found (#14)- Fix 2-3s exit delay and "file already closed" warning on macOS —
Close(ctx)now accepts a context so callers control the graceful shutdown budget (By default 0s for CLI and SDK);SocketPair.Close()is idempotent to prevent double-close errors (#13) --rmflag now properly removes VM state on exit — previouslysb.Close()only marked the VM as stopped without removing the state directory, causing stale entries inmatchlock list(#12)