Files
zk-data-agent/docs/security.md
T
2026-07-26 20:20:37 +08:00

3.4 KiB

Security model

Trust boundaries

Only Open WebUI is public. Runtime, Gateway, PostgreSQL, and Redis are on an internal Compose network.

Open WebUI forwards a short-lived HS256 user JWT. Runtime and Gateway verify the signature, issuer, expiry, and subject. They also require independent service bearer keys, so a copied user identity token alone cannot call either service. Runtime verifies the public request once, then re-signs the already verified identity with a fresh short-lived token for every Gateway call. Long Agent runs therefore do not reuse an expired request token.

The browser never receives:

  • the upstream provider URL or API key;
  • provider model IDs;
  • the Workspace Gateway service key;
  • the user identity signing key;
  • Docker, SSH, MCP/OpenAPI, prompt, or experiment configuration.

Workspace isolation

Each user gets a dedicated container and named volume derived from a SHA-256 hash of the immutable Open WebUI user ID. Containers:

  • run as UID/GID 1000;
  • have a read-only root filesystem and writable /workspace volume;
  • keep Python virtual environments and user package/cache state under the persistent /workspace volume;
  • use a dedicated per-user bridge network when egress is enabled;
  • drop every Linux capability;
  • enable no-new-privileges;
  • receive memory, CPU, and PID limits;
  • do not receive the Docker socket;
  • expose no ports to the host.

Only Workspace Gateway receives the Docker socket in local mode. Runtime and Open WebUI never receive it. Remote mode removes the socket mount, mounts the chosen SSH configuration read-only, and moves Docker access to an SSH-connected execution host.

Workspace paths are normalized and rejected if they escape /workspace. File browsing and downloads use the same identity boundary. Single-file downloads are bounded to 128 MiB by default; directory archives are streamed.

Deployment secrets

Secrets live only in a mode-600 deployment .env outside Git. Images contain no provider or infrastructure credentials. Provider credentials are never returned to the browser, logged by application code, or committed to Git.

The Web image is rebuilt from a commit-pinned Open WebUI release on digest-pinned Node and Python bases. RAG/vector, cloud storage, media model, browser automation, and unused cryptographic dependencies are excluded. Release acceptance audits both the repository environment and the finished Web image. scripts/audit-web-image.sh requires:

  • pip check to report a consistent Python environment;
  • pip-audit to report zero known Python vulnerabilities, with no ignored IDs;
  • Trivy to report zero fixable High/Critical OS or library vulnerabilities.

scripts/audit-images.sh applies the fixable High/Critical gate to Web, Runtime, Gateway, and the user Workspace image. As of 2026-07-26 all four pass. Trivy also reports 38 High/Critical Debian findings in the Web image for which the distribution publishes no fix; the release gate records these separately through --ignore-unfixed rather than pretending an application change can remediate them.

Remaining hardening before hostile public use

Workspaces run on a dedicated physical Docker host, separated from the public web and database services. The Docker daemon remains a high-value boundary. Before treating the service as hostile multi-tenant infrastructure, add per-workspace egress policy, image signing, central audit retention, backup/restore drills, quotas, and resource-abuse alerts.