Before you start, choose an isolation level for agent pods: the standard runtime, gVisor, or Kata Containers. For gVisor or Kata, your cluster needs a RuntimeClass for that runtime. The Kubernetes overview also explains why each piece runs where it does.
Prerequisites
- The Admin role in Agent Vault
- An access bundle with a service for each key the agent uses, including its model provider’s key, such as Anthropic for Claude Code (see the quickstart)
- A Kubernetes cluster whose network plugin enforces network policies, such as Cilium or Calico
curl,jq, andopensslon the machine where you run the script in Step 6
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.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.
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: Deploy the proxy
Save this manifest asagent-vault-proxy.yaml and apply it to your cluster. It creates the agent-vault namespace and runs the proxy in it:
- Instance URL: if you use EU Cloud or self-host Infisical, replace
https://app.infisical.comwithhttps://eu.infisical.comor the URL of your self-hosted instance - Egress: the proxy can only reach public addresses on ports 443 and 80, so add an egress rule for anything else, such as a self-hosted Infisical instance on a private address or a service at
api.example.com:8443 - DNS: this policy and the one in Step 3 allow DNS only to
k8s-app: kube-dnspods inkube-system, so change both if your DNS runs elsewhere, such as a node-local DNS cache or OpenShift’sopenshift-dns
Store the proxy token
Store the proxy token in a Secret namedagent-vault-proxy in the agent-vault namespace, under the key INFISICAL_AGENT_VAULT_PROXY_TOKEN. The proxy’s pods start once the Secret exists.
On the Proxies page in Agent Vault, the proxy’s status changes to Healthy once it connects. Both replicas use the same token and certificate authority, and the Service spreads connections across them (high availability).
Step 3: Create the agents namespace
Save this manifest asagents-namespace.yaml and apply it to your cluster. It creates the agents namespace and blocks all traffic to and from its pods, except DNS lookups and connections to the proxy:
restricted Pod Security Standard refuses pods that run as root, keep Linux capabilities, or can raise their privileges. The agent pod in Step 6 meets it.
Step 4: Set up your orchestrator
Your orchestrator starts each agent run, and it can be a script, a CI pipeline, a job runner, or a Kubernetes controller. Run it outside theagents namespace, so agent pods can’t reach it.
Give your orchestrator the machine identity’s credentials
Set the client ID and client secret of the machine identity from Step 1 in the environment where your orchestrator runs:Allow the orchestrator to start agent pods
Save this manifest asagent-orchestrator-role.yaml and apply it to your cluster, then bind the role to the service account or user that your orchestrator runs as. The role only applies in the agents namespace:
Step 5: Build the agent’s image
Build an image from this Dockerfile and push it to a registry your cluster can pull from:- The
nodeuser: therestrictedPod Security Standard refuses pods that run as root, and Claude Code won’t skip its permission prompts as root, so the agent runs as the image’snodeuser - The entrypoint:
infisical agent-vault runfetches the proxy’s certificate, sets the proxy and certificate trust variables, and starts the agent’s command after-- curl: the checks in Step 7 run it in the agent’s pod
Step 6: Run an agent
Define the agent’s pod
Save this manifest asagent-pod.yaml. The script in the next step starts a pod from it for each run:
agent-vault instead, as in Connect your own agent.
Start the agent with a new session
This script is a minimal orchestrator that runs one agent with its own session. Replace<access-bundle-name> with your access bundle’s name, and https://app.infisical.com with your instance’s URL if you don’t use US Cloud:
Step 7: Verify it works
While an agent runs, check its traffic as a cluster admin. Replace<run-id> with the run ID the script printed, and <api-host> with a host in your access bundle:
kubernetes run <run-id>. It’s Active while the agent runs and Revoked after the script exits. View the session’s logs to see each request the agent made.
Your agents now run in pods that contain only a session token, can only connect to the proxy, and lose access when the session is revoked.
Security considerations
- Hosts through the proxy: agent pods can only connect to the proxy and DNS, but under the default traffic policy, Any host, the proxy forwards their requests to any host its network policy allows (to allow only the hosts that services in the session’s access bundle cover, set the traffic policy to Access bundle hosts only and add any other hosts the agents need to the proxy’s exceptions)
- DNS: agent pods still need DNS to find the proxy, and DNS lookups can carry data out of the pod, so a network policy doesn’t close every channel
- APIs that echo requests: if an endpoint returns the request’s headers in its response, such as an echo or debug endpoint, the response exposes the credential that the proxy attached, so limit each service to the methods and paths the agent needs
- Revoking a session: the proxy stops attaching credentials for a revoked session within one poll interval
- Several teams: a proxy’s traffic policy and exceptions apply to every agent that uses it, so give each team or customer its own proxy and agents namespace if they need different access
- Unsupported connections: WebSocket connections and clients that only speak HTTP/2, such as gRPC clients, fail through the proxy (see Supported connections)
Troubleshooting
Agent or proxy pods can't resolve hostnames
Agent or proxy pods can't resolve hostnames
The network policies allow DNS only to pods labeled
k8s-app: kube-dns in kube-system. If your cluster’s DNS runs elsewhere, such as a node-local DNS cache or OpenShift’s openshift-dns, change the DNS rule in both network policies to match it. Until then, the proxy never becomes ready, and infisical agent-vault run can’t find the proxy.Requests through the proxy time out
Requests through the proxy time out
The proxy’s network policy blocks the host or port. It allows only ports 443 and 80 on public addresses, so add an egress rule for a private address or another port, as Step 2 describes.
The agent reaches the internet without going through the proxy
The agent reaches the internet without going through the proxy
Your cluster’s network plugin doesn’t enforce network policies, so Kubernetes accepts the policies but nothing applies them. Flannel, the default network plugin in k3s, is one example. Install a network plugin that enforces policies, such as Cilium or Calico.
Requests fail with a certificate error
Requests fail with a certificate error
The agent’s HTTP client doesn’t trust the proxy’s certificate. Check that the agent starts through
infisical agent-vault run, as the image’s entrypoint does, and that its HTTP client reads one of the certificate trust variables.The proxy returns 403 with "host blocked by policy"
The proxy returns 403 with "host blocked by policy"
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.
Kata pods stay in ContainerCreating or fail to start
Kata pods stay in ContainerCreating or fail to start
The node doesn’t have hardware virtualization. Run
ls /dev/kvm on the node; if the file doesn’t exist, schedule Kata pods on nodes that support it (see Choose an isolation level).On Kata, output from kubectl exec stops early
On Kata, output from kubectl exec stops early
If you send input to
kubectl exec -i and then close it, Kata ends the command’s output stream right away, while the command keeps running. Anything the command prints after that is lost. To run commands in a Kata pod, pass the input as an argument or in a file instead of on stdin, or start the agent as the pod’s own command, as this guide does.Next steps
Session logs
Record every request an agent makes during a session.
Proxies
Change the proxy’s traffic policy, exceptions, and poll interval.