Skip to content

fix(security): harden infrastructure and CI (sec-infra-01..12)#46

Merged
Abdulkhalek-1 merged 2 commits into
mainfrom
fix/security-infra-2026-04-07
Jul 8, 2026
Merged

fix(security): harden infrastructure and CI (sec-infra-01..12)#46
Abdulkhalek-1 merged 2 commits into
mainfrom
fix/security-infra-2026-04-07

Conversation

@Abdulkhalek-1

Copy link
Copy Markdown
Member

Summary

Implements 12 infrastructure hardening plans covering secrets, containers, CI scanning, and dev environment defaults.

# Plan Fix
01 lavalink-password Remove hardcoded `youshallnotpass`, fail-fast in prod
02 docker-secrets Migrate prod `env_file` → Docker secrets with `*_FILE` pattern
03 backup-pgpass Backup service uses `.pgpass` from secret instead of `PGPASSWORD`
04 dockerfile-nonroot Dev/test stages now run as `node` user
05 dev-postgres-password Parameterize dev postgres password
06 bot-sync-secret-fail-fast `BOT_SYNC_SECRET` prod fail-fast (unset or <32 chars)
07 vite-bind-localhost Vite dev server defaults to `127.0.0.1`
08 ci-security-scanning New `security.yml` workflow (pnpm audit + gitleaks + Trivy)
09 env-example-lavalink Blank Lavalink default + CI grep guard
10 pgadmin-credentials Parameterize pgAdmin credentials
11 postgres-port-exposure `docker-compose.no-db-port.yml` override + CI guard
12 dockerignore-env-guard Broaden `.dockerignore`/`.gitignore` to `.env.*`

Breaking changes

Developers must set these env vars before `pnpm dev`:

  • `PGADMIN_PASSWORD` (only if using the `tools` profile — uses `:?` guard)

Production deploy requires:

  • Populate `secrets/` directory with token files for each Docker secret
  • Rotate any existing `.env.prod` secrets and move them to files
  • Ensure `LAVALINK_PASSWORD` and `BOT_SYNC_SECRET` are set (`≥32 chars`)
  • ⚠️ Rotate the YouTube OAuth refresh token in `lavalink/application.yml` line 17 — flagged by sec-infra-01 as still-committed

Changes

  • Modified: `Dockerfile`, `docker-compose.yml`, `docker-compose.prod.yml`, `docker/backup.sh`, `lavalink/application.yml`, `vite.config.ts`, `packages/config/src/index.ts`, `.env.example`, `.gitignore`, `.dockerignore`, `.gitleaks.toml`
  • New: `.github/workflows/security.yml`, `docker-compose.no-db-port.yml`, `secret-files.ts`, `secrets/.gitkeep`, `vite-config.test.ts`, 3 packages/config tests

Note on packages/config tests

`packages/config` does not yet have a vitest runner wired up, so the 3 new config test files are written but not executed as part of `pnpm test`. They will run once a follow-up adds `vitest` as a devDep and a `test` script to the package.

Test plan

  • `pnpm --filter @fluxcore/config build` — clean
  • `pnpm --filter @fluxcore/dashboard typecheck` — clean
  • `pnpm --filter @fluxcore/bot typecheck` — clean
  • `pnpm --filter @fluxcore/dashboard test` — 281 pass / 15 pre-existing baseline failures (no new regressions)
  • `pnpm --filter @fluxcore/bot test` — 325 pass / 16 pre-existing baseline failures (no new regressions)
  • New `security.yml` workflow passes on this PR
  • Manual: `docker compose -f docker-compose.yml -f docker-compose.no-db-port.yml up` — postgres not publicly exposed
  • Manual: prod deploy with missing secret files fails fast
  • Manual: `docker compose --profile tools up` fails fast without `PGADMIN_PASSWORD`

🤖 Generated with Claude Code

Implements 12 infrastructure hardening plans covering secrets,
containers, CI scanning, and dev environment defaults:

- sec-infra-01: remove hardcoded Lavalink 'youshallnotpass' default;
  fail-fast in production if LAVALINK_PASSWORD unset
- sec-infra-02: migrate production secrets from env_file to Docker
  secrets with *_FILE pattern; adds secret-files.ts resolver
- sec-infra-03: backup service uses .pgpass from Docker secret
  instead of PGPASSWORD env var; backup.sh is fail-closed
- sec-infra-04: Dockerfile dev/test stages now run as node user
- sec-infra-05: parameterize dev postgres password with ${...:-fluxcore}
- sec-infra-06: BOT_SYNC_SECRET production fail-fast (unset or <32)
- sec-infra-07: Vite dev server defaults to 127.0.0.1; opt-in 0.0.0.0
  via VITE_HOST env var
- sec-infra-08: add .github/workflows/security.yml (pnpm audit +
  gitleaks + Trivy for bot/dashboard/filesystem) and .gitleaks.toml
- sec-infra-09: blank LAVALINK_PASSWORD in .env.example + CI guard
  against reintroducing the hardcoded default
- sec-infra-10: parameterize pgAdmin credentials with fail-fast guard
- sec-infra-11: add docker-compose.no-db-port.yml override + CI guard
  against public postgres exposure
- sec-infra-12: broaden .dockerignore and .gitignore to .env.* glob;
  CI guard blocking tracked env files

New files: security.yml workflow, .gitleaks.toml, secret-files.ts,
docker-compose.no-db-port.yml, vite-config.test.ts, 3 config tests,
secrets/.gitkeep.

Typecheck clean. Dashboard 281 pass / 15 baseline failures (no new
regressions). Bot 325 pass / 16 baseline failures (no new regressions).
@Abdulkhalek-1

Copy link
Copy Markdown
Member Author

Superseded by #49, which integrates all 7 open PRs (#42#48) into main in one verified branch — conflicts resolved, typecheck 14/14, and 1053 tests green. This PR's changes are fully included there; it will be closed as merged once #49 lands.

@Abdulkhalek-1 Abdulkhalek-1 merged commit cb66472 into main Jul 8, 2026
1 of 7 checks passed
Abdulkhalek-1 added a commit that referenced this pull request Jul 8, 2026
- turbo.json: add LAVALINK_HOST/PORT/PASSWORD to globalPassThroughEnv so
  turbo's strict envMode stops stripping the now-required LAVALINK_PASSWORD
  (#46) from the bot/dashboard dev processes.
- docker-compose.yml: default PGADMIN_DEFAULT_PASSWORD to empty so
  `pnpm dev/stop` interpolate cleanly (Compose evaluates every service
  regardless of --profile); `--profile tools` still needs a real value.
- docker-compose.override.yml: local dev override (CI=true + matched
  LAVALINK dev secret) so the services boot without a populated .env.dev.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant