Leash wraps AI coding agents in containers and monitors their activity. You define policies in Cedar; Leash enforces them instantly.
- Docker, Podman, or OrbStack
- macOS or Linux (WSL, too!)
Recommended method is via npm:
npm install -g @strongdm/leashAlternative ways follow:
Download the latest pre-built release binary from the releases page.
or if you're on macOS:
brew tap strongdm/tap
brew install --cask leash-appmacOS Note 1: This installs a helper app that enables experimental native mode on macOS and also installs the leash formula.
macOS Note 2: If you download Leash from the releases page, you'll need to run xattr -d com.apple.quarantine leash after extracting it
Refer to MACOS.md to learn more about the additional native macOS capabilities.
# Launch codex with the Control UI and pop open the web browser automatically
leash --open claude
leash --open codex
# Inspect available options
leash --helpAI agents claude, codex, gemini, qwen, and opencode are shipped in the default coder image.
On first use Leash will prompt to mount the host's coder-agent config directory (for example ~/.claude) into the container.
Choose whether to remember that decision globally, for the current project, or just this once; persistent choices are stored at ~/.config/leash/config.toml.
-
Full monitoring captures every filesystem access and network connection initiated by the agent so Cedar policies and audit trails operate on complete telemetry.
-
Agent container runs your command with the current directory bind-mounted, so tools see the same file tree they would on the host.
-
Leash container monitors system calls, applies Cedar policies, and exposes the Control UI at http://localhost:18080 (use
--opento launch it automatically). -
Mount prompts remember whether to forward host agent credentials (see CONFIG.md).
-
Environment forwarding maps common API keys automatically:
ANTHROPIC_API_KEYforclaude,OPENAI_API_KEYforcodex,GEMINI_API_KEYforgemini, andDASHSCOPE_API_KEYforqwen.
Leash includes a Model Context Protocol (MCP) observer that inspects, records, and enforces MCP tool calls made by the agent. Requests flowing through supported MCP transports are correlated with filesystem and network telemetry, enabling Cedar policies to govern tool use alongside core runtime activity.
- Keep the default
public.ecr.aws/s5i7k8t3/strongdm/coderimage for a ready-to-run AI tooling environment. - Extend Dockerfile.coder with project packages, then point Leash at the new image.
- Reuse an existing project image by adding
ca-certificatesand configuring Leash to launch it.
Configure alternative images through TOML, CLI flags, or environment variables:
[leash]
codex = true
[projects."/absolute/path/to/project"]
target_image = "ghcr.io/example/dev:latest"
[projects."/absolute/path/to/project".volumes]
"~/devtools" = "/workspace/devtools:rw"| Configure | Use | Notes |
|---|---|---|
| Target image | target_image in config.toml, |
Defaults to public.ecr.aws/s5i7k8t3/strongdm/coder. |
LEASH_TARGET_IMAGE, or --image flag |
||
| Target container base | TARGET_CONTAINER |
Auto-sanitized from the current directory when unset. |
| Exact agent container | --container-name |
Force the exact agent container name (no sanitization, no collision suffix; leash container becomes <name>-leash). |
| Leash manager image | --leash-image, LEASH_IMAGE |
Native releases default to their matching immutable ghcr.io/sixtoad/leash-manager@sha256:...; compatible labeled overrides remain supported. |
| Container runtime | --runtime, LEASH_RUNTIME |
Which container CLI to drive: docker (default) or podman. |
| Cedar policy file | --policy, LEASH_POLICY_FILE |
Mount a specific Cedar policy. |
| Control UI bind address | --listen, LEASH_LISTEN |
Blank value binds to default 127.0.0.1:18080 |
| Agent docker network | --network, LEASH_NETWORK |
Attach the agent to an existing docker network (e.g. a compose network) so it can reach sibling services. |
| Extra bind mount | -v src:dst[:ro] |
Repeatable for multiple mounts. |
| Environment variables | -e KEY=value |
Forwarded into both containers. |
Run ./bin/leash --help for a complete list of flags and environment variables.
See CONFIG.md and CUSTOM-DOCKER-IMAGES.md for more information.
Choose your own project-specific mounts and set additional environment variables as needed:
leash -v ~/.myconfig:/root/.myconfig claude bash
leash -e MY_VAR=value codex bashDive deeper with CEDAR.md for ready-to-adapt snippets.
Policy files are strict Cedar by default: any matching forbid denies, otherwise a matching permit allows, otherwise the request is denied (MCP calls included). A policy written for Leash's older legacy dialect (most specific rule wins, File:: as a path prefix, MCP allowed unless forbidden) must be converted with leash policy migrate <file> --write, or marked @leash_semantics("legacy") to keep its old meaning. leash policy lint <file> warns when an unmarked file looks written for the legacy dialect.
- Telemetry details live in TELEMETRY.md.
- macOS: Docker runtimes that run inside a VM (Docker Desktop, colima, OrbStack, Rancher) only share the host paths you grant them. Leash anchors its per-run work directory under
~/.leash/runprecisely because the home directory is shared by default — the system temp dir (/var/folders) is not, which otherwise leaves the/leashmount empty and fails withstat /leash/leash-entry-linux-<arch>: no such file or directory. If you pointLEASH_WORK_DIR/LEASH_SHARE_DIRsomewhere else, make sure that path is shared into the VM (e.g.colima start --mount ~:w). - Linux: eBPF LSM (Layer 1) unavailable — leash's Layer 1 enforcement is an eBPF LSM program, which only attaches when
bpfis one of the kernel's active LSMs (cat /sys/kernel/security/lsm). Many distros shipCONFIG_BPF_LSM=ybut don't enable it at boot. This is always fatal: leash refuses to run the workload rather than run it with only the L7 proxy enforcing, and the error prints the fix — appendbpfto thelsm=list inGRUB_CMDLINE_LINUX(/etc/default/grub), thensudo update-grub && sudo reboot.--require-lsm/LEASH_REQUIRE_LSM=1are still accepted as no-ops. If the kernel lacksCONFIG_BPF_LSMentirely, you need a kernel built with it (Linux ≥ 5.7, plusCONFIG_DEBUG_INFO_BTF=y). - Linux: rootless podman and rootless Docker — a rootless container engine cannot load the eBPF LSM itself, so rootless runs get Layer 1 from the leash enforcer daemon, a socket-activated system service that holds only
CAP_BPFandCAP_PERFMONand attaches the same programs, compiled from the same policy, to your container's cgroup (enforcement=lsm, same guarantees as a rootful run). Install it once withsudo leash daemon install(then log in again so you are in theleashgroup) and check it withleash daemon status. Without it a rootless run is refused before anything starts, with that command in the error. Rootless Docker uses the same daemon: the leash client opens the daemon connection and hands it to the leash container, since Docker cannot keep yourleashgroup in a container. Setup, what is enforced and the security model: ROOTLESS.md. On SELinux hosts (Fedora, RHEL) see SELINUX.md for the project-mount label choice (--selinux). - Reset mount decisions or inspect config behavior with the tips in CONFIG.md.
- Explore the development process in DEVELOPMENT.md and CONTRIBUTORS.md.
