Skip to main content

Locki is the first sandbox I've used where I genuinely forget I'm in one — until I try something I shouldn't.

⸺ Claude Code

L O C K I

AI sandboxing without the taste of sand

 

Locki is an AI sandbox for real-world projects. Not another vibe-coded docker wrapper, but an actual engineered solution built for the development needs of Agent Stack. Other sandboxes break down on anything more complex than "a single Next.js app". Locki can handle as many containers, systemd services and even Kubernetes clusters as you like (and your RAM allows).

 

Run agents in parallel with no collisions in ports, image tags, or infrastructure:

locki x claude "fix #42"
# Read issue using `gh`...
# Determined the cause...
# Fixed in code...
# Built image app:local...
# Started k3s cluster...
# Verified the fix...
locki x codex "improve perf"
# Built image app:local...
# Started k3s cluster...
# Measured performance...
# Improved critical paths...
# Re-built and re-deployed...
# Measured again...
locki x pi "add CZ translation"
# Built image app:local...
# Started k3s cluster...
# Explored UI in context...
# Translated strings...
# Re-built and re-deployed...
# Verified accuracy...

 

  • First-class DX: Work with your AI of choice. Zero config. No sign Locki is even there.
  • No compromises: Run anything including systemd, containers, even Kubernetes clusters.
  • Worktree-backed: All data remains on your disk in a git worktree. No need to dig in VMs.
  • Safe Git: Agents are only able to modify namespaced branches. Stash is scoped. Hooks are redirected.
  • Visibility and control: Worktrees live on your computer, see and modify them right there.
  • Agent-friendly: Bundled hand-picked tools and sandbox-specific instructions for best behavior.

Case study: Kagenti ADK uses Locki to run a full MicroShift node, allowing agents to verify their work using E2E tests on a real cluster. Something breaks? The agent can kubectl right in and debug, all contained within the Locki sandbox.

 

Tutorial

  1. Install: uv tool install locki. (Install uv first if you don't have it.)

  2. If on Linux, install QEMU. (Not needed on macOS.)

  3. cd to your Git repository and run: locki ai

    (Supported harnesses: claude, gemini, codex, opencode, pi, copilot.)

  4. First start takes longer, wait a few minutes for the VM to boot.

  5. Follow prompts to log in to the AI CLI. Login will be persisted across sandboxes.

  6. Build! Your agent is already instructed on how to behave in the sandbox.

  7. Run locki ai again to open an interactive selector: continue existing session, or start a new one.

  8. Once happy, commit and push your changes. Ask the agent, or do this manually for more control.

  9. After merging the branch, just delete the worktree from your IDE and Locki will clean up the sandbox.

    (Or do it manually with: locki remove)

 

Folders

Each sandbox gets its own worktree (a full copy of your repo) and shares a common home folder. The original repo and your actual home stay safely out of reach:

  • Your Git repo (~/myproject/) — ❌ Not visible from any sandbox. That means sandboxes can't reach the .git folder and mess it up -- all git calls go through a command bridge and get reviewed and filtered.
  • Each sandbox's worktree (~/.local/share/locki/worktrees/myproject-locki-.../) — Visible in corresponding sandbox, at the same path. All edits in the sandbox are instantly visible on host.
  • Shared sandbox home (~/.local/share/locki/home/) — Visible from every sandbox as ~. Save your agent configuration here to use it in sandboxes.
  • Your actual home (~) — ❌ Not visible from any sandbox. Sandboxes can't mess up your global config.

 

Commands

Every command supports -h/--help; most data commands take --json for scripting. Sandbox-selecting commands share -m/--match (id prefix or branch substring), -i/--interactive (force the picker), and -n/--new (create fresh).

Command What it does
locki ai Start your AI harness in a sandbox — resume, pick, or create.
locki exec | x -- <cmd> Run any command in a sandbox (default: bash).
locki ide Open your editor on the sandbox worktree (runs on host).
locki new | n Create a sandbox worktree without entering it.
locki list | ls [--all] List sandboxes for the current repo (or --all repos).
locki include (--repo <path> | --this) Graft another repo's worktree into a sandbox.
locki port-forward | pf [--list] [--clear] [port[:port]] ... Forward host ports to a sandbox.
locki remove | rm | delete [-f] [-b] [--merged] Remove a sandbox (-b also deletes its branches; --merged sweeps merged-and-clean ones).
locki setup [--defaults] [--copy] Setup wizard: pick harness/editor, copy AI config into the sandbox home.
locki vm status|st / stop / prune / delete Manage the shared Lima VM and its caches.

 

Comparison

Most sandboxing solutions use one of these techniques:

  • Full VM per sandbox (Vagrant, Multipass): resource-heavy, slow to start
  • MicroVM per sandbox (Firecracker, Apple container): none or limited support for building, running and orchestrating containers
  • OCI container per sandbox (Devcontainers, Distrobox, container-use): none or limited support for building, running and orchestrating containers; potentially unsafe if running VM-less on Linux
  • OS-level jail (Landlock, Bubblewrap, sandbox-exec): just restriction, not isolation (ports collide, image tags get overwritten, etc.)

Locki instead runs one Lima VM hosting many lightweight Incus containers — one shared kernel boundary you can trust, cheap per-sandbox containers, and full support for building and orchestrating containers (even Kubernetes) inside. Seriously, stop reading this README and run uvx locki ai, that's all there is.

 

Pro-tips for power users

  • Launch an IDE in the worktree folder using locki ide. 30+ editors are recognized out of the box (VSCode, Cursor, Zed, the JetBrains suite, Neovim, Sublime Text, ...), and you can set any custom command via locki setup or ide_command.
    (The IDE runs on host: you still need to run locki ai / locki x -- <cmd> in the built-in terminal to run commands in the sandbox. This is intentional: running your IDE inside the sandbox (using "remote SSH" or similar features) is unsafe, since the agent could potentially access authentication tokens stored in the IDE's memory.)

  • When cd'd into a worktree folder (~/.local/share/locki/worktrees/.../), locki commands use it by default -- otherwise they show an interactive picker. Use --match/-m to select by sandbox id or branch substring. locki list (alias ls) shows every sandbox and its worktree path.

  • Editors like VSCode show worktrees in the sidebar, useful as a quick UI for reviewing and modifying changes.
    (⚠️ VSCode 1.115.0+ requires setting "git.detectWorktrees": true for this to work.)

  • Working on two repos at once? cd into your sandbox's primary repo and run locki include --repo ../other-repo to graft the other repo into the current sandbox at .locki/include/<repo-name>-locki-<sandbox-id>/. Or from the other repo: locki include --this -m <sandbox-id>.

  • While locki ai opens a coding agent, locki exec (or short locki x) is the low-level version which can run any command. Pass a command to run in a sandbox, use --match/-m to select by branch substring or sandbox id: locki exec -m big-refactor -- pytest.

  • The first locki ai run prompts you to pick a default harness and editor. Re-run locki setup to change them, or edit ~/.config/locki/config.toml directly — the keys are full command lines, e.g. ai_command = "gemini --yolo -r" and ide_command = "code .". A repo can override ai_command via a locki.toml in its root; ide_command is user-only (it launches on your host).

  • Ask your agent to forward ports, or use locki port-forward for more control.

  • Locki sandboxes provide Mise for tool version management -- replacing nvm, rbenv, brew etc. with a single tool. Adding mise.toml to your repo with tool versions and task definitions will help agents and humans alike: ask your agent to do it!

  • Want to use custom AI configuration in the VM -- instructions, skills, MCP servers, ...? Sandboxes share a home folder accessible at ~/.local/share/locki/home on host (or $XDG_DATA_HOME/locki/home). For example, you can run cp ~/.claude/CLAUDE.md ~/.local/share/locki/home/.claude/CLAUDE.md to copy your custom instructions for use in sandboxes.

  • Something is broken? Try locki vm delete -- it will preserve your worktrees and settings, but the VM and sandboxes will be recreated from scratch on next run.

  • Sandboxes run on Fedora 43. Want a different OS? Create a locki.toml file in repo root referencing either an available OS image, or a local Incus image archive by path. For the local archive format, see the Incus image format documentation. Example:

    # locki.toml
    incus_image = "images:ubuntu/questing"
    

    For local image archives, use a path (relative to repo root) or a glob pattern. When a glob matches multiple files, the right one is picked by architecture substring (e.g. arm64, x86_64):

    incus_image = "images/locki-*.tar.xz"
    

    (Since containers share a binary cache, it is not recommended to mix musl distros (like Alpine) with regular ones.)

 

Notes on security

Locki uses a single Lima VM which can only access the ~/.local/share/locki/worktrees and ~/.local/share/locki/home folders (honoring $XDG_DATA_HOME), which forms the security boundary. The sandboxed programs can read and write to these folders, and also access anything on the internet and local network. Furthermore, a guest-to-host SSH server exposes a limited set of git and gh subcommands, with write access restricted to the sandbox's own namespaced branches and stashes (so an agent in one sandbox cannot alter another sandbox's branch, the main branch, or unrelated stashes). .git files are checked for tampering when hooks are executed against them.

Locki is designed to provide protection for the host operating system and files from being messed up by a malfunctioning AI agent. There is no exfiltration protection, so be aware that API keys exposed to the agents need to be treated as potentially exposed and disposable, with limited scope. (This is no different from running the agent locally, just specifying that Locki does not help here. Use a dedicated solution like DAM! if interested.)

Locki may not provide perfect security, however we believe it works better than many existing sandboxing solutions and certainly better than going full --yolo on your bare machine and hoping for the best.

 

How it works

  • Python CLI driving a single Lima VM (both limactl and Lima's guest agents are bundled in the platform wheels — no separate install) that hosts many lightweight Incus containers, one per sandbox. The VM is sized to your full host RAM and CPU count with a 200 GiB sparse disk.
  • A host daemon provides the git/gh/port-forward command bridge (over an SSH forced command bound to loopback) and idles containers and the VM back down when unused.
  • Shared caches across all sandboxes keep repeat work fast: a pull-through container-registry cache (nginx), a shared BuildKit daemon (Docker layers cached across sandboxes), package caches for Mise, cargo, npm/pnpm, pip/uv, go, and more, plus GitHub-release and k3s-installer caching.
  • btrfs with bees deduplication for the container pool, so many similar sandboxes cost little disk. node_modules and .venv are redirected to the shared cache via a per-sandbox symlink (so opening a worktree on the host shows a symlink, not a real directory).
  • Mise provides on-demand, version-managed tools inside each sandbox.

 

Uninstall

locki vm delete            # stop and remove the Lima VM
uv tool uninstall locki    # remove the CLI
rm -rf ~/.local/share/locki ~/.config/locki   # worktrees, shared home, config (honors $XDG_*)

 

Troubleshooting

  • Something is wedged? locki vm delete recreates the VM from scratch on the next run; worktrees and settings are preserved.
  • Command bridge proxy is disabled — the host daemon didn't come up in time; re-run the command, and check ~/.local/state/locki/logs/daemon.log.
  • On Linux, "requires QEMU" — install QEMU (qemu-system-<arch> + qemu-img).
  • VSCode worktree sidebar empty — set "git.detectWorktrees": true (needed on VSCode 1.115.0+).

 

License

Copyright 2026 Jan Pokorný and contributors

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

locki-0.0.24.tar.gz (73.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

locki-0.0.24-py3-none-manylinux_2_34_x86_64.whl (20.9 MB view details)

Uploaded Python 3manylinux: glibc 2.34+ x86-64

locki-0.0.24-py3-none-manylinux_2_34_aarch64.whl (18.9 MB view details)

Uploaded Python 3manylinux: glibc 2.34+ ARM64

locki-0.0.24-py3-none-macosx_12_0_x86_64.whl (21.3 MB view details)

Uploaded Python 3macOS 12.0+ x86-64

locki-0.0.24-py3-none-macosx_12_0_arm64.whl (24.4 MB view details)

Uploaded Python 3macOS 12.0+ ARM64

locki-0.0.24-py3-none-any.whl (79.9 kB view details)

Uploaded Python 3

File details

Details for the file locki-0.0.24.tar.gz.

File metadata

  • Download URL: locki-0.0.24.tar.gz
  • Upload date:
  • Size: 73.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for locki-0.0.24.tar.gz
Algorithm Hash digest
SHA256 670658c42b5e8c0212fc7847ff488df23119f18f6aa11094e1943d2cdcef39c4
MD5 eda8172be3fbb08c5109745d62d3230d
BLAKE2b-256 cf90dc66a630a1167f369619381d4557a1e687abaafcbea57bc8fc39467abda3

See more details on using hashes here.

File details

Details for the file locki-0.0.24-py3-none-manylinux_2_34_x86_64.whl.

File metadata

  • Download URL: locki-0.0.24-py3-none-manylinux_2_34_x86_64.whl
  • Upload date:
  • Size: 20.9 MB
  • Tags: Python 3, manylinux: glibc 2.34+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for locki-0.0.24-py3-none-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 13c94d3e5bb077faf81f131928055137a55d0c91f44371d422629aa6fa2790f3
MD5 b1158aec35b62ad7fcf8b352f72a574a
BLAKE2b-256 e8bdade05eddc8b5c3a78770668a31dbade0e4ac855698febbed3a246832fd03

See more details on using hashes here.

File details

Details for the file locki-0.0.24-py3-none-manylinux_2_34_aarch64.whl.

File metadata

  • Download URL: locki-0.0.24-py3-none-manylinux_2_34_aarch64.whl
  • Upload date:
  • Size: 18.9 MB
  • Tags: Python 3, manylinux: glibc 2.34+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for locki-0.0.24-py3-none-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 406b0d4772e64a703082733d676a1c5d430f9645ea53da126714f1ae6220ddb3
MD5 7f14a405fefc77879ebc3c7c66136cdf
BLAKE2b-256 55d8b2548d91394d0377dba1cce5246b1e6321c7f9cfe3535773e9f28f53c0cc

See more details on using hashes here.

File details

Details for the file locki-0.0.24-py3-none-macosx_12_0_x86_64.whl.

File metadata

  • Download URL: locki-0.0.24-py3-none-macosx_12_0_x86_64.whl
  • Upload date:
  • Size: 21.3 MB
  • Tags: Python 3, macOS 12.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for locki-0.0.24-py3-none-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 b5154aa0e9926e8159f2d182ed09fcc3a4e82d3eab211a2475d106d3522704ab
MD5 070536df0b6ac751e48a52f99d803f6a
BLAKE2b-256 e484b76e00f2bd1c06b3895c0de6d8ba45853f0b341430cc9b0d172631c13ea0

See more details on using hashes here.

File details

Details for the file locki-0.0.24-py3-none-macosx_12_0_arm64.whl.

File metadata

  • Download URL: locki-0.0.24-py3-none-macosx_12_0_arm64.whl
  • Upload date:
  • Size: 24.4 MB
  • Tags: Python 3, macOS 12.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for locki-0.0.24-py3-none-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 7b77dfc44f6963deaf5b882068358233690f98cb7dee2d9064ed2f6ff88c0696
MD5 37cadf275596b8308f3013ae597074c2
BLAKE2b-256 2af36d77f6b34eb96bad9b5b5ae75367251e7143950c7cf0ed43b0fd2dc15967

See more details on using hashes here.

File details

Details for the file locki-0.0.24-py3-none-any.whl.

File metadata

  • Download URL: locki-0.0.24-py3-none-any.whl
  • Upload date:
  • Size: 79.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for locki-0.0.24-py3-none-any.whl
Algorithm Hash digest
SHA256 9ef86068d97ef9fe4a4acbdfe9d8591af841e1bbc7b523b30d3a322f0ec1537f
MD5 1ad60b94949449d1a7402cfac0438be4
BLAKE2b-256 ea824e73aa50700ac4d9e9bcfc6c4895d7807300c5197db66b28be481f14c0c1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page