Skip to main content

AI sandboxing without the taste of sand

Project description

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 sandoxes break down on anything more complex than "a single Next.js app". Locki can handle as many containers, systemd services and even Kuberentes 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-build 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-build 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.

 

Comparison

Most sandboxing solutions use one of these techniques:

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

To my knowledge Locki is the only one packing a fully vertically integrated Incus-based solution. 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. Supported: VSCode, Zed, Fresh -- PR if you want to add your favorite.
    (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 ... to select by sandbox id or branch name.

  • 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.)

  • locki list shows worktree paths. cd to a worktree folder (~/.local/share/locki/worktrees/...) to operate on it directly. locki commands default to operating on the corresponding sandbox when in worktree folder.

  • 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>/. 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; change it later in ~/.config/locki/config.toml under [ai] harness = "...".

  • 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 rootfs tarball by path. Example:

    # locki.toml
    
    [incus_image]
    aarch64 = "ubuntu/questing"
    x86_64 = "ubuntu/questing"
    

    (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 OneCLI if interested.)

Despite best effort, Locki provides no security guarantees and is provided "as is". That's the legal speak for "this is a random project by a random dude provided for free", you can't expect corporate-paid-support level security assurances. Random dude believes that while not perfect, using Locki is better than many existing sandboxing solutions and certainly better than going full --yolo on your bare machine and hoping for the best.

 

Tech

  • Python CLI
  • Single Lima VM
  • Multiple Incus containers
  • Mise for ergonomic package installation
  • Host proxy for bridged commands (git, gh, port forwarding)

Project details


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.17.tar.gz (39.3 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.17-py3-none-manylinux_2_34_x86_64.whl (20.8 MB view details)

Uploaded Python 3manylinux: glibc 2.34+ x86-64

locki-0.0.17-py3-none-manylinux_2_34_aarch64.whl (18.8 MB view details)

Uploaded Python 3manylinux: glibc 2.34+ ARM64

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

Uploaded Python 3macOS 12.0+ x86-64

locki-0.0.17-py3-none-macosx_12_0_arm64.whl (24.3 MB view details)

Uploaded Python 3macOS 12.0+ ARM64

locki-0.0.17-py3-none-any.whl (48.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: locki-0.0.17.tar.gz
  • Upload date:
  • Size: 39.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","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.17.tar.gz
Algorithm Hash digest
SHA256 e5bfff747d627860c5f350c974eb8056f145aa557c5be24b379e466327fe1915
MD5 8b874c80d72f2c30f40259243bb4e5e6
BLAKE2b-256 9648a0d71dad1606a9a25c4cb5395b4cb3669572627b6fb123b7fd8f7d353ff9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.17-py3-none-manylinux_2_34_x86_64.whl
  • Upload date:
  • Size: 20.8 MB
  • Tags: Python 3, manylinux: glibc 2.34+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","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.17-py3-none-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 0a97053cb3d5d4850a4504e3858a18b7102581d40b9d77f440bbd7f220e78f25
MD5 356d06d52892aea5a0213cac0b2fda10
BLAKE2b-256 34f88c336c87fee3e888b417e2b03889e24a8ca249a7fd6d23df7056d5469d44

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.17-py3-none-manylinux_2_34_aarch64.whl
  • Upload date:
  • Size: 18.8 MB
  • Tags: Python 3, manylinux: glibc 2.34+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","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.17-py3-none-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 d1758bb50e4971a29ae2245d45103c8d128c20fc03b202abfa090b81dc0de05f
MD5 a1a3723ffef2b7594ecd75c42699fffb
BLAKE2b-256 fb3667ee232655e13f318970a4e4d46149522c7a37e8403558a22f0298d8d1df

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.17-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.12 {"installer":{"name":"uv","version":"0.11.12","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.17-py3-none-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 9275e4ebb9238fe0abb0d1751155b84ea03a27cfd8900990aa37dd099c014c9f
MD5 7a57f55bd324868a99c2ac855863009f
BLAKE2b-256 f681a1f198c082e81033c89bc2eb9abdefb386860457bf2a5f0c78efb2b0e5ac

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.17-py3-none-macosx_12_0_arm64.whl
  • Upload date:
  • Size: 24.3 MB
  • Tags: Python 3, macOS 12.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","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.17-py3-none-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 c12286bf516944609e66f21cc33211a06716d4e20ce37db4cb6f32a79335b6a9
MD5 eb1b8babe9db95b7e50c535a065f2f8b
BLAKE2b-256 60191670f3b25be8c45b84e6e3e2d728c890ec6acdcb16918f082bfd08a4c490

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.17-py3-none-any.whl
  • Upload date:
  • Size: 48.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","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.17-py3-none-any.whl
Algorithm Hash digest
SHA256 931150a7d58140d2a220d538a1da39097f36d21a1eaa539d128fde4dd90d3e9d
MD5 3a115c7343879b5bddd6f986824cce8e
BLAKE2b-256 3d6bf7ecd058cf881a3dd632d69fe8ab6b4f68609f8f9cabe050257425d1d54e

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