Make leaked API keys worthless.
Your API key is split in two. Neither half works alone. The proxy enforces a hard spend cap before the key reconstructs — blow the budget, the key never forms, the request never leaves your machine.
curl -sSL https://worthless.sh | sh # fresh machine — no Python needed
# or, if you already have Python 3.10+:
pipx install worthlessThen, in your project:
cd your-project
worthlessDetects keys in your .env, splits them, starts a local proxy. No code changes.
Piping a script from the internet into sh is a supply-chain risk. Read it first:
curl -sSL https://worthless.sh -o install.sh
less install.sh # inspect, then run
sh install.shSee docs/install-security.md for trust roots (what the installer talks to and what it verifies) and the kill-switch runbook.
$ worthless
Found 2 API keys:
OPENAI_API_KEY openai
ANTHROPIC_API_KEY anthropic
Lock these keys? [y/N] y
OPENAI_API_KEY locked
ANTHROPIC_API_KEY locked
Proxy ready on 127.0.0.1:8787
worthless locksplits each API key into two shards using XOR- Shard A stays on your machine (encrypted). Shard B goes to the proxy database.
- Your
.envis rewritten with shard-A (format-preserving — looks like a real key but is cryptographically useless alone) - The proxy reconstructs the key only when the rules engine approves the request
- Spend cap blown? The key never forms. The request never reaches the provider.
worthless # Auto-detect, lock, start proxy (the magic)
worthless lock # Lock keys in .env
worthless unlock # Restore original keys
worthless scan # Detect exposed keys without locking
worthless status # Show proxy and key status
worthless up # Start proxy (foreground)
worthless up -d # Start proxy (background daemon)
worthless down # Stop the proxy
worthless wrap <cmd> # Run a command through the proxy
worthless revoke # Revoke enrolled keysdocker run ghcr.io/shacharm2/worthless-proxy:<version> — multi-arch, vulnerability-scanned, cosign-signed. See docs/install-docker.md.
Worthless runs on POSIX hosts. The proxy relies on setsid, os.killpg,
fd-based key transport, and signal-group shutdown — primitives that have no
reliable native-Windows equivalent. Rather than degrade silently, the CLI
refuses to start on native Windows and tells you how to run it under WSL or
Docker.
| Platform | Status |
|---|---|
| macOS | Supported |
| Linux | Supported |
| Windows + WSL | Supported |
| Windows + Docker | Supported |
| Native Windows | Not supported — up, wrap, and the default command exit with WRTLS-110. down is allowed so existing state can be cleaned up. |
WORTHLESS_WINDOWS_ACK=1 suppresses the soft warning on down; it does not
bypass the hard gate on the other entry points.
Planned: native-Windows support (stdin Fernet key transport, Windows Job
Objects, DETACHED_PROCESS) is tracked in
WOR-237 —
target v1.2. If you need it sooner or want to help, comment on the issue
rather than patching around the guard locally.
curl worthless.sh | sh bootstraps uv and worthless with no Python required
on the target host. Coverage (run via pytest -m docker):
| Host | Status | Notes |
|---|---|---|
| Ubuntu 24.04 (bare) | Supported | no python, no uv |
| Ubuntu 22.04 (bare) | Supported | still the LTS most prod/CI boxes run |
Ubuntu 24.04 + pre-installed uv |
Supported | asserts uv is reused, not reinstalled (sha256 check) |
| Debian 12 (bare) | Supported | second glibc distro |
| Alpine / musl | Supported | uv fetches musl-compatible Python via PBS; zstd required for modern tarballs |
| macOS (Intel / ARM) | Supported | manual test on dev boxes |
| Fedora / RHEL | Untested | — |
| Windows + WSL | Untested (expected to work) | — |
| Native Windows | Not supported | see Platforms section |
All distros are pinned to linux/amd64 so arm64 hosts still exercise amd64
coverage. Per-distro verification runs verify_install.sh — checks resolved
binary path, --version, --help (exercises lazy imports), and scans stderr
for Traceback / ModuleNotFoundError.
$ worthless unlock
1 key(s) restored.Original key is back. No trace.
repos:
- repo: https://github.com/shacharm2/worthless
rev: main
hooks:
- id: worthless-scanWorthless ships a SKILL.md that tells Claude Code, Cursor, and Windsurf what commands are available. Agents use --json for structured output:
worthless status --jsongit clone https://github.com/shacharm2/worthless && cd worthless
uv sync --extra dev --extra test
uv run pytest- Security model -- threat model, invariants, known limitations
- Engineering docs -- internal developer documentation for the live codebase
- Engineering architecture -- current internal architecture overview
- Contributor security rules -- invariants all contributions must preserve
- SKILL.md -- agent discovery file
PRs welcome. Read CONTRIBUTING-security.md first.