Skip to content

Commit b655096

Browse files
committed
Harden Docker compose gateway exposure
1 parent 986bba5 commit b655096

5 files changed

Lines changed: 35 additions & 8 deletions

File tree

packaging/docker/README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ From this directory:
88
```bash
99
cp calciforge.env.example .env
1010
mkdir -p data data-security-proxy data-clashd
11+
openssl rand -base64 32 > data/gateway-api-key
12+
chmod 600 data/gateway-api-key
1113
docker compose --env-file .env build calciforge
1214
docker compose --env-file .env up -d
1315
docker compose --env-file .env exec calciforge \
@@ -29,11 +31,18 @@ to the Compose mounts before starting the container. The sample Compose file
2931
uses `/config` for clean trials; live migrations should keep paths stable unless
3032
they are intentionally changing layout.
3133

32-
The example starts:
34+
The example publishes each service on `${CALCIFORGE_HOST_BIND:-127.0.0.1}` by default:
3335

34-
- `calciforge` on `${CALCIFORGE_PROXY_PORT:-18792}`
35-
- `security-proxy` on `${CALCIFORGE_SECURITY_PROXY_PORT:-8888}`
36-
- `clashd` on `${CALCIFORGE_CLASHD_PORT:-9001}`
36+
- `calciforge` on `${CALCIFORGE_HOST_BIND:-127.0.0.1}:${CALCIFORGE_PROXY_PORT:-18792}`
37+
- `security-proxy` on `${CALCIFORGE_HOST_BIND:-127.0.0.1}:${CALCIFORGE_SECURITY_PROXY_PORT:-8888}`
38+
- `clashd` on `${CALCIFORGE_HOST_BIND:-127.0.0.1}:${CALCIFORGE_CLASHD_PORT:-9001}`
39+
40+
Keep the default loopback host binding for local trials. If you intentionally set
41+
`CALCIFORGE_HOST_BIND=0.0.0.0` or another non-loopback address for LAN staging,
42+
first provision a strong gateway key in `data/gateway-api-key` and require clients
43+
to send it as `Authorization: Bearer <key>`. Do not expose the security proxy to
44+
untrusted networks; it is intended for controlled agent egress, not as a public
45+
forward proxy.
3746

3847
The Compose file builds the shared `calciforge:local` image through the
3948
`calciforge` service and reuses that image for the sidecars. Build the
@@ -45,7 +54,9 @@ small staging hosts; increase it only on builders with enough RAM.
4554

4655
The default Calciforge config points the model gateway at an OpenAI-compatible
4756
service on the host machine at `http://host.docker.internal:11434/v1`, which
48-
matches common Ollama-compatible local testing. Edit `config.example.toml` or set
57+
matches common Ollama-compatible local testing. It also reads the client-facing
58+
gateway bearer token from `/var/lib/calciforge/gateway-api-key`, backed by the
59+
`data/gateway-api-key` file created above. Edit `config.example.toml` or set
4960
`CALCIFORGE_CONFIG` before using it for real traffic.
5061

5162
Subprocess-backed agents run inside the Calciforge container. If you configure

packaging/docker/calciforge.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ CALCIFORGE_CLASHD_DATA=./data-clashd
1616
CALCIFORGE_PROXY_PORT=18792
1717
CALCIFORGE_SECURITY_PROXY_PORT=8888
1818
CALCIFORGE_CLASHD_PORT=9001
19+
# Published ports bind to loopback by default. Set to 0.0.0.0 only for intentional LAN exposure.
20+
CALCIFORGE_HOST_BIND=127.0.0.1
1921
RUST_LOG=calciforge=info,security_proxy=info,clashd=info

packaging/docker/config.example.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ version = 2
44
[proxy]
55
enabled = true
66
bind = "0.0.0.0:18792"
7+
api_key_file = "/var/lib/calciforge/gateway-api-key"
78
backend_type = "http"
89
backend_url = "http://host.docker.internal:11434/v1"
910
backend_api_key = "ollama"

packaging/docker/docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ services:
1111
environment:
1212
RUST_LOG: ${RUST_LOG:-calciforge=info}
1313
ports:
14-
- "${CALCIFORGE_PROXY_PORT:-18792}:18792"
14+
- "${CALCIFORGE_HOST_BIND:-127.0.0.1}:${CALCIFORGE_PROXY_PORT:-18792}:18792"
1515
volumes:
1616
- "${CALCIFORGE_CONFIG:-./config.example.toml}:/config/config.toml:ro"
1717
- "${CALCIFORGE_DATA:-./data}:/var/lib/calciforge"
@@ -29,7 +29,7 @@ services:
2929
SECURITY_PROXY_CONFIG: /config/security-proxy.toml
3030
AGENT_CONFIG: /config/agents.json
3131
ports:
32-
- "${CALCIFORGE_SECURITY_PROXY_PORT:-8888}:8888"
32+
- "${CALCIFORGE_HOST_BIND:-127.0.0.1}:${CALCIFORGE_SECURITY_PROXY_PORT:-8888}:8888"
3333
volumes:
3434
- "${CALCIFORGE_SECURITY_PROXY_CONFIG:-./security-proxy.example.toml}:/config/security-proxy.toml:ro"
3535
- "${CALCIFORGE_AGENTS_CONFIG:-./agents.example.json}:/config/agents.json:ro"
@@ -47,7 +47,7 @@ services:
4747
CLASHD_POLICY: /config/policy.star
4848
CLASHD_AGENTS: /config/agents.json
4949
ports:
50-
- "${CALCIFORGE_CLASHD_PORT:-9001}:9001"
50+
- "${CALCIFORGE_HOST_BIND:-127.0.0.1}:${CALCIFORGE_CLASHD_PORT:-9001}:9001"
5151
volumes:
5252
- "${CALCIFORGE_CLASHD_POLICY:-./policy.example.star}:/config/policy.star:ro"
5353
- "${CALCIFORGE_AGENTS_CONFIG:-./agents.example.json}:/config/agents.json:ro"

scripts/check-packaging.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,19 @@ grep -q "calciforge-ollama-switch" "$ROOT/scripts/build-dist-archive.sh" || {
5858
exit 1
5959
}
6060

61+
grep -q 'CALCIFORGE_HOST_BIND:-127.0.0.1' "$ROOT/packaging/docker/docker-compose.yml" || {
62+
echo "Docker Compose published ports must default to loopback host binding" >&2
63+
exit 1
64+
}
65+
grep -q 'api_key_file = "/var/lib/calciforge/gateway-api-key"' "$ROOT/packaging/docker/config.example.toml" || {
66+
echo "Docker example config must require a client-facing gateway API key file" >&2
67+
exit 1
68+
}
69+
grep -q 'openssl rand -base64 32 > data/gateway-api-key' "$ROOT/packaging/docker/README.md" || {
70+
echo "Docker README must provision the sample gateway API key before startup" >&2
71+
exit 1
72+
}
73+
6174
installer_shell_files=(
6275
"$ROOT/scripts/install.sh"
6376
"$ROOT/scripts/clean-install-reset.sh"

0 commit comments

Comments
 (0)