Towel twl
Let the agent run the app without handing it the real project key
Experimental open-source security tool · website ↗ · source ↗
Why I built it
Giving a coding agent an API key through an environment variable always felt like the wrong abstraction. The application needs to make an authenticated request; the agent does not need to see a reusable credential.
Towel keeps those two things separate. I register a project and its allowed API destinations in a trusted store,
authorize one session, and then start the agent through twl. The child sees fake keys and loopback URLs.
The real credentials stay with the broker.
What happens in a session
- I unlock one named project with Touch ID on macOS or the vault password on Linux.
- Towel starts a small HTTP broker on
127.0.0.1and launches the child command. - The child receives a random fake key and a route-specific local URL for each project route.
- The broker forwards requests only to the exact HTTPS destinations stored with the project and adds the real Bearer key on the way out.
The useful boundary
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 instead of a real secret, so it is the safest way to inspect the request flow first.
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.
The repository includes the threat model, security policy, adversarial regression tests, build scripts, and release-verification steps. Reviews and focused failure cases are especially welcome.