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 addcalls.
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:
- Declare your product once, a
kit.Productwith its names (binary, console account, clients group, keychain service, env prefix), and pass it everywhere. - Register your refusal codes with
refusal.Register: they are part of your client protocol. - Implement
console.Backend: your IPC methods,Connect,Checks,LoadPolicyandStatus. - Start the console with one call,
console.Run(ctx, P, backend, opts), launched by lockhub (lox run) with the hub options. - Expose MCP tools with
mcpkit(each a thin adapter overclient.Call) and wire the agents withagentwire. - Implement the launcher verbs (
init,profile add,doctor) withverbs, solox addcan 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 |
🎭 Masking built in |
|
✍️ Signed tickets |
🔌 Any MCP client |
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.