lock family docs GitHub

Locks · lockkit

lockkit

The shared Go core of every Lock: write the operations,
get the console, the approvals, the masking and the audit for free.

lockkit is the shared foundation of the Lock Family, harness security for AI agents. It holds everything that keeps a secret-holding console separate from an AI agent, asks the human, and records what happened.

A product supplies its names and its operations, through a Backend; lockkit supplies the rest.

Note

No stability promise before v1. Products pin an exact version. GUIDE.md is the contract between lockkit and the products built on it.

Why lockkit #

  • One security model for every Lock. The console, its isolated account and socket, and the policy review behave the same in locksql, lockmq, lockfile, lockhttp, locklog and lockssh.
  • The AI tightens, only the human loosens. Policy files, their review and the approved store are shared code, not re-implemented per product.
  • Masking and audit you do not write twice. Personal-data detectors, masks, capped output, error scrubbing and the append-only audit log.
  • One contract with the hub. Signed tickets and decisions, the client for lockhub, and the launcher verbs lox add calls.

Install #

lockkit is a Go library (Go 1.26 or later). Pin an exact version:

go get github.com/DavidGodefroid/lockkit@v0.14.0

To work on a Lock and lockkit together, use an uncommitted go.work (see GUIDE.md § 15).

Quick start #

A new Lock builds on lockkit in a few steps, each detailed in GUIDE.md:

  1. Declare your product once, a kit.Product with its names (binary, console account, clients group, keychain service, env prefix), and pass it everywhere.
  2. Register your refusal codes with refusal.Register: they are part of your client protocol.
  3. Implement console.Backend: your IPC methods, Connect, Checks, LoadPolicy and Status.
  4. Start the console with one call, console.Run(ctx, P, backend, opts), launched by lockhub (lox run) with the hub options.
  5. Expose MCP tools with mcpkit (each a thin adapter over client.Call) and wire the agents with agentwire.
  6. Implement the launcher verbs (init, profile add, doctor) with verbs, so lox add can set your Lock up.
var P = kit.Product{
	Name:            "lockmq",                                     // binary, .lockmq/, <config>/lockmq, sockets
	Tagline:         "Your AI reads the queue. You hold the key.", // banner
	Account:         "lockmq",                                     // console account
	ClientsGroup:    "lockmq-clients",                             // may reach the console
	KeychainService: "lockmq",                                     // OS keychain service
	EnvPrefix:       "LOCKMQ_",                                    // LOCKMQ_RUNTIME_DIR, ...
}

Highlights #

🖥️ The console, done
console.Run does the isolation checks, the policy review, the secret (ask, OS keychain or Vault), the socket and the request loop. Your Backend only runs operations.

🎭 Masking built in
pii detects emails, phones, IBANs, cards, national IDs, public IPs and secrets; render caps and escapes output; sanitize scrubs errors.

✍️ Signed tickets
ticket is the lock ↔ lockhub contract: RFC 8785 canonical JSON, Ed25519 signatures, X25519 sealed boxes. hubclient submits tickets and waits for signed decisions.

🔌 Any MCP client
mcpkit gives the MCP plumbing; agentwire wires Claude Code, Codex, Cursor and Gemini CLI to your server, in a project or for the account, merging and never clobbering.

How it works #

lockkit splits a Lock in two sides that never share an account:

  • The human side, console: it holds the credentials and the only connection, shows the policy for approval, and serves a socket. In hub mode it sends masked, signed tickets to lockhub and acts only on a decision signed by the hub key it pinned.
  • The agent side, client + mcpkit: secret-free. It dials the console's socket (peer credentials checked by the kernel) and calls it over newline-delimited JSON-RPC 2.0.

The product plugs its own operations in between, through console.Backend.

Packages #

Area Package Owns
Product kit kit.Product: a product's names and directories
refusal refusal codes registry, refusal.Error, structured Info
Human side console terminal, approvers (typed, desktop, fingerprint), isolation checks, request loop, the generic Server and Run that host a Backend
ui palette, banner, status marks of human-facing output
fingerprint fprintd verification (desktop security level 2) and a fake for tests
sysconf the machine-wide /etc/<name>/system.toml of the separated setup; process, tty and relay probes
Config and secrets config config lookup, secret-safe TOML decoding, profiles, Policy, diff helpers, approved store
managed the company-managed managed.toml of the family: root-owned, optionally signed, bounds users may tighten but never loosen
secrets credential sources: terminal prompt, OS keychain, Vault CLI; Sanitize, Wipe
plans a lock's persisted plans awaiting a decision: bound, single use, 0600
Data protection pii value detectors, mask modes, name heuristics, the redacted-reference store
render capped, escaped output for agents: Value and Table
sanitize error text scrubbing and terminal-safe text
audit the console's append-only JSONL audit log
Transport ipc console socket, peer credentials, 1 MiB JSON-RPC 2.0 framing, lockkit's methods and error codes
client the secret-free side: dial, hello, Call
tunnel SSH bastion: known_hosts, key/agent/password auth, Dial and NewSession through it
lazyconn backend connections opened on a connect ticket's approval, closed when idle
Hub ticket signed tickets and decisions, risk classes and TTLs, ticket kinds, canonical JSON, sealed boxes
hubclient a lock's client for lockhub: Submit, long-poll of decisions, Begin/Finish, Ask; hubclient/hubtest fake hub
Agent side mcpkit MCP server and stdio, profile resolution, progress while the human decides, untrusted framing, structured refusals
agentwire wiring Claude Code, Codex, Cursor and Gemini CLI to your MCP server
verbs the launcher verbs every lock shares (init, profile add, doctor) and the JSON lox add reads
Release update cosign keyless signature check of a release artifact, checksums

The full map, with what not to reimplement in your product, is in GUIDE.md § 1 and § 11.

Who uses it #

Every Lock is built on lockkit: locksql, lockmq, lockfile, lockhttp, locklog and lockssh. lockhub uses its ticket package to verify what the locks sign, and lea builds on it too.

Safety model #

  • The agent side holds no secret: credentials, the connection and the approved policy stay in the console's separated account.
  • The boundary is the operating system's: separate accounts, the kernel's peer credentials on the socket.
  • A policy change the agent proposes can only tighten; loosening is asked of the human, and on production takes the typed profile name.
  • In hub mode, a lock executes only on a decision signed by the hub key it pinned, bound to the exact plan that was approved.
  • Masking is best effort. PII detection quality: precision and recall per detector and language on a synthetic bench, held to a CI baseline, in pii/testdata/bench/RESULTS.md; its Known gaps section lists what the detectors miss most.

Details: GUIDE.md § 6, § 10 and § 13.