Towel twl

Letting an agent use an API without giving it the real key.

Experimental open-source security tool  ·  website ↗  ·  source ↗

Why I built it

I wanted coding agents to be able to run my apps without having access to the real API keys. Towel puts a small broker between the app and the API. The app gets a temporary fake key; the broker adds the real one when it forwards a request.

I register a project and its allowed API destinations, unlock a session, and start the agent through twl. The app sends its requests to local URLs, and the broker forwards them to the destinations I configured.

What happens in a session

  1. I unlock one named project with Touch ID on macOS or the vault password on Linux.
  2. Towel starts a small HTTP broker on 127.0.0.1 and launches the child command.
  3. The child receives a random fake key and a route-specific local URL for each project route.
  4. The broker forwards requests only to the exact HTTPS destinations stored with the project and adds the real Bearer key on the way out.

What it protects

A key cannot be printed from the child environment, copied from a command line, or reused after the session. Workspace files also cannot change the destination that receives it. Redirects are disabled, and the broker ignores client-supplied forwarding and authentication headers.

The scope is deliberately narrow. Towel is not a sandbox: while a session is running, the agent can still use the API, spend quota, and change any data that key is allowed to change. It protects the credential itself, not every action made with it.

Storage on each platform

On macOS, projects live in an application-scoped Data Protection Keychain record and real sessions require a correctly signed, hardened binary. On Linux, projects live in a password-encrypted age vault with strict file checks and atomic updates. If Bubblewrap is installed, Towel also masks that vault from the child process.

Both platforms expose the same CLI and project format. Passwords, decoded vault records, and broker route credentials use zeroizing memory so their contents are cleared when their useful lifetime ends.

Try the canary demo

The demo uses a generated canary credential, so you can try the request flow without any real API keys.

cargo build --locked
./target/debug/twl demo --config examples/towel.yaml -- \
  python3 examples/application_client.py

Built with

Core Rust 1.82+
macOS storage Data Protection Keychain + LocalAuthentication
Linux storage Passphrase-encrypted age vault
Broker Loopback HTTP, fixed HTTPS upstreams
License Apache-2.0

Current state

Towel is experimental security software and has not had an independent audit. I use disposable or tightly scoped development credentials while evaluating it, and I recommend the same to anyone trying it.

I've put the threat model, security policy, adversarial tests, build scripts, and release checks in the repository. Reports of things that break are welcome.

Visit the project site ↗ Read the source ↗