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 a CLI that safely runs AI agents with all permissions bypassed in isolated worktrees.

❌ without Locki ✅ with Locki
git worktree add -b fix-42 ../fix-42
cd ../fix-42
claude "fix issue #42"
# ...wait a few seconds
# ...approve a command
# ...wait a few seconds
# ...approve another command
# ...different agent rebuilt the image
#    and caused a name clash‽
# ...something is hogging the port‽
# ...approve another command
# ...
locki x claude "fix issue #42"
# ...go make a cup of tea
# ...drink tea 🍵
# ...look, the PR is ready

 

Selling Points

  • First-class DX: locki ai, work in your CLI of choice. Zero config. No sign Locki is even there.
  • No compromises: Run anything including systemd, containers, even Kubernetes clusters.
  • Safe Git: Sandboxes 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 you're on Linux, also install OpenSSH (usually preinstalled) and QEMU.

  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)

 

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

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

Uploaded Python 3manylinux: glibc 2.34+ x86-64

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

Uploaded Python 3manylinux: glibc 2.34+ ARM64

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

Uploaded Python 3macOS 12.0+ x86-64

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

Uploaded Python 3macOS 12.0+ ARM64

locki-0.0.15-py3-none-any.whl (47.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: locki-0.0.15.tar.gz
  • Upload date:
  • Size: 38.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","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.15.tar.gz
Algorithm Hash digest
SHA256 78a8d8068e9e982634eb4c4b619ce4eb66e683ee98b7c1fb87938879983fc4b3
MD5 e73a483c40df1dc4aff9ff0e5b87e454
BLAKE2b-256 4b5f23655012f954bc96e7c073527dd62fdc35f7b9eec76a0634297c2b779b3b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.15-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.11 {"installer":{"name":"uv","version":"0.11.11","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.15-py3-none-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 afe77d67e8b6122c20f012e96cdf78e566fb58f4495b8c26d3306c0a469eab9d
MD5 376f75db20f123168666c05a910ab3ad
BLAKE2b-256 3b56c4575531e69aa44fc7b7b8fa406a76bda0a22d502490c8a366da62347875

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.15-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.11 {"installer":{"name":"uv","version":"0.11.11","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.15-py3-none-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 d6e912c2da56b4b4fdb3a99fc5861efde3bf48bb34cfb3a4f7a0987580684c8e
MD5 c000e36c377258a65ef63369c0ae06c6
BLAKE2b-256 8839ad77b92a680e134c67645d5a7d58f17b9ab9a16d68b14be327e063bcb4f3

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.15-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.11 {"installer":{"name":"uv","version":"0.11.11","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.15-py3-none-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 aa141e72d131406bc8ae881b870c00beea5b6f80841cc093f3228717063cfc57
MD5 30340a04b26a090ca3bb3b6b64f21baa
BLAKE2b-256 00fe7f264e7d6f71e951c18369dcfb717f51ee028dd80f46fa05440fb205ae52

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.15-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.11 {"installer":{"name":"uv","version":"0.11.11","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.15-py3-none-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 0a5d3d131aa5bfe2a5249d4def98c35b7b7d65dc36f4369c506b8111b6f7d44d
MD5 d9a77746cb16cf0243bd4b5808a5de0c
BLAKE2b-256 5a6892f56a353d417519d1d5362cac996fb00c57975caf83390adb3015678666

See more details on using hashes here.

File details

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

File metadata

  • Download URL: locki-0.0.15-py3-none-any.whl
  • Upload date:
  • Size: 47.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","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.15-py3-none-any.whl
Algorithm Hash digest
SHA256 1b53c7bc083d1efa73511a76550a3e0e04bc9660bea8065420db5a8436aaaa73
MD5 1bf69b373b8852dad297695b6641e8cb
BLAKE2b-256 d3a95a0253fcce9545f6289d0419ea5f18752f5d55f50b3abb98eb7c1ad1aa79

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