lock family docs GitHub

lea · Start

Quick start

brew trust davidgodefroid/tap                # Homebrew asks you to trust a third-party tap once
brew install davidgodefroid/tap/lockfamily   # the Lock Family: lea, lox and the Locks' launchers
cd ~/projects                                 # lea's projects directory, not a project inside it
lea                                           # the first run sets everything up
lox add locksql                               # when your agents need a database (lockmq, lockfile, locklog, lockhttp likewise)

brew install davidgodefroid/tap/lea installs lea alone. The journey is brew, lea, lox add: there is no separate setup command to run first.

On a first run lea initialises itself: it checks that Docker answers, pulls and verifies the images, installs its AppArmor profile on Linux hosts that use it (it needs sudo once: when sudo would prompt, lea stops with "the AppArmor profile 'lea' needs sudo once: run lea init, then lea"), records the projects directory, then opens the deck. Before all that, on a terminal and while LEA_DECK is not set, it asks once whether you want the deck or your own tool in the lea container (see Without the deck): it records the answer and the command that switches it, and opens that tool instead of the deck on a no. The projects directory is LEA_PROJECTS_DIR when you preset it (in the environment or in ~/.config/lea/lea.conf: a preset value wins over the working directory); when it is unset, it is the directory you ran lea from. If that directory cannot be one (/, your home directory or a parent of it, or one that overlaps ~/.claude or a credentials directory), lea says why and to cd into the directory that holds your projects and run lea again, or LEA_PROJECTS_DIR=DIR lea.

Approvals live outside lea, in lox run. lea runs no lox command: it starts no hub (no lox init) and shows no approval, ticket or lock console. Keep lox run open in a terminal of its own, outside lea (lox 0.9.0 or later: brew install davidgodefroid/tap/lox): it starts the projects directory's hub and locks, shows every request of the agents, approves reads on its own and asks you for connections and writes. When the projects directory declares locks (.lockfamily/lockfamily.yaml) and no lox run serves them, lea says, as it starts: "Open another terminal (outside lea) and run lox run to approve the agents' connections and writes." lea starts anyway: the agents reach the locks' sockets, and their requests wait at the hub until lox run decides them. The deck's status line and lea doctor say the same while it does not serve. LEA_LOX_UP is obsolete: lea warns when it is set, and ignores it.

lox add is how a Lock gets set up for lea's agents, run in lea's projects directory (lea reads .lockfamily/up.json only there; a plain claude on the host uses the nearest one from the project up). A tool (locksql, lockmq, lockfile, locklog) is on for lea once lox run runs a lock of its type there: you need not turn it on, and LEA_<TOOL>=0 in ~/.config/lea/lea.conf keeps it off. A lock added while lea runs reaches the agents once lea restarts (lea stop, then lea): restarting an agent or the deck does not give a running container a new mount. Without Homebrew, lea's own installer:

curl -fsSL https://leadeck.dev/install.sh | sh
lea

The installer checks the requirements, downloads the release for your platform and verifies its checksum and the release's signature (see Verify a release), links ~/.local/bin/lea, then runs lea init, which asks for your projects directory and pulls the images. The first agent is a Control Tower (see Control tower); in it, run /login once (Claude Code's own login, kept per projects directory). Press n for another agent, N for another Control Tower.

Requirements #

  • Linux, macOS, or Windows with WSL2 (run lea from WSL).
  • Docker Engine (Linux) or Docker Desktop, running, usable without sudo; a patched host kernel (see How lea keeps your machine safe).
  • On macOS, tmux 3.2 or later (brew install tmux); the Linux release brings its own. Without the deck (--no-deck), only lea new needs it.
  • curl, tar, ssh-keygen.
  • A Claude subscription or API key for Claude Code.

lea never runs sudo itself, except once in lea init on Linux hosts where Docker uses AppArmor: it installs lea's AppArmor profile, and only when that profile changed.

Verify a release #

Each release is signed keyless with cosign (Sigstore, GitHub OIDC) by the release workflow, on its v* tag: checksums.txt (bundle checksums.txt.sigstore.json, a release asset) and the lea and lea-proxy images, by digest. The installer verifies checksums.txt with cosign before trusting it: the cosign on your PATH, else cosign v3.0.6, which it downloads from Sigstore's GitHub release and checks against the SHA-256 pinned in install.sh (it never fetches a "latest" cosign). It stops on a bad signature, on a missing signature, and when no cosign can be had: it never installs on the checksum alone. The only exception is v0.1.0 and v0.1.1, which predate signing: their checksums.txt must then be the genuine one, whose SHA-256 the installer pins (it stops otherwise), and the install goes on by checksum, with a warning. LEA_REQUIRE_COSIGN=1 removes that exception too. lea update and the background update verify the signature the same way before they run the new release's installer. Each tag also bumps the lea formula of the Homebrew tap (brew trust davidgodefroid/tap, then brew install davidgodefroid/tap/lea), from the same signed checksums.txt.

curl -fsSL https://leadeck.dev/install.sh | LEA_REQUIRE_COSIGN=1 sh

By hand, with the same identity and issuer:

cosign verify-blob --bundle checksums.txt.sigstore.json \
  --certificate-identity-regexp '^https://github\.com/DavidGodefroid/lea/\.github/workflows/release\.yml@refs/tags/v[0-9]' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  checksums.txt
cosign verify \
  --certificate-identity-regexp '^https://github\.com/DavidGodefroid/lea/\.github/workflows/release\.yml@refs/tags/v[0-9]' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/davidgodefroid/lea:<version>   # and ghcr.io/davidgodefroid/lea-proxy:<version>

The limit: the installer comes from the same GitHub account as the release. The signature protects against a tampered asset or mirror, and every signature is logged publicly (Rekor), so it can be audited; it does not replace trusting that account.