Skip to content

Latest commit

 

History

History
122 lines (88 loc) · 8.2 KB

File metadata and controls

122 lines (88 loc) · 8.2 KB

Open WebUI setup

Both the code execution function and tool require the ability to run gVisor for secure sandboxing. Your Open WebUI instance needs to be set up to handle this.

Supported environment

This utility should work wherever gVisor works, i.e. x86_64/AMD64 and ARM64 processors.

gVisor only runs on Linux. However, if you are running on Windows or OS X, you can use Docker Desktop or similar container runtime which will automatically run a Linux virtual machine in which the container will actually run.

Container runtime setup

If you run Open WebUI inside a container, you will need to adjust its settings to grant gVisor the necessary privileges to work.

You can do this the easy way (good for single-user setups) by running Open WebUI in privileged mode, or the hard way to change the minimal set of things that still allows sandboxing to be possible.

The easy way: Run Open WebUI in privileged mode

  • On Docker: Add --privileged=true to docker run.
  • On Kubernetes: Set spec.securityContext.privileged to true.

This will remove all security measures from the Open WebUI container. From a security perspective, this is roughly equivalent to running the Open WebUI server as root outside of a container on the host machine. However, code running as part of this code execution function/tool will still run in a secure gVisor sandbox and cannot impact the host or the Open WebUI container.

This is adequate for single-user setups not exposed to the outside Internet, while still providing strong security against LLMs generating malicious code. However, if you are running a multi-user setup, or if you do not fully trust Open WebUI's code, or the Open WebUI server's HTTP port is exposed to the outside Internet, you may want to harden it further. If so, don't set the privileged setting, and read on to the hard way instead.

The hard way

The below is the minimal subset of changes that --privileged=true does that is still necessary for sandboxing to work.

  • Remove the container's default system call filter (seccomp):
  • Mount cgroupfs as writable:
    • On Docker: Add --mount=type=bind,source=/sys/fs/cgroup,target=/sys/fs/cgroup,readonly=false to docker run.
    • On Kubernetes: Add a hostPath volume with path set to /sys/fs/cgroup, then mount it in your container's volumeMounts with options mountPath set to /sys/fs/cgroup and readOnly set to false.
    • Why: This is needed so that gVisor can create child cgroups, necessary to enforce per-sandbox resource usage limits.
  • Set the container_engine_t SELinux label:
    • On Docker: Add --security-opt=label=type:container_engine_t to docker run.
    • On Kubernetes: Set spec.securityContext.seLinuxOptions.type to container_engine_t.
    • Why: The default SELinux label for containers (container_t) does not allow the creation of namespaces, which gVisor requires for additional isolation . The container_engine_t label allows this.
    • If you don't have SELinux enabled, this setting does nothing and may be omitted.

Self-test mode

To verify that your setup works, you can run the tool in self-test mode using run_code.py's --use-sample-code flag.

For example, here is a Docker invocation running the run_code.py script inside the Open WebUI container image with the above flags:

$ git clone https://github.com/EtiennePerot/open-webui-code-execution && \
  docker run --rm \
    --security-opt=seccomp=unconfined \
    --security-opt=label=type:container_engine_t \
    --mount=type=bind,source="$(pwd)/open-webui-code-execution",target=/selftest \
    ghcr.io/open-webui/open-webui:main \
    python3 /selftest/open-webui/tools/run_code.py --self_test

If all goes well, you should see:

⏳ Running self-test: simple_python
✔ Self-test simple_python passed.
⏳ Running self-test: simple_bash
✔ Self-test simple_bash passed.
⏳ Running self-test: bad_syntax_python
✔ Self-test bad_syntax_python passed.
⏳ Running self-test: bad_syntax_bash
✔ Self-test bad_syntax_bash passed.
⏳ Running self-test: long_running_code
✔ Self-test long_running_code passed.
⏳ Running self-test: ram_hog
✔ Self-test ram_hog passed.
✅ All self-tests passed, good go to!

If you get an error, try to add the --debug flag at the very end of this command (i.e. as a run_code.py flag) for extra information, then file a bug.

Set valves

The code execution tool and function have the following valves available:

  • Networking allowed: Whether or not to let sandboxed code have access to the network.
    • Note: If you are running Open WebUI on a LAN, this will expose your LAN.
  • Max runtime: The maximum number of time (in seconds) that sandboxed code will be allowed to run.
    • Useful for multi-user setups to avoid denial-of-service, and to avoid running LLM-generated code that contains infinite loops forever.
  • Max RAM: The maximum amount of memory the sandboxed code will be allowed to use, in megabytes.
    • Useful for multi-user setups to avoid denial-of-service.
  • Auto Install: Whether to automatically download and install gVisor if not present in the container.
    • If not installed, gVisor will be automatically installed in /tmp.
    • Useful for convenience, but should be disabled for production setups.
  • Debug: Whether to produce debug logs.
    • This should never be enabled in production setups as it produces a lot of information that isn't necessary for regular use.
    • When filing a bug report, please enable this valve, then reproduce the issue in a new chat session, then download the chat log (triple-dot menu → DownloadExport chat (.json)) and attach it to the bug report.

Optional: Pre-install gVisor

To avoid the tool having to download and install gVisor on first run, you can pre-install gVisor in your Open WebUI container image or environment. Follow the gVisor installation guide. At the end, the command runsc --version (run within the Open WebUI container if you are running it in a container) should work and return the gVisor version you installed.

Optional: Lockdown for production setups

TODO: Add environment variables that take precedence over valves to allow multi-user setups.