- Creates an Agent Vault session for the run
- Creates a sandbox with no internet access, and starts the proxy in a sidecar
- Starts the agent in the sandbox with the session token
- Revokes the session and terminates the sandbox when the agent finishes
Why not run one proxy with every sandbox pointing at it?
Why not run one proxy with every sandbox pointing at it?
A proxy outside the sandbox doesn’t work well on Modal:
- Modal can place sandboxes in the same region on different clouds, and its private network doesn’t connect sandboxes across clouds, so a proxy in another sandbox can’t reach every agent
- A sandbox can only allow a hostname for HTTPS on port 443, and the proxy listens for plain HTTP on port 17323, so you’d have to allow the proxy by a fixed IPv4 address
- If the proxy is reachable from the internet, anyone who gets a session token can use it from anywhere until the session ends
Prerequisites
- The Admin role in Agent Vault
- A Modal account, with a Modal token on the machine that runs your code (run
modal setup, or setMODAL_TOKEN_IDandMODAL_TOKEN_SECRET) - The Modal SDK for your language: the
modalandrequestspackages for Python, themodalpackage for TypeScript, or the Modal Go SDK - The API keys your agent uses, such as your Anthropic API key
Step 1: Set up Agent Vault
Create an access bundle
Create an access bundle that contains a service for each API the agent calls.1
In Infisical, open Agent Vault from the product switcher and go to Access Bundles.
2
Select Create Access Bundle. Give the access bundle a Name, such as
modal-agent, then select Create Access Bundle.3
Select the access bundle you just created, then select Add Service.
4
On the Choose a template panel, pick the template for the API, such as Anthropic, or select Custom.
5
On the Details step, check the hosts the service covers, or enter the API’s host if you selected Custom, then select Continue.
6
On the Credential step, paste the real API key.
If the API expects the key somewhere other than a header, such as in the URL, add a substitution instead, and have the agent send the placeholder you enter in Replace.
7
Select Add Service. Repeat from the third step for each remaining API.
Create a proxy
1
In Agent Vault, go to Proxies and select Create Proxy.
2
Enter a Name, such as
modal-sandboxes, and expand Advanced Options. Under Traffic Policy, choose Access bundle hosts only, and add any hosts the agent needs without a credential to Exceptions, such as registry.npmjs.org.The sidecar can reach the internet, so with Any host, the agent could send requests through the proxy to any host. Learn more about the traffic policy.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 this 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.
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: Store the credentials
The proxy token and the machine identity’s credentials stay out of the agent’s container.Store the proxy token in Modal
In the Modal dashboard, create a custom secret namedagent-vault-proxy with this key, set to the proxy token:
agent-vault-proxy secret. Modal runs each sidecar in its own container with its own kernel, so the agent can’t read the sidecar’s environment or files.
If you use EU Cloud or self-host Infisical, add this key as well:Set the key to
https://eu.infisical.com for EU Cloud, or the URL of your self-hosted instance.Give your code the machine identity’s credentials
SetINFISICAL_UNIVERSAL_AUTH_CLIENT_ID and INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET in the environment of the code that starts your sandboxes.
Step 3: Build the sandbox image
The agent’s container and the sidecar use the same image, which has the Infisical CLI and your agent. This example installs Claude Code:- Infisical CLI: replace
<cli-version>with<min-cli-version>or later, because earlier versions can’t start a proxy from a proxy token - The
agentuser: Modal runs commands as root, and Claude Code won’t skip its permission prompts as root, so the agent runs as this user - Building the image first: Modal can’t build a sidecar’s image when it starts the sidecar, so the code builds the image before it creates any sandbox
Step 4: Run an agent in a sandbox
This function runs one prompt in a new sandbox. 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:
agent-vault run CLI reference.
To run a different agent, install it in the image, replace the claude command in the script that starts the agent with the agent’s non-interactive command, such as codex exec, and replace the Claude Code settings in the agent’s environment variables. For an agent you built yourself, run it the same way, or set the proxy in its HTTP client as Connect your own agent describes.
Modal sidecars are in beta, and Modal may change the sidecar API, so pin the version of the Modal SDK your code uses.
Step 5: Verify it works
Call the function with a prompt that needs an API in the access bundle:Each run now gets its own sandbox, proxy, and session. The only credential in the agent’s container is a session token, and your code revokes the session when the run ends.
Security considerations
Network access from the sandbox
The agent’s container can’t connect to the internet directly, but it has two kinds of network access:- DNS: Modal answers DNS lookups in a sandbox even with an empty allowlist, so the agent can look up hostnames
- Hosts through the proxy: with Access bundle hosts only, the agent can reach the hosts that services in the session’s access bundle cover, and the proxy’s exceptions
Compromised sandboxes
Each sidecar has a copy of the proxy token. If you think someone took control of a sandbox, rotate the proxy’s token, then put the new token in theagent-vault-proxy secret in Modal.
Troubleshooting
The proxy doesn't start in the sidecar
The proxy doesn't start in the sidecar
The function’s error includes the proxy’s log. If the log says
The provided access token is malformed, the proxy token is wrong. Check the following:- The
agent-vault-proxysecret in Modal has the current proxy token (a token stops working when you rotate it) - If you use EU Cloud or self-host Infisical, the secret has
INFISICAL_DOMAIN - The image has an Infisical CLI version that can start a proxy from a proxy token
|| sleep 600: if the proxy exits, the sidecar keeps running, and the function can read the proxy’s log.Requests fail with a 403 partway through a run
Requests fail with a 403 partway through a run
The session expired or was revoked. Set the session’s
ttl a few minutes longer than the sandbox’s timeout, so the session lasts as long as the sandbox can run.Requests to a host fail with a 403 from the start
Requests to a host fail with a 403 from the start
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.
Can I use Modal's proxy_traffic_via_sidecar option instead?
Can I use Modal's proxy_traffic_via_sidecar option instead?
No. That option sends the agent’s HTTPS connections to the sidecar without a session token, and the proxy needs the session token to know which credentials to attach. Use
infisical agent-vault run, or set the proxy in the agent’s HTTP client.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.