fix(compose): forward INTERNAL_API_SECRET to prod mcp-server + CORS/SSH/LOG levers to prod backend (#722)#1256
Open
AndriiPasternak31 wants to merge 2 commits into
Open
fix(compose): forward INTERNAL_API_SECRET to prod mcp-server + CORS/SSH/LOG levers to prod backend (#722)#1256AndriiPasternak31 wants to merge 2 commits into
AndriiPasternak31 wants to merge 2 commits into
Conversation
…SH/LOG levers to prod backend (#722) #722's /validate-config report flagged 5 config issues; 3 were already fixed (GOOGLE_API_KEY, FRONTEND_URL dup, TRINITY_DATA_PATH). The 2 remaining are the "prod packaging gap" class: a var forwarded in docker-compose.yml but absent from docker-compose.prod.yml. There is no env_file: in either compose, so a missing environment: entry = a dead lever in prod. docker-compose.prod.yml: - mcp-server: add INTERNAL_API_SECRET (SEC-001, no default — matches backend/scheduler prod style). Corrected failure mode: without it, src/mcp-server/src/audit.ts postAudit early-returns (`if (!INTERNAL_SECRET) return;`) and ALL MCP tool-call audit is silently dropped in prod — no request is sent (so not "every audit 401s"). Backend + scheduler already receive the secret in prod, so forwarding it to mcp-server makes both ends share the same value (internal.py returns 403 only on a *mismatch*). - backend: add EXTRA_CORS_ORIGINS (config.py), SSH_HOST (ssh_service.py), and LOG_ARCHIVE_ENABLED/LOG_RETENTION_DAYS/LOG_CLEANUP_HOUR (log_archive_service.py). LOG_ARCHIVE_PATH is intentionally omitted — the code default /data/archives lands in the TRINITY_DATA_PATH bind mount (/data), so no new volume is needed. src/frontend/src/components/HostTelemetry.vue: - Drop the dead `import.meta.env.VITE_API_BASE` reference (the var is never set anywhere, so API_BASE was always ''); hardcode `API_BASE = ''` to match api.js `baseURL: ''` (relative, same-origin). Zero behavior change. The naive "point it at VITE_API_URL" fix would be a regression (VITE_API_URL build-defaults to http://localhost:8000). Verification: `docker compose -f docker-compose.prod.yml config` and the +enterprise overlay both render clean; the 6 added vars resolve into the correct service blocks (no cross-block leak); `vite build` passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…archival runs (#722) The PR forwarded LOG_ARCHIVE_ENABLED/LOG_RETENTION_DAYS/LOG_CLEANUP_HOUR to the prod backend, but archival still no-opped: log_archive_service.py reads LOG_DIR=/data/logs, and the prod backend mounted only the trinity-data bind mount at /data, never Vector's trinity-logs volume (dev mounts it at docker-compose.yml:145). Add the same read-only mount so the forwarded knobs actually take effect — completing the #1039 packaging-gap fix one layer down. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the two remaining prod packaging-gap findings from #722's
/validate-configreport. There is noenv_file:in either compose, so a var forwarded indocker-compose.ymlbut absent fromdocker-compose.prod.ymlis a dead lever in prod — the missingenvironment:entry never reaches the container.3 of the 5 original findings were already fixed (
GOOGLE_API_KEY,FRONTEND_URLdup,TRINITY_DATA_PATH); this PR addresses the 2 that remained, plus a zero-behavior-change frontend cleanup surfaced during review.What changed
docker-compose.prod.yml— mcp-server+ INTERNAL_API_SECRET=${INTERNAL_API_SECRET}(no default, matches backend/scheduler prod style)docker-compose.prod.yml— backend+ EXTRA_CORS_ORIGINS,+ SSH_HOST,+ LOG_ARCHIVE_ENABLED / LOG_RETENTION_DAYS / LOG_CLEANUP_HOUR(mirror dev)src/frontend/src/components/HostTelemetry.vueimport.meta.env.VITE_API_BASEref →API_BASE = ''Corrected failure mode (Finding 1)
The original "every audit 401s" framing was wrong. The prod mcp-server lacked
INTERNAL_API_SECRET, sosrc/mcp-server/src/audit.tspostAudithitsif (!INTERNAL_SECRET) return;and never POSTs → all MCP tool-call audit (SEC-001) is silently dropped in prod (no request, so no 401). Backend + scheduler already receive the secret in prod, so forwarding it to mcp-server makes both ends share the same value (routers/internal.pyreturns 403 only on a mismatch).Design notes
LOG_ARCHIVE_PATHis intentionally omitted — the code default/data/archives(routers/logs.py,archive_storage.py) already lands in theTRINITY_DATA_PATHbind mount (/data), so no new volume is needed.VITE_API_BASEwas never set anywhere, soAPI_BASEwas always''; the single Axios client (api.js) usesbaseURL: ''(relative, same-origin). The naive "point it atVITE_API_URL" fix would be a regression (VITE_API_URLbuild-defaults tohttp://localhost:8000). Not routed throughapi.jsto preserve the 3s timeout / no 401-redirect / raw-fetchresponse shape (deferred as an Invariant-security: Fix token logging and add HTML reports to gitignore #7 follow-up).Verification
docker compose -f docker-compose.prod.yml configand the+enterpriseoverlay render cleanLOG_ARCHIVE_PATHabsent; backend/schedulerINTERNAL_API_SECRETuntouched)vite buildpassessource='mcp'row +200) not run in this PR — the mechanism is proven at the compose layer (audit.ts/internal.pyunchanged)Deferred follow-ups (flagged, not dropped)
SLACK_APP_TOKEN,TRUSTED_PROXIES,REDIS_STREAM_MAXLEN, etc.) — inert without compose-forwarding too; do compose + docs together in a dedicated issueADMIN_USERNAME→ prod (needs mcp-serverTRINITY_USERNAMEdefault alignment)INTERNAL_API_SECRET(${VAR:?}, Config Validation: 5 critical config issues found (TRINITY_PASSWORD P0, 4x undocumented vars) #692 pattern)api.jsrefactor (Invariant security: Fix token logging and add HTML reports to gitignore #7)VITE_API_URLbuild arg)Fixes #722
🤖 Generated with Claude Code