Harden default Docker Compose security

This commit is contained in:
Yuxin Lou
2026-07-18 17:37:41 +08:00
committed by Xubin Ren
parent d35f99abfc
commit b76d54aae1
4 changed files with 42 additions and 12 deletions
+16
View File
@@ -0,0 +1,16 @@
x-bwrap-security: &bwrap-security
cap_add:
- SYS_ADMIN
security_opt:
- apparmor=unconfined
- seccomp=unconfined
services:
nanobot-gateway:
<<: *bwrap-security
nanobot-api:
<<: *bwrap-security
nanobot-cli:
<<: *bwrap-security
-5
View File
@@ -6,11 +6,6 @@ x-common-config: &common-config
- ~/.nanobot:/home/nanobot/.nanobot
cap_drop:
- ALL
cap_add:
- SYS_ADMIN
security_opt:
- apparmor=unconfined
- seccomp=unconfined
services:
nanobot-gateway:
+1 -1
View File
@@ -1919,7 +1919,7 @@ For API keys, tokens, and other secrets, see [Environment Variables for Secrets]
| `tools.ssrfWhitelist` | `[]` | CIDR ranges exempted from the shared SSRF guard used by web fetches and HTTP/SSE MCP connections. Prefer exact host CIDRs such as `192.168.1.50/32`; broad ranges increase SSRF exposure. |
| `channels.*.allowFrom` | omitted | Access control per channel. Omit to use pairing-only mode; set `["*"]` to allow everyone; or list specific user IDs. See [Pairing](#pairing) for details. |
**Docker security**: The official Docker image runs as a non-root user (`nanobot`, UID 1000) with bubblewrap pre-installed. When using `docker-compose.yml`, the container drops all Linux capabilities except `SYS_ADMIN` (required for bwrap's namespace isolation).
**Docker security**: The official Docker image runs as a non-root user (`nanobot`, UID 1000) with bubblewrap pre-installed. The default `docker-compose.yml` drops all Linux capabilities and keeps Docker's default AppArmor/seccomp profiles enabled. If you enable `"tools.exec.sandbox": "bwrap"` inside Docker, start Compose with `docker-compose.bwrap.yml` as an additional override so bubblewrap can create nested namespaces.
## Pairing
+25 -6
View File
@@ -74,6 +74,20 @@ docker compose logs -f nanobot-gateway # view logs
docker compose down # stop
```
The default Compose file drops all Linux capabilities and keeps Docker's default
AppArmor/seccomp profiles enabled. If you explicitly set
`"tools.exec.sandbox": "bwrap"` in `~/.nanobot/config.json`, add the bwrap
override file when starting containers:
```bash
docker compose -f docker-compose.yml -f docker-compose.bwrap.yml up -d nanobot-gateway
docker compose -f docker-compose.yml -f docker-compose.bwrap.yml run --rm nanobot-cli agent -m "Hello!"
```
The override grants `CAP_SYS_ADMIN` and disables AppArmor/seccomp confinement for
the container so bubblewrap can create its nested namespaces. Use it only when the
bwrap sandbox is enabled.
### Docker
```bash
@@ -87,12 +101,17 @@ docker run -v ~/.nanobot:/home/nanobot/.nanobot --rm nanobot onboard
vim ~/.nanobot/config.json
# Run gateway (connects to enabled channels, e.g. Telegram/Discord/Mochat).
# Mirrors the security caps and port mappings declared in docker-compose.yml:
# - `--cap-drop ALL --cap-add SYS_ADMIN` + unconfined apparmor/seccomp are required
# when `tools.exec.sandbox: "bwrap"` is enabled (bwrap needs CAP_SYS_ADMIN for
# user namespaces). Without them, `bwrap` exits with `clone3: Operation not permitted`.
# - `-p 8765:8765` exposes the WebSocket channel / WebUI alongside the gateway health
# endpoint on 18790.
# `-p 8765:8765` exposes the WebSocket channel / WebUI alongside the gateway
# health endpoint on 18790.
docker run \
--cap-drop ALL \
-v ~/.nanobot:/home/nanobot/.nanobot \
-p 18790:18790 -p 8765:8765 \
nanobot gateway
# If `tools.exec.sandbox: "bwrap"` is enabled, run with the extra permissions
# bubblewrap needs for nested namespaces. Without them, `bwrap` may exit with
# `clone3: Operation not permitted`.
docker run \
--cap-drop ALL --cap-add SYS_ADMIN \
--security-opt apparmor=unconfined \