fix: harden compose Pi auth mounts
This commit is contained in:
@@ -13,3 +13,4 @@ THT_DWH_REST_URL=https://dwh.example.invalid
|
||||
THT_VEC_REST_URL=https://vector.example.invalid
|
||||
THT_VEC_WRITE_REST_URL=https://vector-write.example.invalid
|
||||
THT_OLLAMA_URL=https://embeddings.example.invalid
|
||||
THT_LLM_URL=https://llm.example.invalid
|
||||
|
||||
@@ -25,10 +25,12 @@ services:
|
||||
THT_VEC_REST_URL: ${THT_VEC_REST_URL:-}
|
||||
THT_VEC_WRITE_REST_URL: ${THT_VEC_WRITE_REST_URL:-}
|
||||
THT_OLLAMA_URL: ${THT_OLLAMA_URL:-}
|
||||
THT_LLM_URL: ${THT_LLM_URL:-}
|
||||
MAX_PI_PROCESSES: ${MAX_PI_PROCESSES:-4}
|
||||
volumes:
|
||||
- settings:/data/settings
|
||||
- pi-state:/home/thoth/.pi
|
||||
- ${PI_AUTH_FILE:?set PI_AUTH_FILE}:/home/thoth/.pi/agent/auth.json:ro
|
||||
- workspace-registry:/data/workspace-registry
|
||||
- sessions:/data/sessions
|
||||
healthcheck:
|
||||
|
||||
@@ -8,6 +8,7 @@ services:
|
||||
volumes: !override
|
||||
- ${THT_DATA_ROOT:?set THT_DATA_ROOT}:/data
|
||||
- ${THT_PI_STATE_ROOT:?set THT_PI_STATE_ROOT}:/home/thoth/.pi
|
||||
- ${PI_AUTH_FILE:?set PI_AUTH_FILE}:/home/thoth/.pi/agent/auth.json:ro
|
||||
- ${THT_WORKSPACE_REGISTRY_ROOT:?set THT_WORKSPACE_REGISTRY_ROOT}:/data/workspace-registry
|
||||
restart: unless-stopped
|
||||
|
||||
|
||||
Vendored
+2
@@ -3,6 +3,7 @@
|
||||
THOTH_HTTP_PORT=8080
|
||||
THOTH_CORE_HTTP_PORT=8787
|
||||
MAX_PI_PROCESSES=4
|
||||
PI_AUTH_FILE=/absolute/path/to/pi-auth.json
|
||||
|
||||
THT_WORKSPACE_GIT_REMOTE=https://git.example.invalid/platform/thoth-workspaces.git
|
||||
THT_WORKSPACE_GIT_BRANCH=main
|
||||
@@ -14,3 +15,4 @@ THT_DWH_REST_URL=https://dwh.example.invalid
|
||||
THT_VEC_REST_URL=https://vector.example.invalid
|
||||
THT_VEC_WRITE_REST_URL=https://vector-write.example.invalid
|
||||
THT_OLLAMA_URL=https://embeddings.example.invalid
|
||||
THT_LLM_URL=https://llm.example.invalid
|
||||
|
||||
Vendored
+2
@@ -3,6 +3,7 @@
|
||||
THOTH_SERVER_BIND=127.0.0.1
|
||||
THOTH_HTTP_PORT=8080
|
||||
MAX_PI_PROCESSES=4
|
||||
PI_AUTH_FILE=/absolute/path/to/pi-auth.json
|
||||
|
||||
THT_DATA_ROOT=/srv/thothii/data
|
||||
THT_PI_STATE_ROOT=/srv/thothii/pi-state
|
||||
@@ -17,3 +18,4 @@ THT_DWH_REST_URL=https://dwh.example.invalid
|
||||
THT_VEC_REST_URL=https://vector.example.invalid
|
||||
THT_VEC_WRITE_REST_URL=https://vector-write.example.invalid
|
||||
THT_OLLAMA_URL=https://embeddings.example.invalid
|
||||
THT_LLM_URL=https://llm.example.invalid
|
||||
|
||||
@@ -26,6 +26,18 @@ if (/omics_portal|chirone|localllm_default|\/home\/chirone/i.test(JSON.stringify
|
||||
throw new Error("forbidden application coupling");
|
||||
}
|
||||
if (!config.networks || !config.networks.thothii) throw new Error("base stack must define the thothii network");
|
||||
if (!Object.hasOwn(config.services.core.environment || {}, "THT_LLM_URL")) {
|
||||
throw new Error("core must expose a generic THT_LLM_URL endpoint contract");
|
||||
}
|
||||
if (/docker\.sock|\/var\/run\/docker|docker[-_]?daemon/i.test(JSON.stringify(config.services))) {
|
||||
throw new Error("Compose must not mount the Docker socket or daemon");
|
||||
}
|
||||
const piAuthMounts = (config.services.core.volumes || []).filter(
|
||||
(mount) => mount.target === "/home/thoth/.pi/agent/auth.json",
|
||||
);
|
||||
if (piAuthMounts.length !== 1 || piAuthMounts[0].type !== "bind" || !piAuthMounts[0].read_only) {
|
||||
throw new Error("Pi auth must be one read-only file bind");
|
||||
}
|
||||
|
||||
const ports = Object.fromEntries(
|
||||
Object.entries(config.services).map(([name, service]) => [name, service.ports || []]),
|
||||
@@ -74,6 +86,18 @@ if (!config.networks || !config.networks.thothii) throw new Error("base stack mu
|
||||
for (const volume of ["settings", "pi-state", "workspace-registry", "sessions"]) {
|
||||
if (!config.volumes || !config.volumes[volume]) throw new Error(`missing required volume: ${volume}`);
|
||||
}
|
||||
if (!Object.hasOwn(config.services.core.environment || {}, "THT_LLM_URL")) {
|
||||
throw new Error("core must expose a generic THT_LLM_URL endpoint contract");
|
||||
}
|
||||
if (/docker\.sock|\/var\/run\/docker|docker[-_]?daemon/i.test(JSON.stringify(config.services))) {
|
||||
throw new Error("Compose must not mount the Docker socket or daemon");
|
||||
}
|
||||
const piAuthMounts = (config.services.core.volumes || []).filter(
|
||||
(mount) => mount.target === "/home/thoth/.pi/agent/auth.json",
|
||||
);
|
||||
if (piAuthMounts.length !== 1 || piAuthMounts[0].type !== "bind" || !piAuthMounts[0].read_only) {
|
||||
throw new Error("Pi auth must be one read-only file bind");
|
||||
}
|
||||
NODE
|
||||
|
||||
render_profile local deploy/env/local.env.example deploy/compose.local.yaml
|
||||
|
||||
Reference in New Issue
Block a user