Local-first · Open source · Agent-safe

lockit

Secrets your agents can use. Never see.

Store each key once. lockit injects it into the process that needs it—without putting the value in a .env, shell history, or agent transcript.

curl -fsSL https://raw.githubusercontent.com/Ishaannarang22/lockit/v0.11.1/install.sh | sh
Read the docs

Installs the CLI, shell completion, and Claude + Codex skills. No account required.

AGENT / ~/acmevalue-free view
agent> starting the app with admitted secrets
$ lockit run -- npm start
 STRIPE_KEY      hasValue
 DATABASE_URL    hasValue
server ready          
Agent-facing output stays value-free. A child process can still leak what it receives. See the boundary.
A river winding through a monumental mountain valley at blue hour
Keep the value off the screen.Keep the work moving.
Encrypted locallyXChaCha20-Poly1305
Human-gated admissionTouch ID / OS authentication
Value-free agent outputslugs · fields · hasValue
Ciphertext-only sharingX25519 · HPKE

60-second start

Your first protected run.

Install the CLI and agent skills, store one value through stdin, admit its reference to a project, then run. No account or service setup.

  1. 01 / Install

    Get the CLI.

    curl -fsSL https://raw.githubusercontent.com/Ishaannarang22/lockit/v0.11.1/install.sh | sh
  2. 02 / Store

    Enter a value once.

    lockit set stripe/prod STRIPE_KEY
    Paste the value via stdin; it never enters argv.
  3. 03 / Admit

    Choose this project’s access.

    lockit init
    lockit admit stripe/prod#STRIPE_KEY
  4. 04 / Run

    Start the process.

    lockit run -- npm start

The project-world sandbox

The agent can ask.
Only you can admit.

Every project starts with an empty, value-free vault. An agent may request a secret by name, but crossing into that project requires human confirmation and local authentication.

An interactive demonstration of a secret moving from the protected store, through a human authentication gate, into the project world and child process. The agent sees metadata only.

01 · protected store stripe/prod encrypted value
02 · request Agent asks STRIPE_KEY by name
03 · human gate Confirm + authenticate Touch ID / OS auth
04 · project world
STRIPE_KEYstripe/prod
Value-free slot committable reference
05 · child process Value injected in memory at runtime
Agent can seestripe/prod · STRIPE_KEY · requested
Process receivesnothing · admission pending
The request stops at the human boundary.
01 / Output

Names and structure, never values.

02 / Admission

Human presence is required at the boundary.

03 / Resolution

Exact match or a hard error. lockit never guesses.

Sets + Slots

Rotate once.
Every project follows.

lockit stores secrets by portable slug—not by environment-variable name. Projects commit value-free Slots that reference the right Set locally.

Global store · Set

supabase/acme

schema supabase

  • urlhasValue
  • anonKeyhasValue
  • servicehasValue
Project world · Slots

dashboard

urlSUPABASE_URL

urlNEXT_PUBLIC_SUPABASE_URL

admin

urlVITE_SUPABASE_URL

01

References, not copies.

Rotate the source once. Every admitted consumer follows.

02

Collisions stop the run.

Duplicate injected environment names are a hard error—never last-write-wins.

Stored once admitted deliberately injected only at runtime

From vault to process

Four commands.
One controlled path.

~/code/app01 · store
# value enters through stdin, not command history
$ lockit set stripe/prod STRIPE_KEY
  paste value via stdin · press Ctrl-D
 stored · stripe/prod → STRIPE_KEY

The value is encrypted into your local store. It is never included in argv.

Designed around constraints

Security is the architecture,
not a badge.

01

Pure cryptographic core

packages/crypto performs no filesystem, network, or environment I/O.

Architecture ↗
02

Strict project boundary

A project can use only secrets admitted to its project world.

Threat model ↗
03

Exact resolution

Zero means missing; one resolves; many return a value-free hard error.

Data model ↗
04

Ciphertext-only server

Encryption and decryption remain client-side. No operator master key exists.

Cryptography ↗

Honest limits

Containment is not omnipotence.

  1. 01

    A child process holds the real value while it runs. A malicious command can still exfiltrate it.

  2. 02

    Node’s garbage collector means lockit minimizes plaintext lifetime, but cannot promise a guaranteed memory wipe.

  3. 03

    Lose your passphrase and every enrolled device, and your encrypted data cannot be recovered.

Read the full threat model

Start local

Set it once.
Run anywhere it belongs.

Open source. Local-first. No account or server required for local use.

curl -fsSL https://raw.githubusercontent.com/Ishaannarang22/lockit/v0.11.1/install.sh | sh