feat: rebuild as multi-user web agent
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# 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.
|
||||
|
||||
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;
|
||||
- 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`.
|
||||
|
||||
## Deployment secrets
|
||||
|
||||
Secrets live only in a mode-600 deployment `.env` outside Git. Images contain
|
||||
no provider or infrastructure credentials. Any API key pasted into a chat
|
||||
should be rotated before deployment and the replacement placed in `.env`.
|
||||
|
||||
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
|
||||
|
||||
Local Docker provides process and filesystem isolation, but the Docker daemon
|
||||
remains a high-value boundary. Before treating the service as hostile
|
||||
multi-tenant infrastructure, move workspaces to the dedicated physical
|
||||
execution host, add egress policy, image signing/scanning, central audit
|
||||
retention, backup/restore tests, and resource-abuse alerts.
|
||||
Reference in New Issue
Block a user