feat(miner): add GITHUB_TOKEN_FILE secret-mount indirection for fleet mode - #5560
Conversation
… mode The miner is a separate deployable from ORB (its own process/container per DEPLOYMENT.md's fleet mode), so it never ran through ORB's own src/selfhost/load-file-secrets.ts server-startup resolver -- a plain GITHUB_TOKEN env var is visible in plaintext via `docker inspect` on any host running the miner, with no file-mount alternative. Add a generic <NAME>_FILE resolver, ported from that same ORB pattern, called once at CLI startup (before any subcommand dispatches or reads process.env) so it covers GITHUB_TOKEN and any coding-agent env-var credential with zero changes to the individual call sites that already read those vars. Diverges from the ORB analogue on purpose: throws (rather than logging and continuing) on a missing/unreadable file, so a broken secret mount fails a container fast and loud. Fixes JSONbored#5178
|
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 #5560 +/- ##
=======================================
Coverage 94.91% 94.91%
=======================================
Files 570 571 +1
Lines 45351 45360 +9
Branches 14675 14675
=======================================
+ Hits 43046 43055 +9
Misses 1571 1571
Partials 734 734
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-13 05:18:16 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 5 non-blocking
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 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
DEPLOYMENT.md's fleet mode —so it never runs through ORB's own
src/selfhost/load-file-secrets.tsserver-startup resolver.GITHUB_TOKEN(and any coding-agent credential passed via env var) is only ever readable as a plain env var, meaning its
value is visible in plaintext via
docker inspect/docker compose configon any host running the miner,with no file-mount alternative for Docker Swarm/Kubernetes-managed secrets.
packages/gittensory-miner/lib/env-file-indirection.js(+.d.ts): a generic<NAME>_FILEresolverported from ORB's exact pattern. It's generic by design — it scans
envfor any<NAME>_FILEkey andresolves it into
<NAME>— so one early call at CLI startup (before any subcommand dispatches, inbin/gittensory-miner.js) coversGITHUB_TOKENand any coding-agent env-var credential(
CLAUDE_CODE_OAUTH_TOKEN,ANTHROPIC_API_KEY) with zero changes to the several individual call sitesthroughout the package that already read
env.GITHUB_TOKENdirectly (discover-cli.js,loop-cli.js,manage-poll.js,attempt-cli.js).missing/unreadable
<NAME>_FILEthrows (rather than logging and continuing), so a broken secret mountfails a miner container fast and loud with a clear message naming the var and path — never a silent
empty/undefined credential that surfaces later as a confusing GitHub 401.
bin/gittensory-miner.jscatchesthat throw and exits 1 with the message, instead of an uncaught-exception stack trace.
<NAME>value always wins over<NAME>_FILE.DEPLOYMENT.md's fleet-modedocker runexample with aGITHUB_TOKEN_FILEalternative (Swarm/K8ssecret-mount style) alongside the existing plain-env-var example, and added a commented example to the
repo-root
.gittensory-miner.env.examplestarter file.Fixes #5178
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 —packages/gittensory-miner/lib/**/*.jsis included in this repo'scodecov/patchgate. Targeted coverage run (--coverage.includescoped toenv-file-indirection.js): 100% statements, 100% branches, 100% functions, 100% lines.bin/gittensory-miner.jsis NOT incoverage.include(onlylib/**is), so its lines aren't Codecov-patch-gated; its wiring is instead proven by real end-to-end tests below rather than coverage numbers.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run build:minernpm run test:miner-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateRan the full local gate:
npm run test:ci(803 test files, 0 failures) andnpm audit --audit-level=moderate(0 vulnerabilities), both clean on the final rebased commit.New
test/unit/miner-env-file-indirection.test.ts(13 tests): plain-var-only,_FILE-only (trimmed), both-set precedence, neither-set, missing/unreadable file (throws, with both theErrorand non-Errorfallback branches covered), an empty-but-readable file resolving to""(not an error),COMPOSE_FILE/COMPOSE_ENV_FILEexclusion (mirrors the ORB analogue's own reserved-var guard), multiple independent_FILEvars resolved in one pass, an invariant asserting a thrown error message never contains the resolved secret's own value, and — beyond unit coverage — two real end-to-end tests that spawn the actualbin/gittensory-miner.jsbinary: one confirmingGITHUB_TOKEN_FILEresolves correctly through the real CLI with the secret value never appearing in stdout/stderr, one confirming a broken_FILEpath fails the real process with exit 1 and a clear stderr message.Safety
UI Evidencesection below. — N/A, see below.DEPLOYMENT.mdand.gittensory-miner.env.example.UI Evidence
N/A — this is a local CLI-only credential-resolution change with no visible UI surface. No screenshots apply.
Notes
env-file-indirection.js, not something with "secret" in the name — this PR's own localgate (
npm run test:miner-pack→scripts/check-miner-package.mjs) caught a real, self-inflicted defectbefore ever pushing: the package's own npm-pack safety guard forbids any packed file whose path matches
.*secret.*(case-insensitive), so the module was originally namedload-file-secrets.jsand had to berenamed. A related second hit:
DEPLOYMENT.md's first draft literally wrote`-e GITHUB_TOKEN=...`inprose, which matched the same guard's content-side check for a
TOKEN=assignment shape — reworded to dropthe
=.... Both were caught and fixed by running the exact regexes fromscripts/check-miner-package.mjs/scripts/forbidden-content.mjsdirectly against every touched file before the final push, not just byre-running the test suite and hoping.
GITHUB_TOKENand any coding-agent credential passed via a plain env var. Explicitly notapplied to
codex-cli's credential, which is already a file path (auth.json) read directly today, not anenv-var-provided secret value —
<NAME>_FILEindirection doesn't apply to something that's already a filereference, so there's nothing to port there.
packages/gittensory-engine/**— the coding-agent driver's own construction path continues toread whichever env var it already reads; this PR only ensures that var is populated correctly before
construction happens, via the single early resolver call.