Context
dev-secrets.sh (#147 / #150) authenticates with a Bitwarden Secrets Manager machine-account access token. Today a developer's token reads the entire SM project — including deploy/infra-only secrets that local dev never needs: LIGHTSAIL_SSH_KEY, LIGHTSAIL_IP, GHCR_DEPLOY_TOKEN, GHCR_USERNAME. A leaked dev token therefore exposes production-deploy credentials, not just app-runtime ones.
This surfaced concretely while setting up #147: a dev token (and, via an over-broad bws secret list, GHCR_DEPLOY_TOKEN) leaked and had to be rotated. Least-privilege would have bounded that blast radius.
Scope (GitNexus)
Process/infra only — no application code change (the app reads whatever .env provides).
- Bitwarden (manual, console): create a dedicated dev machine account with read-only access to only the app-runtime secrets
dev-secrets.sh consumes (SECRET_KEY, R2_*, INSTAGRAM_*, FACEBOOK_*, OPENAI_API_KEY, TELEGRAM_*, SOUNDCLOUD_*, GITHUB_DISPATCH_TOKEN). Exclude all LIGHTSAIL_* / GHCR_*.
- Likely needs the secrets split across two projects (e.g.
app-runtime vs deploy-infra) so the dev account can be scoped to the first; the CI deploy account keeps access to both.
backend/scripts/dev-secrets.sh — already only fetches the app-runtime allowlist, so it keeps working; missing deploy keys just won't appear (already handled by the "not found in Bitwarden" notice). Verify no dev-needed key lives only in the deploy project.
.github/workflows/backend.yml — unchanged (uses the separate CI deploy account via BW_ACCESS_TOKEN); confirm its UUIDs still resolve after any project split.
backend/README.md — note that the dev token is read-only and app-runtime-scoped; deploy secrets are intentionally out of reach locally.
Acceptance criteria
Notes
Context
dev-secrets.sh(#147 / #150) authenticates with a Bitwarden Secrets Manager machine-account access token. Today a developer's token reads the entire SM project — including deploy/infra-only secrets that local dev never needs:LIGHTSAIL_SSH_KEY,LIGHTSAIL_IP,GHCR_DEPLOY_TOKEN,GHCR_USERNAME. A leaked dev token therefore exposes production-deploy credentials, not just app-runtime ones.This surfaced concretely while setting up #147: a dev token (and, via an over-broad
bws secret list,GHCR_DEPLOY_TOKEN) leaked and had to be rotated. Least-privilege would have bounded that blast radius.Scope (GitNexus)
Process/infra only — no application code change (the app reads whatever
.envprovides).dev-secrets.shconsumes (SECRET_KEY,R2_*,INSTAGRAM_*,FACEBOOK_*,OPENAI_API_KEY,TELEGRAM_*,SOUNDCLOUD_*,GITHUB_DISPATCH_TOKEN). Exclude allLIGHTSAIL_*/GHCR_*.app-runtimevsdeploy-infra) so the dev account can be scoped to the first; the CI deploy account keeps access to both.backend/scripts/dev-secrets.sh— already only fetches the app-runtime allowlist, so it keeps working; missing deploy keys just won't appear (already handled by the "not found in Bitwarden" notice). Verify no dev-needed key lives only in the deploy project..github/workflows/backend.yml— unchanged (uses the separate CI deploy account viaBW_ACCESS_TOKEN); confirm its UUIDs still resolve after any project split.backend/README.md— note that the dev token is read-only and app-runtime-scoped; deploy secrets are intentionally out of reach locally.Acceptance criteria
LIGHTSAIL_SSH_KEY,LIGHTSAIL_IP,GHCR_DEPLOY_TOKEN, orGHCR_USERNAME(verified:bws secret listwith a dev token does not return them).dev-secrets.shstill generates a working.envand the backend starts + uploads to R2 with a dev-scoped token.backend.yml) still resolves all its secret UUIDs and deploys successfully.Notes