Vault
Let an agent use a key it never reads
The agent has to deploy, push or call a paid API. That needs a credential. The Vault lets the command have it and keeps it out of the conversation.
Updated
The Forkbench Vault lets a coding agent use an API key without the value reaching it. The key stays on the machine. When the agent runs a command that needs it, the command gets the key and the agent gets the result, so the value is never in the prompt, the command line or the transcript. A key bound to a destination is refused if it is aimed anywhere else.
Why this exists
A coding agent runs in your shell as you. Whatever your shell can read, it can read: the .env file in the project, the token you exported this morning, the credentials in your home directory. Asking it not to look is a request, not a boundary. In January 2026 The Register reported Claude Code reading .env files that an ignore rule was meant to hide, and GitGuardian's State of Secrets Sprawl 2026 found that code written with an agent leaks credentials at about twice the rate of code written without one.
Most of that is not an attack. It is an agent being thorough. It reads a config to debug a build, echoes an environment variable to see why a call failed, or pastes a token into a command it then quotes back to you. Once a value has been in the conversation it has been sent to a model provider and it is sitting in a transcript. You can revoke the key. You cannot take the copy back.
So the useful goal is not to stop the agent using the key. It is to make sure using it never requires seeing it.
How it works
The agent needs the command to succeed. It does not need the credential to be readable. The Vault separates those two.
- Put the key in the Vault. It is stored on your machine, not in a project file and not on our servers.
- Grant it to the job that needs it. Nothing is available by default. An agent can use no keys at all until you grant one to its Thread, and you can pull a grant at any time.
- The agent asks for it by name. It runs its usual command through the Vault and names the key. It never types, pastes or prints the value, because it never has it.
- The command gets the key. The agent gets the answer. The push succeeds, the deploy goes out, the API responds. What comes back to the conversation is the output of the command.
A key that only works where it belongs
Bind a key to the place it is for, and the strongest path applies. The command does not receive the real credential at all. It receives a stand-in: a value minted for that one terminal and that one key, worth nothing to anybody else. On the way out, a local proxy swaps in the real credential, and only for a request going to the destination that key is bound to.
Point the same stand-in anywhere else and the request is refused, recorded and never sent. That holds whether the credential travels in a header, a query string or a body, because nothing here needs to know what a provider's API looks like.
The command cannot route around this. It runs in a child process that is denied every outbound connection except the local proxy, so a program that ignores the proxy settings has nowhere to dial.
Who is asking is not taken on trust
When something asks the Vault for a key, the Vault does not believe what the caller says about itself. It asks the operating system which terminal the request came from, and checks again before answering. A process cannot claim to be a pane it is not, so a key granted to one job stays with that job.
You can also require a fingerprint on every use, or let a grant stand while you work. And for a few minutes after a key is used, your terminal's output is watched for an accidental echo of the value, which is masked if it appears. That last one is a backstop for a stray print, not the control.
Sealed to the machine holding it
A key in the Vault is encrypted under a key that lives in that machine's secure hardware and cannot be exported from it. A copied keychain file or a stolen disk is unreadable.
If you use more than one machine, a key added on one can be usable on another. It is sealed before it leaves and stays sealed on our servers, and a new machine has to be admitted from one that already holds the Vault. Removing a machine is a rotation, not a delisting: every item is sealed again under a new key, so the machine you removed is left holding ciphertext it can no longer open.
The Vault and a .env file
A .env file is the default because it is easy. This is what the convenience costs once an agent is in the shell.
| The Vault | A .env file or an exported variable | |
|---|---|---|
| Can the agent read the value | No, a command uses it by name | Yes, like any other file or variable |
| Can it end up in a transcript | It is never in the conversation | As soon as it is read or echoed |
| Where it can be sent | Only the destination it is bound to | Anywhere the shell can reach |
| Who can use it | The job it was granted to | Every process running as you |
| Taking it back | Pull the grant | Rotate the key and hope |
Where it stops
- A key with no destination is weaker. A key that is not bound to a destination cannot be swapped in on the wire, so it is placed in the command's environment instead. It stays out of the prompt, the argument list and the transcript, but the program that was run can read what it was handed. Think seatbelt, not guarantee, and bind the key where you can.
- Containing a key is not containing authority. An agent that is allowed to call a destination can still ask it to do something destructive. That is a different control, and it is why destructive calls stop and ask a person.
- It governs what it holds. A .env file you leave in the project is as readable as it ever was. Moving the key out of the file is something you do once, and nothing does it for you.
- It is not a guard against a hostile program. This protects against accidental exposure, which is what actually happens. A program you deliberately hand a value to is trusted with that value.
Frequently asked
How do I let Claude Code use an API key without it seeing the key?
Keep the key out of the shell and give it to the command instead. In Forkbench, the key goes in the Vault and is granted to the job; Claude Code then runs the command through the Vault by the key's name. The command receives the key and Claude Code receives the output, so the value never appears in its prompt, command line or transcript.
Is the Forkbench Vault a password manager?
No. A password manager stores secrets for a person to copy out. The Vault exists so that nothing has to be copied out: a command uses a key by name and the value is never shown to the agent. It can sit beside a password manager, and the comparison with 1Password's agent features covers where each fits.
Where are Vault keys stored?
On the user's own machine, in the system keychain, encrypted under a key held in that machine's secure hardware. They are not stored in a project file and not readable on Forkbench's servers. The full storage model is on the security page.
Can an agent still leak a key that is in the Vault?
If the key is bound to a destination, the command only ever holds a stand-in that is refused anywhere else, so there is nothing useful to leak. If the key has no destination, it is injected into the command's environment and the program that was run could read it. Binding keys to their destination is the stronger setup.
Does the Vault stop an agent reading my .env file?
No. The Vault protects the keys you put in it. A .env file left in the project is still a file the agent can open, which is why the fix is to move the value out of the file. Stop Claude Code reading your .env file walks through it.
Can I give a teammate a key they can use but not read?
Yes. Grant the key to the Thread they are working in and invite them. Their commands get the value when they run, and it never lands in their prompt, their command line or their transcript. Removing them rotates that Thread's key. The step by step is here.
Keep reading
- The full security model: what is held, sealed and refused
- Give an agent deploy access without giving it the credential
- Stop Claude Code reading your .env file
- The folder lock: the other half of fencing an agent in
Sources
Let the agent do the work, not hold the keys
Move one key out of a file today and watch the same command succeed without it.