fix(selfhost): exclude Docker Compose's reserved _FILE vars from the secret-dereference scan - #4729
Conversation
…secret-dereference scan (#4403) loadFileSecrets() treats every *_FILE env var as a gittensory Docker-secret pointer, including Compose's own reserved COMPOSE_FILE (a colon-delimited list of compose file paths, never a single readable file) and COMPOSE_ENV_FILE. Both threw on every readFileSync attempt, logging a guaranteed-false level:error on every container boot -- undermining the convention that error-level logs are real operator-alertable signals. Also extracts loadFileSecrets into its own module: server.ts boots the whole app on import and is Codecov-ignored, so it had no way to carry a real runtime regression test for this fix.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4729 +/- ##
=======================================
Coverage 94.21% 94.21%
=======================================
Files 439 440 +1
Lines 38704 38714 +10
Branches 14101 14104 +3
=======================================
+ Hits 36466 36476 +10
Misses 1576 1576
Partials 662 662
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-10 21:56:16 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 7 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
loadFileSecrets()scans every env var ending in_FILEand dereferences it as a gittensory Docker-secret pointer. It had no exclusion for Docker Compose's own reservedCOMPOSE_FILE(a colon-delimited list of compose file paths, e.g.docker-compose.yml:docker-compose.override.yml:docker-compose.local-gpu.yml) orCOMPOSE_ENV_FILE— neither is ever a single readable file, soreadFileSyncalways throws, logging a guaranteed-falselevel:"error"structured line on every container boot. Confirmed live on edge-nl-01 tonight ({"level":"error","event":"selfhost_secret_file_unreadable","var":"COMPOSE_FILE"}on every deploy).level:"error"logs are the actual signal for Sentry-visible operator alerts. A guaranteed false alarm on every restart trains operators to ignore them._FILEvars by name before the dereference attempt.loadFileSecretsinto its own module (src/selfhost/load-file-secrets.ts), injectingenv/readFileas optional params (defaulting toprocess.env/realreadFileSync, byte-identical at runtime) —server.tsitself boots the entire app on import and is Codecov-ignored, so there was no way to give this fix a real runtime regression test while it lived there.Closes #4403
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateCOMPOSE_FILEset → no dereference attempt, no error log).npm run engine-parity:drift-check— clean (this file isn't a hand-duplicated twin).If any required check was skipped, explain why:
test:coveragewas run targeted on the new test file (7/7 passing, 100% line/branch/function coverage onsrc/selfhost/load-file-secrets.ts) rather than the full unsharded suite.Safety
hasGenericSecretAssignmentdetector directly — clean.)UI Evidencesection below. (N/A — no visible UI change)UI Evidence
N/A — no UI/frontend/docs-visible change.
Notes