Skip to main content
You can run an agent in a Docker container to keep it away from the rest of your machine. The agent still runs commands that a prompt can influence, so any API key you give the container can leak through a prompt injection. With Agent Vault, the agent’s container has no API keys. Each run is its own Docker Compose project with two containers: one for an Agent Vault proxy, and one for the agent. The agent’s container is only on a private network with its proxy and can’t reach the internet, so every request the agent makes goes through the proxy, and the proxy attaches the real credential to requests for the APIs you allowed. For each run, your script does the following:
  1. Creates an Agent Vault session for the run
  2. Starts the proxy’s container, then the agent’s container with the session token
  3. Stops the proxy when the agent finishes, so the proxy uploads the rest of the session logs
  4. Removes both containers and the run’s network, then revokes the session
Every proxy starts from the same proxy token, so you create the proxy in Infisical once, no matter how many agents you run.
You can, as long as every agent’s container is on a network with the proxy. This guide runs a proxy beside each agent instead, the same way the Modal and Daytona guides do, so the proxy starts and stops with its run.Each run also gets its own private network, so nothing outside the run can send requests through its proxy.

Prerequisites

Step 1: Set up Agent Vault

Create a proxy

1
In Agent Vault, go to Proxies and select Create Proxy.
2
Enter a Name, such as sandboxes, and expand Advanced Options. Under Traffic Policy, choose Access bundle hosts only. Then add any other hosts the agent needs to reach to Exceptions (for example, registry.npmjs.org).
Make sure you select the Access bundle hosts only traffic policy. The proxy can reach the internet, so if you leave the traffic policy set to Any host, the agent can send requests through the proxy to any host.
3
Select Create, then copy the proxy token from the Proxy Token dialog. Infisical shows the token only once.

Create a machine identity for your code

Your code creates a session for each run as a machine identity. Give the machine identity the Member role and access to only your access bundle, because an Agent Vault admin can create sessions for every access bundle.
1
In Agent Vault, go to Access Control > Machine Identities and select Add Machine Identity.
2
On the Create New tab, enter a Name, choose Member in Role, then select Create. Infisical creates the machine identity with Universal Auth and opens its page.
To use a machine identity that already exists in your organization, select the Assign Existing tab instead.
3
On the machine identity’s page, select Universal Auth under Authentication. Copy the Client ID, then select Add Client Secret and copy the client secret.
4
Go to Access Bundles and open the access bundle the agent uses. Select Options > Manage Access, then select Grant Access. Select the machine identity, then select Grant Access.

Step 2: Give your script the credentials

Set the following environment variables in the shell that runs your script:
Docker Compose passes the proxy token only to the proxy’s container, and the machine identity’s credentials never enter a container.

Step 3: Write the agent’s Dockerfile

Create a directory for the Compose project. In that directory, create a Dockerfile for the agent’s image, which has the Infisical CLI and your agent. This example installs Claude Code:
  • Infisical CLI: replace <cli-version> with 0.44.7 or later, because earlier versions can’t start a proxy from a proxy token
  • The node user: Claude Code won’t skip its permission prompts as root, so the agent runs as the image’s node user
  • The entrypoint: infisical agent-vault run sends the agent’s requests through the proxy, and the agent’s command follows --

Step 4: Define the containers

Create a compose.yaml file in the same directory:
compose.yaml
Replace <cli-version> with the same version as in the Dockerfile. The file sets up the containers as follows:
  • Networks: the agent network is internal, so containers on it can’t reach the internet, and only the proxy is also on the internet network
  • Credentials: the variables with no value, such as INFISICAL_AGENT_VAULT_PROXY_TOKEN, get their values from the shell that runs your script
  • Starting order: Docker Compose starts the agent only after the proxy is ready
Then build the agent’s image:

Step 5: Run an agent

This script runs one prompt in a new Compose project. Create it in the same directory, and replace <access-bundle-name> at the top with your access bundle’s name. If you use EU Cloud or self-host Infisical, also replace https://app.infisical.com with https://eu.infisical.com for EU Cloud or the URL of your self-hosted instance:
run-agent.sh
For more about creating sessions from code, see Create sessions with the API. For the flags the agent starts with, see the agent-vault run CLI reference.
To run a different agent, install it in the agent’s Dockerfile, replace the CMD with the agent’s non-interactive command, such as codex exec, and replace the Claude Code settings in the agent’s environment variables in compose.yaml.For an agent you built yourself, run it the same way, or set the proxy in its HTTP client.

Step 6: Verify it works

Make the script executable, then run it with a prompt that needs an API in the access bundle:
Claude Code replies, even though its container has no Anthropic API key and no internet access.
Each run now gets its own containers, network, and session. The only credential in the agent’s container is a session token, and the script revokes the session when the run ends.
To check which requests the agent made, set up session logs, then view the session’s logs in Agent Vault. Requests that got a credential have the outcome Brokered.

Security considerations

Network access from the agent’s container

The agent’s container can’t reach the internet. It can’t look up hostnames on the internet either, because on an internal network, Docker only answers DNS lookups for the names of containers. With the Access bundle hosts only traffic policy, the agent can reach two kinds of hosts through the proxy: the hosts of the services in the session’s access bundle, and the proxy’s exceptions. The agent can still connect to services on the Docker host that listen on all of the host’s addresses, such as 0.0.0.0, through the gateway address of the run’s network. To keep the agent away from a service on the host, have the service listen only on 127.0.0.1, or block traffic from Docker’s networks to the host with a firewall rule.

Isolation between containers

Docker containers share the host’s kernel. If an agent escapes its container, it can read the proxy token and the machine identity’s credentials from the host. If the agent runs code you don’t trust, run its container with a stronger runtime, such as gVisor, or run the agent in a sandbox, such as Modal or Daytona.

Compromised hosts

If you think someone took control of the machine that runs Docker, rotate the proxy’s token and update INFISICAL_AGENT_VAULT_PROXY_TOKEN where your script runs. Then create a new client secret for the machine identity and revoke the old one.

Troubleshooting

The script fails with dependency failed to start, and prints the proxy’s log. If the log says The provided access token is malformed, the proxy token is wrong. Check the following:
  • INFISICAL_AGENT_VAULT_PROXY_TOKEN has the current proxy token (a token stops working when you rotate it)
  • If you use EU Cloud or self-host Infisical, INFISICAL_DOMAIN in the script is the URL of your instance
  • The image tag in compose.yaml is an Infisical CLI version that can start a proxy from a proxy token
The session expired before the agent finished. Set the session’s ttl in the script longer than your longest run.
The proxy’s traffic policy blocks hosts that no service in the access bundle covers. Add a service for the host, or add the host to the proxy’s exceptions.
The agent has only a placeholder, so the error is about the key in the access bundle. The proxy’s log shows decision=brokered and status=401 for the provider’s host. Update the key in the access bundle’s service for that provider, such as Anthropic for Claude Code.
When Claude Code starts, it requests /api/claude_code/settings from api.anthropic.com, and the request can return a 404. Claude Code runs without the response, so you can ignore this line.

Next steps

Create sessions with the API

Create a session for each agent run from your own code.

Session logs

Record every request an agent makes during a session.