Why Dify code execution sandbox security matters before you publish workflows
The sandbox is the boundary between code written by your builders and your network, so it has to be configured deliberately before anyone publishes a workflow. In a self-hosted Dify, workflow authors can add Code and Template nodes, and those nodes run inside a separate sandbox service rather than in the api container itself. Once a builder can add that logic, the questions that matter are what the code can reach, how long it can run, how much output it can return and who is allowed to write it. A default setup answers some of these, but a team should confirm the answers rather than assume them.
The Dify 1.16.1 release notes on GitHub describe three security changes relevant here: network isolation for agent sandboxes through a Squid proxy, token-based authentication between services, and sandboxed Jinja2 template rendering. The Docker Compose stack includes a code sandbox and an SSRF proxy, so the components exist in a standard deployment. The release notes describe what changed, but they do not give every setting you need. Before you rely on any of these controls, confirm the exact configuration keys, default values and the sandbox API key behavior against the version you run, using the Dify environment variables reference and your own test instance.
Treat this as a planning decision with an owner. Name who may author Code and Template nodes, decide whether those authors work in a staging workspace first, and record the version you tested. The sections that follow cover each control in turn. Each one needs a check you can repeat after every upgrade, because the sandbox and proxy are part of the release cycle that arrives roughly monthly.
Which sandbox controls fit which risk
The sandbox API key is the credential the API service presents to the code sandbox, so any caller holding that key can ask the sandbox to run code. Replacing the shipped default keeps unrelated processes on the Compose network from invoking the sandbox. The key does not decide what submitted code can do once it runs, and it does not limit outbound connections from that code. Confirm the exact setting name in the environment variable reference and in .env.example for your version, because the default value ships in the published files.
- What it protects: the sandbox from callers that have no business invoking it.
- What it does not cover: code written by an authorized author, or the network reach of that code.
- Replace before first start: generate a unique value per deployment and keep it out of version control.
- Plan rotation: confirm whether a change needs api, worker and sandbox restarted together, and schedule it.
- Tighten when: the Compose host is shared, or the sandbox port is reachable outside the internal network.
Check that the sandbox service publishes no host port in your Compose file and that the running value differs from the shipped default.
Outbound requests from the sandbox should pass through the SSRF proxy, which the environment reference describes as blocking internal and private IP ranges. The 1.16.1 release notes describe agent sandbox network isolation through a Squid proxy, so the proxy is part of the sandbox security design and not only a convenience for HTTP nodes. The proxy limits where code reaches on private networks. It does not decide which public destinations are acceptable, and it does not stop data sent to an allowed destination. Read the environment variable reference for the SSRF_PROXY settings before you change them.
- What it protects: internal hosts and private address ranges from code and agent calls.
- What it does not cover: public destinations that remain reachable, or content sent to them.
- Confirm the sandbox path: check that your version routes code node traffic through the same proxy.
- Avoid direct routes: keep the sandbox on a network where the proxy is the only egress path.
- Tighten when: code nodes call external APIs or agents hold tools with broad reach, so allow only named hosts.
Test a request from a code node to an internal address and to a public test endpoint, and record which requests succeed and which fail.
Timeouts and output limits protect worker capacity and the workflow run from a code step that loops, consumes memory or returns a very large payload. They keep one faulty step from holding a worker or flooding logs and downstream prompts. These limits do not make code safe. Short, hostile code that stays within the limits still runs, and data it returns within the allowed size still reaches the next node. The values are version-specific, so confirm the timeout and size settings for code and template execution in the environment reference and in the node documentation for your release before setting them.
- What it protects: worker availability and the workflow run from stuck or oversized code steps.
- What it does not cover: malicious logic that completes within the limits, or sensitive data returned within the allowed size.
- Find the settings: record each timeout and output size value your version exposes, with its default.
- Test failure paths: run a deliberate infinite loop and a large output in staging, then observe how the run fails and what appears in logs.
- Tighten when: outputs feed prompts or external calls, since large outputs also raise token use and exposure.
Write the configured values into your change record so that an upgrade or redeploy that resets them is caught during verification.
Code and Template nodes are only as safe as the people allowed to add them. Limiting who can create, edit and publish apps keeps unreviewed code out of production workflows. Permissions do not make approved code safe, because a reviewer can approve logic that still has bugs or more access than it needs. Anyone who can run a published app also runs its code nodes, so viewer roles matter too. The app management documentation describes the roles and app operations in Dify, and it is the right place to confirm which roles exist in your version and which of them can change workflows.
- What it protects: production apps from code added by people who have not been reviewed.
- What it does not cover: approved code that is faulty or over-privileged, or harm from users who run an app as intended.
- Keep edit rights small: grant authoring to a named group, and review who holds it each quarter.
- Require review: have a second person approve changes to Code and Template nodes before publishing.
- Review from source: export the app as a DSL file for review in version control, noting that exports omit third-party API keys.
Before assigning roles, confirm in the app management documentation which roles can create, edit and publish apps in your version, and test each role in a staging workspace.
How to harden the code sandbox in a Docker Compose deployment
This sequence moves a self-hosted Dify from default sandbox settings to a verified state, where the sandbox key is private, Code and Template nodes cannot reach internal or unapproved hosts, runaway runs stop on time, and only named builders can change them. Each step closes with a check you can repeat after every upgrade.
Inventory every Code and Template node
The workspace owner or a platform engineer lists each app whose workflow or chatflow contains a Code node or Template node. Export each app as a DSL file, since exports include workflow nodes, and search the YAML for the node type names so nothing is missed. Record the app name, owner, and whether it runs in production or a test workspace. Done when you have a written list that the team has reviewed and that matches the apps visible in the console.
Replace the default sandbox API key
On the Docker host, open the
.envfile in the Dify deployment directory and find the sandbox API key variable. Confirm its exact name against.env.examplefor your release. Set a long random value generated with a cryptographic tool, and store it only in.envwith restricted file permissions. Restart the stack withdocker compose up -dso the api, worker and sandbox read the new value. Done when the variable differs from the example default and every service reports started after the restart.Confirm sandbox and proxy containers are running
Run
docker compose psfrom the deployment directory and confirm the code sandbox and SSRF proxy services show a running state alongside the api, worker and web services. Service names may differ in your release, so match them against the compose file. Checkdocker compose logsfor the sandbox service and look for authentication errors from the api after the key change. A sandbox that rejects the key stops Code nodes from running. Done when all services are up and the logs show no key mismatch messages.Test that Code nodes cannot reach internal hosts
In a draft app in a test workspace, add a Code node that attempts an outbound request to a private address such as 10.0.0.1 and to a public host outside your approved list (both illustrative). Run it and confirm each request fails with a connection or policy error and returns no content. Repeat for any internal service your team expects to be unreachable. Check the proxy logs for the blocked attempts. Done when every test request fails and appears in the proxy logs. Confirm you run 1.16.1 or later, the release that added Squid-based sandbox network isolation.
Check timeout and output limits with a heavy test
Build a Code node with a deliberately heavy workload, such as a long loop or a large string built in memory (illustrative), and run it from the test app. Watch the sandbox container with
docker statswhile it executes. Confirm the node stops with a timeout or error within the limit your team set, and that an oversized output is truncated or rejected instead of passing downstream. Look up the limit variable names and defaults in the environment variable reference for your version before changing them. Done when the run ends with a recorded error and the sandbox returns to idle.Restrict node authoring to named builders
Review which accounts hold editor or admin roles in each workspace, and remove edit rights from anyone who only runs apps. Write a short list of named builders with one accountable owner, and require that changes to Code and Template nodes come only from that list. Use the app management controls to confirm which accounts can edit or publish apps, and confirm the role names in your version. Done when the list matches the workspace member roles and a second person finds no editor outside it.
Repeat the checks after each upgrade
Dify minor releases arrive roughly monthly, so sandbox and proxy behavior can change between versions. After each upgrade, read the release notes, compare
.envagainst.env.examplefor new variables, and rerun the container, network and limit checks. Keep the test app and its results in a dated record. Done when the key, container states, blocked requests and limit tests all pass on the new version and the record is filed with the change ticket.
Security risks that remain after the default settings are changed
Changing the sandbox key and routing traffic through the proxy closes the most obvious gaps, but several risks stay open. Each card below names one residual risk, what the default controls do not cover, and what to check in your own deployment.
Leaked or unchanged sandbox key
The sandbox API key is the credential the API uses to call the code sandbox. If it still holds the default value, or a copy sits in a shared .env file, anyone who can reach the sandbox service can submit code under that key. Replacing the key controls only the value; it does not limit who can read the file, who has shell access to the host, or how old the key is. Check where the key is stored, who can read those files, and whether the sandbox port is reachable from outside the Compose network.
Egress paths outside the proxy
The Squid proxy in the Dify stack handles sandbox egress, but it only governs traffic that is sent through it. Any container that is attached to a network with a direct route, or any code path that opens its own socket, can reach external hosts without passing the proxy's rules. Confirm which containers have default routes, whether host networking is used anywhere, and whether outbound firewall rules at the host or cloud layer block the sandbox subnet directly.
Resource exhaustion from long-running code
Timeouts and output limits stop a single runaway node, but they do not bound the total load a team of authors can place on the host. Repeated workflow runs with heavy loops can starve the api and worker containers of CPU and memory on a host that meets only the stated minimums of 2 CPU cores and 4 GB of RAM. Ask your team to measure sandbox CPU and memory under a representative load, set container resource limits, and alert on queue growth in the worker.
Sensitive data echoed in outputs
A code node can return any value it computes, including values read from workflow variables, knowledge base results or tool responses. Output limits cap the size of that value but not its content, so a script that prints a retrieved customer record or an API token will pass it to the next node, the end user or the logs. Review which variables reach each code node, decide which fields must never be returned, and test a sample run with real-looking records before publishing.
Workspace members writing code
Any member with build rights in a workspace can add or edit Code and Template nodes, and those nodes run inside the sandbox with whatever variables the workflow exposes. The sandbox limits the runtime but not the authorship decision, so a member who is trusted with prompts may not be trusted with arbitrary code. Map which roles can create or publish apps, decide who reviews code node changes, and confirm how your Dify edition handles workspace roles before you rely on that separation.
What buyers ask about sandbox hardening effort and ownership
How much effort does a Dify code sandbox hardening pass take?
No fixed figure is supplied for this work, so the effort depends on the variables below. The main drivers are how many Code and Template nodes already exist, whether any of them call internal systems, how many workspaces and authors use the platform, and whether the sandbox runs under the default settings or has already been changed. A pass that covers one workspace with a few simple nodes is far smaller than one that must review every published app across several teams. Ask any partner to size the work from a written inventory of nodes, outbound targets and author roles, and to state which items are included in the price.
Can an internal team harden the Dify sandbox on its own?
Often yes, provided the team can read Docker Compose files, manage secrets, and test outbound requests from inside the containers. The core steps are replacing the default sandbox API key, routing sandbox egress through the proxy, setting timeouts and output limits, and restricting who may author code nodes. Teams that lack container or network skills, or that must prove the result to an assessor, often find the verification and documentation take longer than the configuration itself. Decide early whether you need the evidence produced as well as the change.
What does the hardening work need from our team?
Expect to provide access to the Docker Compose host or Kubernetes namespace, a copy of the current .env settings with secrets handled through your approved channel, and the list of workspaces and editors who write code nodes. You will also need a test workflow that exercises Code and Template nodes, plus a named owner to approve a change window, because restarting the sandbox and API services interrupts running apps. Confirm with your partner who holds the sandbox API key once it is replaced, and where it will be stored.
How do Dify upgrades affect sandbox settings, and when should we re-verify?
Dify ships minor releases roughly monthly, and each upgrade can change environment variables, container images and the sandbox configuration. The Docker Compose upgrade guide recommends a backup before every upgrade and advises checking .env.example for new variables. Security-related changes can also arrive in release notes, such as the agent sandbox network isolation through a Squid proxy described for 1.16.1. Re-verify the sandbox after every upgrade that touches the sandbox, proxy or template rendering, and treat any new variable that you have not reviewed as a change to test before it reaches production.
What does a fixed-scope sandbox engagement cover?
A fixed-scope engagement covers only what is written into the agreed scope, deliverables and timeline before work starts. A typical written scope lists the Dify versions and hosts in use, the sandbox settings to be reviewed or changed, the egress tests to run, the author policy to document, and the evidence handed over. It usually excludes changes to unrelated components, model provider contracts and application logic unless added. Ask for the scope to name what is tested, what is changed, and what the client must do after handover.
What drives the cost of hardening, and what is recurring?
The one-time cost is the hardening pass itself: review, configuration, testing and documentation. The recurring cost is the work of re-verifying after upgrades, reviewing new code node authors and checking release notes. Cost rises with the number of environments, the complexity of the egress rules and the depth of evidence required. Dify Enterprise pricing is custom and quoted from scope, and the Community edition is free and limited to a single workspace, so the licence tier can change who must do the work. Ask any quote to separate one-time and recurring items.
Does a hardening engagement certify that the sandbox is compliant?
No. DeployOpen prepares configurations, test results and evidence for compliance assessments, but independent auditors and certification bodies issue any audit report or attestation. A hardening pass gives your assessor a documented sandbox configuration, verification records and a re-verification procedure. Ask your assessor which artifacts they expect before work starts, so the evidence is produced in the form they will accept.
Limits to confirm in your environment before you rely on the sandbox
The sandbox behavior described on this page depends on your Dify release, your deployment files and your host. The cards below list what to check in your own environment before you treat the sandbox as a control, and each check can change the answer.
Sandbox and proxy settings per version
Sandbox and proxy configuration keys can change between releases, so the values you read in one guide may not match your version. Compare the sandbox service, its API key, the proxy settings and the .env values in your deployed files against the environment variable reference for the exact version you run. Confirm that the Dify 1.16.1 changes on agent sandbox network isolation through a Squid proxy are present in your build. Record the result with the version tag.
Template and Code node parity
Code nodes and Template nodes both rely on sandboxed execution, and the release notes describe sandboxed Jinja2 template rendering. Do not assume that both node types enforce the same limits, timeouts and output caps in your version. Run a test workflow in each node type with oversized output, a long loop and a blocked network call, then compare the results. Repeat the test after every upgrade, because a node type may change behavior before the other.
Third-party package handling
If your workflows import third-party packages, confirm how the sandbox obtains them, whether it can reach a package index through the proxy, and whether packages persist between runs. A package pulled from the public internet is a dependency that the sandbox proxy must allow and that your change control must track. Ask whether installed packages are pinned, scanned and reviewed, and whether a workflow can change them at runtime.
Container runtime and host isolation
The sandbox is a container, so its protection depends on the runtime and the host beneath it. Check the container user, the privilege settings, filesystem mounts, kernel and runtime version, and whether the sandbox shares a host with other sensitive services. Compare these results with your own container hardening policy and with the controls your security team already applies to workloads that run untrusted code. Document any gap as an accepted risk or a required change.
Retention of sandbox run logs
Logs from code runs can contain input data, error text and fragments of model output, so they may hold sensitive information. Identify where the sandbox and the API write these logs, how long each store keeps them, and who can read them. Confirm the retention period in your environment, because it is set by your deployment and log pipeline rather than by a fixed default in this guide. Align the period with your data retention schedule and test that deletion actually runs.
How DeployOpen scopes and delivers sandbox hardening
The engagement is agreed in writing before work starts, then configuration is validated in your own environment, egress and timeout behavior is tested with purpose-built workflows, and the result is documented for your team and your assessors. Each step closes with a named output so you can confirm progress.
Agree the scope in writing
DeployOpen and your team confirm which Dify instances, workspaces and environments are in scope, who is allowed to author Code and Template nodes today, which model and tool endpoints the sandbox must reach, and which internal hosts, if any, need an exception. The scope, deliverables and timeline are written into a fixed-scope agreement before any change is made. Done when both parties have signed off the written scope and the list of open questions for your infrastructure team.
Collect the current configuration baseline
DeployOpen reviews the running deployment in your infrastructure, including the sandbox API key in the environment file, the sandbox service definition, the outbound proxy settings, the Squid proxy rules, the code execution timeouts and output limits, and the console roles that can edit workflows. Findings are recorded against the version you run, since the sandbox security changes in the Dify 1.16.1 release notes may or may not be present in your build. Done when a baseline record lists each setting and its current value.
Replace default credentials and restrict authors
Your team, with DeployOpen guiding the steps, replaces the default sandbox API key with a generated value stored in your secrets process, restarts the affected services, and confirms that the api and worker services authenticate successfully. Workspace roles are then adjusted so only named authors can create or edit Code and Template nodes. Done when a test login with the old key fails and a non-author account is confirmed unable to save a Code node.
Validate egress through the proxy
DeployOpen runs test workflows that attempt outbound requests from a Code node in several ways: to an approved endpoint, to a public host outside the allowlist, and to private and internal addresses. The tests confirm that traffic leaves only through the configured proxy and that private ranges are refused. Any exception needed for an approved internal host is added narrowly and retested. Done when the test results match the written egress policy and each exception has a recorded owner and reason.
Verify timeouts and output limits
Test workflows run code that exceeds the configured time limit, produces output above the size limit, and loops or allocates excessively, so the team can see how each failure surfaces in logs and in the workflow run view. Values are adjusted to match your largest legitimate workflows, and the chosen numbers are recorded with the reasoning. Done when each limit has been triggered once in a test, the failure is visible to operators, and the agreed values are documented.
Document the result and hand over
DeployOpen delivers a written record of the configuration changes, the egress and limit test results, the author list and the procedure for rotating the sandbox key. Your operators receive a runbook for checking the sandbox after each upgrade. This record supports your internal review and gives independent assessors evidence to examine. It is not an audit report or certification. Done when your team confirms receipt and the runbook has been walked through with the people who will operate the platform.
Re-verify after upgrades under a retainer
Dify ships minor releases roughly monthly, and each upgrade can change sandbox defaults, proxy rules or environment variables. DeployOpen can re-run the validation tests after each upgrade under a retainer, and can provide continuous testing if your policy requires it. Retainer scope and frequency are agreed in writing. Done when each upgrade has a recorded re-verification result that matches the documented baseline or lists the deviations.

