agent-backend: the Agent runtime service, deployed by the Helm Chart.sandbox-gateway: the sandbox control plane responsible for sandbox allocation and reclamation, deployed by the Helm Chart.agent-sandboxcontroller: the official Kubernetes community project kubernetes-sigs/agent-sandbox, which provides the sandbox CRDs and controller. It must be installed in the cluster in advance.
Install the agent-sandbox controller
Installation requires cluster admin privileges and is performed once per cluster:sandboxes.agents.x-k8s.iosandboxclaims.extensions.agents.x-k8s.iosandboxtemplates.extensions.agents.x-k8s.iosandboxwarmpools.extensions.agents.x-k8s.io
Helm Chart configuration
BothagentBackend.enabled and sandboxGateway.enabled default to true, so a standard deployment enables the sandbox capability out of the box, provided the controller installation above has been completed. Run helm show values dify/dify to see all available options. Below is an example of the Agent Sandbox related configuration:
-
agentBackend.enabled- Whether to deploy agent-backend. When disabled, the Agent app is not available in the console.
-
agentBackend.serverSecretKey- Encryption key for Agent tool callback tokens: a base64url-encoded 32-byte random value. The default value must be replaced in production. Generate one with:
-
sandboxGateway.enabled- Whether to enable the dedicated-Pod sandbox mode. When disabled, the deployment automatically falls back to the shared sandbox mode with no extra configuration.
-
agentRuntime.image- The sandbox runtime image, shared by both the dedicated-Pod mode and the shared sandbox mode. The sandbox ships with Python 3.12, Node.js 22, pnpm, uv, git, and other common tools. See Customize the sandbox image below for customization.
-
sandboxGateway.provision.warmPoolReplicas- Warm pool size, i.e. the number of idle sandboxes kept on standby. Adjust according to Agent concurrency.
-
sandboxGateway.provision.requestsCpu/requestsMemory/limitsCpu/limitsMemory- Resource configuration for a single sandbox Pod. For capacity planning, running N concurrent Agent sessions requires headroom for roughly N +
warmPoolReplicassandbox Pods.
- Resource configuration for a single sandbox Pod. For capacity planning, running N concurrent Agent sessions requires headroom for roughly N +
sandboxGateway.namespace: namespace for sandbox Pods, defaults to the release namespace.sandboxGateway.provision.sandboxTtl: maximum lifetime of a single sandbox, default1800s.sandboxGateway.inactiveTtl: idle reclamation time for sandboxes, default360s.sandboxGateway.execTimeout: execution timeout for a single command, default300s.sandboxGateway.provision.extraEnv: extra environment variables injected into sandbox Pods, e.g. egress proxy settings.sandboxGateway.provision.volumeClaimTemplates: persistent volumes mounted into sandbox Pods; each entry creates a PVC.sandboxGateway.provision.securityContext/podSecurityContext: security contexts for sandbox Pods, configure as needed when the cluster enforces Pod Security Standards.- The global
imagePullSecretsis automatically propagated to sandbox Pods; no extra configuration is needed for private registries.
Sandbox network policy
Egress traffic from sandbox pods is controlled by two layers, both enabled by default: SSRF proxy: the chart deploys a dedicated squid proxy for sandboxes (agent-sandbox-ssrf-proxy) and injects HTTP_PROXY / HTTPS_PROXY into sandbox pods, forcing all outbound HTTP(S) traffic through it. By default the proxy blocks requests to private (RFC1918 and similar) address ranges, providing SSRF protection. The proxy itself is configured via sandboxGateway.ssrfProxy (replicas / image / resources / squidConf).
NetworkPolicy: sandboxGateway.provision.networkPolicy defaults to enabled: true and only allows the following egress: DNS (kube-dns/coredns in kube-system), agent-backend (port 5050), the SSRF proxy (port 3128), and the external internet (allowExternalEgress: true, excluding private ranges). Sandboxes cannot reach dify-api directly.
If sandboxes need to reach other in-cluster services or internal addresses, both layers must be opened:
- Add allow rules for the target addresses via
networkPolicy.extraEgressRules; - Override
sandboxGateway.ssrfProxy.squidConfand insert allow rules for the targets before the defaultdeny private_dstrule.
- With
networkPolicy.enabled: false, the agent-sandbox controller’s secure defaults take over: only the public internet is reachable and all private (RFC1918) addresses are blocked. networkPolicy.management: "Unmanaged"skips NetworkPolicy provisioning entirely, leaving it to the cluster to manage.
Deploy and verify
Apply the updated values with an upgrade:SandboxTemplate and SandboxWarmPool resources in the namespace (sandboxGateway.provision.managedByHelm defaults to true); no manual creation is needed. Verify the deployment:
RBAC permissions
Enabling this feature introduces the following cluster permission changes, for security review reference:- The
agent-sandboxcontroller is a cluster-scoped component responsible for creating and deleting sandbox Pods based on the CRDs. - sandbox-gateway uses a namespace-scoped Role (created by the Chart, controlled by
sandboxGateway.rbac.create) containing only:- read/write on
sandboxclaims(sandbox lifecycle management); - read-only on
sandboxtemplates/sandboxwarmpools(the resources themselves are created by Helm); - read-only on
sandboxes(status queries).
- read/write on
- sandbox-gateway has no permissions on native resources such as Pods, Secrets, or ConfigMaps, and no cluster-scoped permissions.
sandboxGateway.rbac.create: false and specify it via sandboxGateway.serviceAccountName.
Alternative without agent-sandbox (shared sandbox mode)
If your cluster does not allow installing third-party CRDs and controllers, simply setsandboxGateway.enabled to false. The Chart then automatically deploys a long-running agent-runtime service, and all Agent sessions share a single sandbox container instead of getting dedicated Pods:
- This mode installs no CRDs and introduces no additional RBAC permissions.
- All sessions share one container, so isolation is weaker than the dedicated-Pod mode, and only a single replica is supported. Recommended only as a fallback for restricted environments.
- Adjust resources via
agentRuntime.resources.
Customize the sandbox image
To provide additional tools, SDKs, or internal CA certificates inside the sandbox, build on top of the official image:- Do not override the image’s default
CMD/ENTRYPOINT; the sandbox service must listen on port 5004. - Do not remove the
shellctl*anddify-agentbinaries under/usr/local/bin. - Switch to
USER rootto install system packages, and always switch back toUSER difyafterwards. - Keep the
/home/difyand/mnt/drivedirectories and their ownership.
agentRuntime.image in your values and run helm upgrade. In dedicated-Pod mode the warm pool rolls over to the new image automatically; in shared sandbox mode the agent-runtime deployment restarts on rollout.
FAQ
- No Agent app entry in the console
- Confirm
agentBackend.enabledistrueand the Dify version is at least 3.12.0.
- Confirm
- sandbox-gateway fails to start with CRD-not-found errors
- The agent-sandbox controller is not installed. Complete the installation steps above, or switch to the shared sandbox mode if installation is not possible.
- Sandbox Pods stuck in Pending or ImagePullBackOff
- Check node resource headroom; when using a private registry, confirm the global
imagePullSecretsis configured.
- Check node resource headroom; when using a private registry, confirm the global
- Sandbox cannot reach in-cluster services or internal addresses
- Egress goes through the SSRF proxy by default and only DNS, agent-backend, and the external internet are allowed. Open both layers: add the targets to
networkPolicy.extraEgressRulesand allow them insandboxGateway.ssrfProxy.squidConf; see Sandbox network policy.
- Egress goes through the SSRF proxy by default and only DNS, agent-backend, and the external internet are allowed. Open both layers: add the targets to
- Agent command execution times out
- A single command is limited to 300 seconds by default; adjust via
sandboxGateway.execTimeout.
- A single command is limited to 300 seconds by default; adjust via
- Sandbox reclaimed while a session is in progress
- The sandbox idled longer than
inactiveTtl(default 360s) or lived longer thansandboxTtl(default 1800s); increase them as needed.
- The sandbox idled longer than