feat(selfhost): wire native Docker Compose secrets for the gittensory service#5121
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | 00cf22f | Commit Preview URL Branch Preview URL |
Jul 11 2026, 04:48 PM |
|
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 #5121 +/- ##
=======================================
Coverage 94.32% 94.32%
=======================================
Files 471 471
Lines 39821 39821
Branches 14533 14533
=======================================
Hits 37560 37560
Misses 1583 1583
Partials 678 678
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-11 16:56:36 UTC
⏸️ Suggested Action - Manual Review
Review summary Blockers
Nits — 7 non-blocking
Concerns raised — review before merging
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 Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. 🟩 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.
|
… service Adds a `secrets:` block for the 10 highest-value secrets (GitHub App private key, webhook secret, API/MCP/internal-job tokens, the setup token, the two token-encryption master keys, the Orb enrollment secret, and the PagerDuty routing key), file-mounted at /run/secrets/<name> instead of a plain environment/env_file value visible via `docker inspect`/`docker compose config`. Zero application code changes: reuses the existing generic <NAME>_FILE loader (src/selfhost/load-file-secrets.ts). Purely additive and backward-compatible -- an inline .env value always wins over the file, so migrating is optional and can be done one secret at a time. scripts/selfhost-init-secrets.sh idempotently creates empty placeholder files so a deploy never breaks for an operator who hasn't opted in; wired into both deploy scripts before they touch docker compose.
d99a816 to
00cf22f
Compare
Summary
secrets:block todocker-compose.ymlfor the 10 highest-value secrets the always-ongittensoryservice reads (GitHub App private key, webhook secret, API/MCP/internal-job tokens, the setup token, the two token-encryption master keys, the Orb enrollment secret, and the PagerDuty routing key). Each is file-mounted at/run/secrets/<name>instead of sitting as a plainenvironment:/env_filevalue visible viadocker inspect/docker compose config.<NAME>_FILEresolver (src/selfhost/load-file-secrets.ts, previously only demonstrated forGITHUB_APP_PRIVATE_KEY_FILE) — this PR just wires the Compose-level mount + sets the matching<NAME>_FILEenv default for the rest of the list..envvalue always takes priority over the file (existing loader behavior, unchanged), so this cannot break any current self-host operator (including the live edge-nl-01 instance, which keeps using inline.envvalues unless/until it migrates a secret at a time).scripts/selfhost-init-secrets.shidempotently creates empty placeholder files for every declared secret sodocker compose build/upnever fails on a missingsecrets:source file, even on a fresh checkout that has never touched this convention. Wired into bothdeploy-selfhost-prebuilt.shanddeploy-selfhost-image.shbefore they touchdocker compose, so every future deploy self-heals.secrets/README.mddocuments the convention;.env.selfhost.example,.env.example, and the/docs/self-hosting-securitypage point at it, making the pre-existing (but previously only prose) "Prefer secret files" guidance concrete and turnkey.Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run test:ci— full local gate green, includingui:openapi:check,ui:lint,ui:typecheck,ui:test,ui:build.npm audit --audit-level=moderate— 0 vulnerabilities.docker compose configvalidated with every profile active (postgres, observability, rees, qdrant, ollama, visual-review, caddy, tailscale, pgbouncer, runner, backup) — all 22 services resolve cleanly, no YAML errors.gittensoryservice forbusybox, confirmed/run/secrets/github_app_private_keyand/run/secrets/pagerduty_routing_keyexist and are readable inside the running container.scripts/selfhost-init-secrets.shtested directly: creates all 10 placeholder files on first run, correctly no-ops (never overwrites) on a second run.Safety
secrets/*files are gitignored except the README; verifiedgit add secrets/only stagesREADME.md.)/docs/self-hosting-security— no UI Evidence table needed (prose/code-block only, no new interactive states).Notes
Scoped to the always-on
gittensoryservice's own secrets for this pass. The same convention (onesecrets:entry + one<NAME>_FILEdefault) extends trivially to the optional-profile services' own secrets (Postgres password, Grafana admin password, Litestream S3 keys, Tailscale auth key, runner tokens, Qdrant/Browserless API keys) as a natural follow-up — left out here to keep this PR narrow and fully testable against the one service I can validate end-to-end.