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

Quick Answer

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.

  1. Put the key in the Vault. It is stored on your machine, not in a project file and not on our servers.
  2. 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.
  3. 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.
  4. 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 VaultA .env file or an exported variable
Can the agent read the valueNo, a command uses it by nameYes, like any other file or variable
Can it end up in a transcriptIt is never in the conversationAs soon as it is read or echoed
Where it can be sentOnly the destination it is bound toAnywhere the shell can reach
Who can use itThe job it was granted toEvery process running as you
Taking it backPull the grantRotate 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

Keep reading

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.