Skip to main content

Split-key reverse proxy that makes leaked API keys worthless

Project description

Worthless

Make leaked API keys worthless.

Python 3.10+ License: AGPL-3.0 Tests

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.

Quickstart

curl -sSL https://worthless.sh | sh        # fresh machine — no Python needed
# or, if you already have Python 3.10+:
pipx install worthless

Then, in your project:

cd your-project
worthless

Detects keys in your .env, splits them, starts a local proxy. No code changes.

Integrity check (transit, not origin)

Piping a script from the internet into sh is a supply-chain risk. The Worker emits an X-Worthless-Script-Sha256 header so you can confirm the saved file matches what the Worker advertised at fetch time:

# 1. Download.
curl -sSL https://worthless.sh -o install.sh

# 2. Body sha matches the header advertised by the Worker.
echo "$(curl -sSI https://worthless.sh | grep -i 'x-worthless-script-sha256' | awk '{print $2}' | tr -d '\r')  install.sh" \
  | sha256sum -c -

# 3. (Optional) read it.
less install.sh

# 4. Run.
sh install.sh

What this catches: post-download local-file tampering (between curl -o install.sh and sh install.sh), CDN cache poisoning, and Worker regressions that detach the served body from the advertised header.

What this does NOT catch: transit MITM (TLS + HSTS already prevent that — the header/body match check would be redundant if that were the only threat), or a compromised origin. The header and the body come from the same Worker; an attacker who controls the response controls both, so the sha check is not origin attestation. Real cryptographic origin attestation lands with cosign-signed release manifests — tracked in WOR-303.

See 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

How it works

  1. worthless lock splits each API key into two shards using XOR
  2. Shard A stays on your machine (encrypted). Shard B goes to the proxy database.
  3. Your .env is rewritten with shard-A (format-preserving — looks like a real key but is cryptographically useless alone)
  4. The proxy reconstructs the key only when the rules engine approves the request
  5. Spend cap blown? The key never forms. The request never reaches the provider.

Commands

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 keys

Docker

docker run ghcr.io/shacharm2/worthless-proxy:<version> — multi-arch, vulnerability-scanned, cosign-signed. See docs/install-docker.md.

Platforms

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.

install.sh / worthless.sh support matrix

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.

Undo everything

$ worthless unlock
1 key(s) restored.

Original key is back. No trace.

Pre-commit hook

repos:
  - repo: https://github.com/shacharm2/worthless
    rev: main
    hooks:
      - id: worthless-scan

For AI coding agents

Worthless ships a SKILL.md that tells Claude Code, Cursor, and Windsurf what commands are available. Agents use --json for structured output:

worthless status --json

Development

git clone https://github.com/shacharm2/worthless && cd worthless
uv sync --extra dev --extra test
uv run pytest

Learn more

Versioning

Three identifiers, kept loosely aligned:

  • PyPI version (pip install worthless==0.3.2) — canonical Python package. Source of truth: pyproject.toml.
  • Git tag (v0.3.2) — same value, signed by the maintainer, drives both the PyPI publish and the worthless.sh Worker deploy. CI fails fast if the tag and pyproject.toml disagree (see .github/workflows/publish.yml).
  • X-Worthless-Script-Tag header on https://worthless.sh/ — labels the Worker deploy (which install.sh bytes you fetched). Usually matches the latest PyPI version; can drift when the Worker is redeployed without a new package release. Not a promise of PyPI alignment — for that, run pip install and check worthless --version.

install.sh resolves the latest worthless from PyPI at install time; override with WORTHLESS_VERSION=x.y.z curl … | sh to pin.

Contributing

PRs welcome. Read CONTRIBUTING-security.md first.

License

AGPL-3.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

worthless-0.3.2.tar.gz (320.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

worthless-0.3.2-py3-none-any.whl (130.3 kB view details)

Uploaded Python 3

File details

Details for the file worthless-0.3.2.tar.gz.

File metadata

  • Download URL: worthless-0.3.2.tar.gz
  • Upload date:
  • Size: 320.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for worthless-0.3.2.tar.gz
Algorithm Hash digest
SHA256 7bc162b8a324d05f52bf6f3f5ed18dba8b5e1ea25da5c927ebe24ea721b78daf
MD5 3c3e4f661d4a2c02e0ff1b7f2f3b9f4a
BLAKE2b-256 1fe3caa35df02f0767c2d2ed330490031cb1ea7cfc5332ccc9060f18c7d6ca6e

See more details on using hashes here.

Provenance

The following attestation bundles were made for worthless-0.3.2.tar.gz:

Publisher: publish.yml on shacharm2/worthless

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file worthless-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: worthless-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 130.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for worthless-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3be9a9d23ce0d9fb35905f756370454aa416fd0e512d078e707fbd744f5fe935
MD5 9a4d0ce740939594f9a5f08a5dc4d3eb
BLAKE2b-256 22b95ab943897d41e9e41ca2a320dc12ae11b1dd37708455297c3714cb4cd713

See more details on using hashes here.

Provenance

The following attestation bundles were made for worthless-0.3.2-py3-none-any.whl:

Publisher: publish.yml on shacharm2/worthless

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page