Files
zk-data-agent/docs/security.md
T
2026-07-26 21:32:12 +08:00

80 lines
3.5 KiB
Markdown

# Security model
[中文](security.zh-CN.md) · English
## 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.