Skip to main content

Custom code execution security

The code-executor container executes arbitrary user-written code for custom JavaScript or Python libraries in workflows. Retool recommends running code-executor with sandboxing enabled, for flow safety and data security reasons. But Retool does support running without sandboxing enabled, as it requires privileged container access, which some organizations do not allow.

Privileged container access is commonly restricted by default and why Retool allows code-executor to run in unprivileged mode. Should this be the case, Retool recommends an exception be made so that Retool can run as a trusted product or framework. This will allow code-executor to safely manage your operational code.

Security, functionality, and usability

Retool follows three core philosophies when developing the self-hosted architecture: security, functionality, and usability.

PriorityDescription
SecurityProtect systems and data with strong safeguards.
FunctionalityBuild powerful and flexible features.
UsabilityProvide straightforward and low-friction experiences.

Too much focus on one priority can be at the detriment of the others. Retool's approach is to always strike the right balance across all three.

Due to the potential impact that executing arbitrary code can have, Retool prioritizes security and functionality above usability. As such, Retool's architecture is built so that this custom code is executed in a secure, sandboxed environment but without arbitrary restrictions. This approach ensures that customers don't have to review and ensure that all custom code written by their users is free from bugs or malicious code.

Sandboxed environment with NsJail

Retool uses NsJail, a process isolation tool for Linux, to securely execute custom code. NsJail levegages Linux kernel features such as namespaces, control groups (cgroups), and seccomp-bpf syscall filters to isolate custom code from the rest of the system.

By doing so, NsJail is able to isolate the file system, restrict network access, and enforce CPU and memory limits to prevent any single workflow from impacting overall system stability.

Priviledged and unprivileged modes

Docker containers can be run in either unprivileged or privileged mode.

ModeDescription
UnprivilegedIf the container cannot run with --privileged, NsJail cannot apply its sandbox. In this case, custom code runs without Retool’s isolation safeguards, and you must fully trust all user-written code.
PrivilegedIn self-hosted Retool, the code-executor container is configured with Docker’s --privileged flag. This allows NsJail to configure the kernel features required for sandboxing. NsJail then executes user code inside a jailed process with reduced privileges.

The code-executor container is configured to run in privileged mode by default. Retool only uses the minimum amount of elevated permissions necessary to implement sandboxing and relinquishes these once no longer required.

Only the code-executor container is configured to run in privileged mode—all other backend services operate separately without any form of elevated permissions.

Retool strongly recommends that self-hosted organizations always use privileged mode unless there are specific reasons which prevent this.

Exceptions for using unprivileged mode

In some cases, it may not be possible for a self-hosted deployment instance to run code-executor in priviledged mode. For instance:

  • Managed container orchestration environments, such as GKE Autopilot and AWS Fargate, do not allow the use of privileged containers.
  • Kubernetes clusters with pod security policies can explicitly block privileged containers.

Retool provides customers with the option of running the container in unprivileged mode for these types of situations. When you configure code-exector to use unprivileged mode, however, many of the safeguards that sandboxing provide are no longer in place. This assumes that you fully trust all user-written custom code that is executed.

Risks of non-sandboxed custom code environment

A non-sandboxed environment should only be used if an organization can trust that all users will not write code that is either malicious or critically flawed.

Risk CategoryExamples
Data risksExfiltrating credentials or sensitive data to an external attacker; accessing or manipulating restricted data.
Account risksCompromising or taking control of other user accounts.
Execution risksInterfering with future code execution. Bugs or malicious code can cause unexpected or unstable results.
System risksDamaging the deployment instance by deleting or modifying critical system files. Bugs in user code can also cause unintended damage, such as erroneous deletion of files or unpredictable outcomes.
External misuseCoordinating targeted attacks using the deployment instance.