SafetyCard Request a review

Dify

Low-code platform for agentic workflows and RAG pipelines

github.com/langgenius/dify · 2026-10-03 · 8222397

Defense-in-depth score

2.9 / 10

Dify as shipped runs model-chosen tool calls, including an Agent V2 shell with public internet access and the agent's secret environment variables, with no human approval anywhere. Service-to-service authentication in the default deployment is not locked down, and the shared shell sandbox can reach the agent backend. Credential storage, SSRF filtering, and audit records are solid; harden service credentials and isolate the shell before exposing published apps to untrusted users.

Safest setup

Dify keeps model-written code out of its API process, encrypts stored credentials, filters private addresses on tool traffic and records every tool call in its database. As shipped it runs an Agent V2 shell with internet access and the agent's secrets, with no approval step anywhere, so the safest setup narrows the credentials, moves or turns off that shell and puts containment around the stack.

SetupHowWhat it gives you
Scoped, low-limit keysGive each workspace only the provider and tool credentials its apps need, scoped or read-only with a spending limit set at the providerEvery app and end user reaches only the systems and spend you chose, since they all act with these stored keys C1
Shell only where neededSet AGENT_SHELL_ENABLED=false on the API for deployments whose agents don't need a shellAgent V2 runs without the unapproved script runner and its internet access C2
A remote shell sandboxDIFY_AGENT_RUNTIME_BACKEND=e2b with your E2B key, as in the shipped E2B compose overrideShell jobs run in remote per-binding sandboxes in place of one container shared by every workspace C4
Admin-only plugin installsSet the workspace plugin install permission to adminsThird-party plugins enter the workspace only by an admin's decision C7
Signed plugins onlyKeep the default FORCE_VERIFYING_SIGNATURE of true on the plugin daemonThe plugin daemon installs only signature-verified plugins C7
Concurrency and time limitsSet APP_MAX_ACTIVE_REQUESTS=<n> and lower WORKFLOW_MAX_EXECUTION_TIME to what your workflows needEach app runs a bounded number of requests at once, and each workflow ends at a time you chose C10
A private network, narrow egressRun the stack on a private network for trusted users, with the agent sandbox's outbound proxy limited to the hosts your tasks needFewer untrusted people reach your agents, and a narrow path for data to leave C5

Approving with confidence

  • Dify has no per-call approval; place a Human Input node before consequential steps in a workflow so a person reviews them first.
  • Before publishing an Agent V2 app, review the agent configuration changes made during build sessions, since they reach every user once published.

Handling data

  • Shell output shown to the agent is redacted only for the callback token unless you add patterns to DIFY_AGENT_SHELL_REDACT_PATTERNS.
  • Tool calls are stored in the database with their inputs and outputs; protect it like the data your agents read.
  • Anonymous, content-free usage telemetry is on by default; DISABLE_TELEMETRY=true turns it off.

Key gaps (4)

  1. The Agent V2 shell runs arbitrary model-written scripts with no approval and is enabled by default. C2 · Approval gates
  2. The shared local shell sandbox holds secret env vars, has public egress, and has a direct network route to the agent backend control plane. C4 · Code-execution isolation
  3. A hijacked agent can both exfiltrate (shell egress) and take irreversible tool actions with no human in the loop. C5 · Untrusted input blast radius
  4. The default shell prompt has the model install and run arbitrary public packages and MCP servers without consent, inside a sandbox holding the agent's secrets. C7 · Third-party extensions

Criteria

C1 Identity & least privilege

0.15 / 1.00

Agents and workflows act with workspace-level provider and tool credentials that any member can configure and that every end user of a published app then uses, with no per-user authorization. Service-to-service calls between the API, the plugin daemon, and the Agent V2 backend authenticate with single static keys, and those calls name the tenant in the request body; the default service credentials are also not locked down. The Agent V2 sandbox's own callback token is properly scoped by a signed execution context, but the sandbox can also reach the agent backend's control plane.

C2 Approval gates

0.00 / 1.00

No tool call is gated by a human by default. The classic agent runner, the workflow tool node, and the Agent V2 runtime all execute model-chosen tool calls directly, including the Agent V2 shell, which is enabled by default and runs arbitrary scripts with internet access. Workflows offer a Human Input node and Agent V2 offers an ask-human tool, but the first is a step a builder may place in a workflow and the second is a tool the model decides whether to call; neither gates the agent's actions. Consequential actions (third-party write APIs, outbound HTTP, shell) happen without a person seeing them.

C3 Tool & action scoping

0.45 / 1.00

Tool arguments are cast to their declared types, and outbound HTTP from OpenAPI tools, MCP clients, and the HTTP node goes through a Squid proxy that blocks private and metadata addresses on every hop, including redirects. But the toolset is general by design: an arbitrary-URL HTTP node, custom OpenAPI tools against any host, and an Agent V2 shell that takes raw scripts. Classic agent apps only receive tools the builder selected, while Agent V2 adds the shell by default. A misused tool can reach any public host with the workspace's credentials.

C4 Code-execution isolation

0.50 / 1.00

Model-driven code runs outside the API process: workflow code and template nodes go to the separate dify-sandbox service, and the Agent V2 shell runs in a dedicated non-root container with Landlock filesystem rules per job. That container is shared by every workspace on the deployment, its Landlock layer silently falls back to no isolation on unsupported kernels, and its policy configuration is not integrity-protected. Inside, the shell holds the agent's secret environment variables and a callback token, has public internet egress, and has a direct network route to the agent backend. An opt-in E2B backend moves the shell to a remote sandbox service.

C5 Untrusted input blast radius

0.20 / 1.00

Nothing structurally limits a hijacked agent. Untrusted content arrives from public web-app users, crawled web pages, uploaded documents, tool and MCP results, and shell output, and enters the model's context with no provenance marking beyond plain output tags on shell results. The same session can hold workspace secrets in the shell environment and has open egress through the shell and HTTP tools. A successful injection can therefore leak data and take irreversible actions with no human involved.

C6 Memory, context & configuration integrity

0.25 / 1.00

Conversation history is scoped to a conversation and knowledge-base retrieval is filtered by workspace in queries. Agent V2 lets the model itself push persistent changes to its own agent configuration (skills, notes, files, and environment variables) through the sandbox CLI, limited to build-draft sessions by a signed context; those changes load into later runs and reach end users once a builder publishes. Knowledge bases filled from crawled websites or uploaded documents are retrieved for every user of an app with no provenance or review step.

C7 Third-party extensions

0.07 / 1.00

Marketplace plugins are installed by pinned unique identifiers and the plugin daemon ships with signature verification forced on, but any workspace member may install plugins by default and patch updates are applied automatically without re-approval. Plugins run inside the plugin daemon container, which holds database and storage credentials and an unrestricted network route. Separately, the Agent V2 shell prompt tells the model to install whatever Python or Node packages and MCP servers it needs, and it does so without asking, inside a sandbox holding the agent's secrets.

C8 Secrets & sensitive-data protection

0.20 / 1.00

Stored provider and tool credentials are encrypted at rest with per-tenant RSA keys and masked in console responses. But default service credentials are not locked down, the Agent V2 shell receives configured secret values as environment variables while the prompt tells the model they are there, and only the callback token is redacted from shell output unless the operator adds patterns. Anonymous, content-free usage telemetry is on by default.

C9 Audit & traceability

0.63 / 1.00

Dify records every tool call in the database: classic agent thoughts store the tool, its input, and its observation; Agent V2 tool calls are relayed back and stored the same way; workflow node executions are persisted by default; and Human Input form submissions are recorded. Records are written by the API server, which the sandboxed shell cannot reach. The record is not tamper-evident, actor attribution is partial (classic agent thoughts are always stamped as account-created), and there is no correlation chain across nested workflows.

C10 Limits & kill switch

0.45 / 1.00

Classic agents are capped at 99 iterations, workflows at 500 steps and one hour, and Agent V2 runs at 500 model requests and one hour, with per-call timeouts for the code sandbox and plugins. There is no token or cost cap, per-app concurrency is unlimited by default, and stopping a run sets a flag the loop checks between steps. Nested workflows called as tools get their own budgets, bounded only by a call depth of five.