Skip to content
ofradesPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

lock

lock is a sudo-gated local secret vault for developer machines.

It reduces the blast radius of supply-chain attacks where code running as your normal user silently reads local secrets (.env, cloud credentials, npm tokens, deploy keys, etc.). Protected files are encrypted in place at their original paths. Commands that need plaintext must be launched through lock exec, lock run, or lock pipe.

Architecture

Rust core/CLI/daemon
  crates/lock-core   age-compatible encryption, metadata, audit
  crates/lock-cli    lock CLI
  crates/lockd       Unix socket daemon MVP

TypeScript UI
  ui/                OpenTUI manager that shells out to lock

Requirements

  • Rust toolchain
  • age + age-keygen
  • sudo
  • Bun for the OpenTUI manager

Build

cargo build

Install

cargo install --path crates/lock-cli --bin lock --locked
cargo install --path crates/lockd --bin lockd --locked

Or install both binaries, completions, and the man page under /usr/local:

make install

Build a tarball and SHA-256 checksum under dist/:

make package

Packaged installs include the TUI source under share/lock/ui. Before using lock tui from a packaged install, install its Bun/npm dependencies once:

cd /usr/local/share/lock/ui
npm install

Test

Black-box integration tests are written in Bats so the test suite stays independent from the Rust implementation.

bats tests/bats

The tests use isolated HOME/XDG directories and a fake sudo wrapper that redirects /etc/lock/identity.txt to a temporary age identity. They do not require touching the real /etc/lock.

For a real sudo smoke test on a clean machine after install:

scripts/smoke-real-sudo.sh

Set LOCK_BIN=/path/to/lock to test a non-PATH binary.

CLI usage

cargo run -p lock-cli -- init
cargo run -p lock-cli -- protect aws ~/.aws/credentials
cargo run -p lock-cli -- protect env .env
cargo run -p lock-cli -- restore env
cargo run -p lock-cli -- unprotect env
cargo run -p lock-cli -- remove aws
cargo run -p lock-cli -- remove --restore env
cargo run -p lock-cli -- rotate env
cargo run -p lock-cli -- rotate --all
cargo run -p lock-cli -- verify env
cargo run -p lock-cli -- verify --all
cargo run -p lock-cli -- inspect
cargo run -p lock-cli -- inspect env
cargo run -p lock-cli -- repair
cargo run -p lock-cli -- doctor
cargo run -p lock-cli -- doctor --json
cargo run -p lock-cli -- tui
cargo run -p lock-cli -- key export ~/lock-age-identity-backup.txt
cargo run -p lock-cli -- list
cargo run -p lock-cli -- cat aws
cargo run -p lock-cli -- edit env
cargo run -p lock-cli -- run --env DOTENV=env -- node app.js
cargo run -p lock-cli -- run --file env:.env -- npm test
cargo run -p lock-cli -- run --daemon --env DOTENV=env -- node app.js
cargo run -p lock-cli -- run --mapped -- npm test
cargo run -p lock-cli -- exec -- npm test
cargo run -p lock-cli -- pipe env -- sh -c 'cat >/tmp/secret-copy'
cargo run -p lock-cli -- daemon ping
cargo run -p lock-cli -- daemon list
cargo run -p lock-cli -- daemon cat aws
cargo run -p lock-cli -- audit
cargo run -p lock-cli -- status
cargo run -p lock-cli -- completion bash > lock.bash
cargo run -p lock-cli -- man > lock.1

Installed binary names:

lock
lockd

Daemon

cargo run -p lockd -- --cache-ttl-seconds 300

The daemon listens on the configured Unix socket, currently $XDG_RUNTIME_DIR/lockd.sock or /tmp/lockd.sock.

The MVP supports JSON lines:

{"type":"ping"}
{"type":"list"}
{"type":"decrypt","reference":"aws"}

The daemon caches decrypted secret bytes in memory for the configured TTL. lock run --daemon ... uses the daemon, so a sudo-gated decrypt can be reused during the TTL instead of prompting repeatedly.

Future daemon work:

  • per-process authorization
  • request origin inspection
  • approval TTLs per command
  • OpenTUI pending-request screen
  • command-based policy for lock exec and lock run

TUI manager

The TypeScript manager uses @opentui/core. It is intentionally outside the security-critical path and shells out to the Rust lock CLI.

Preferred launch path:

cargo build
cargo run -p lock-cli -- tui

lock tui runs sudo -v before opening the UI, then launches the OpenTUI app with LOCK_BIN set to the current lock binary.

Direct dev launch:

cargo build
cd ui
npm install
LOCK_BIN=../target/debug/lock npm run dev

Current manager actions are performed inside the OpenTUI interface with built-in inputs, modals, a viewer, and a scrollable multiline editor:

  • list secrets
  • inspect encrypted/plaintext state
  • protect file in place
  • edit selected secret in a TUI textarea, then save through lock write
  • complete path fields with Tab, relative to the directory where lock tui was opened
  • run a command through lock exec
  • remove selected secret
  • unprotect selected secret
  • repair plaintext inline files
  • view audit log
  • export the root-owned age identity backup with c

Security model

  • age-compatible encrypted blobs at rest
  • public recipient stored in user config
  • private identity stored root-owned at /etc/lock/identity.txt
  • decryption gated through sudo age -d -i /etc/lock/identity.txt ...
  • secret metadata under the user data dir: ~/.local/share/lock/...
  • audit log under user state dir: ~/.local/state/lock/audit.log
  • lock protect auto-initializes lock if config is missing, encrypts a file in place, records its path mapping, and leaves age ciphertext at the original path
  • lock restore decrypts a secret back to its mapped path or an explicit target path while keeping it encrypted in lock
  • lock unprotect restores plaintext and removes the encrypted secret from lock
  • lock remove deletes encrypted secret metadata/blob; lock remove --restore restores plaintext first
  • lock rotate decrypts and re-encrypts secrets with the current configured recipient
  • lock verify checks that encrypted secrets can be decrypted without printing plaintext
  • lock inspect reports whether managed files are encrypted, plaintext, or missing
  • lock repair re-encrypts plaintext inline files after interrupted/manual restores
  • lock pipe feeds a secret to a command's stdin without printing it directly from lock
  • lock doctor checks dependencies, config, store, and secret counts
  • lock tui asks for sudo upfront and opens the OpenTUI manager
  • lock key export <path> exports the root-owned age identity so you can back it up safely
  • lock run --file materializes plaintext into a temporary private file and removes the symlink after the command exits
  • lock run --mapped decrypts mapped inline files for the child command lifetime, then re-encrypts them on exit or Ctrl-C/SIGTERM
  • lock exec is shorthand for lock run --mapped --
  • lock completion <shell> emits shell completions
  • lock man [path] emits a man page to stdout or a file

Core supply-chain defense flow

printf 'API_TOKEN=secret' > .env
lock protect env .env

# Normal userland process only sees age ciphertext:
node -e "require('fs').readFileSync('.env', 'utf8')" # returns ciphertext, app parsing fails

# Explicitly authorized launch gets plaintext .env only for the child lifetime:
lock exec -- node app.js

We intentionally do not leave protected plaintext files in place. If .env remains readable as plaintext after protection, compromised package scripts can still steal it. The default lifecycle is:

lock protect env .env
  .env is replaced with an age encrypted blob
  lock metadata records that env maps to .env

lock exec -- command
  sudo-gated decrypt
  .env is plaintext for the child command
  .env is re-encrypted when the command exits or lock receives Ctrl-C/SIGTERM

lock unprotect env
  .env is restored as plaintext permanently
  lock metadata is removed

Current phase

lock is a usable MVP: Rust core, CLI, daemon, OpenTUI manager, and black-box integration tests are in place. The main deferred areas are packaging, shell completions/man pages, richer daemon policy, and clean-machine smoke testing with real sudo.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages