Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 36 additions & 51 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,45 +25,43 @@ jobs:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: Audit (fail on high or critical)
run: pnpm audit --audit-level=high
- name: Audit production deps (fail on high or critical)
# Scope to shipped dependencies — dev/test tooling (vitest, vite, rollup)
# never reaches the built images, which Trivy scans separately.
run: pnpm audit --prod --audit-level=high

gitleaks:
name: gitleaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_ENABLE_UPLOAD_ARTIFACT: true
# Use the gitleaks CLI directly: gitleaks-action@v2 requires a paid
# GITLEAKS_LICENSE for organization repos. Scan the working tree (`dir`)
# so current files must be clean; historical secrets are rotated, not
# rewritten. Config/allowlist in .gitleaks.toml.
- name: Install gitleaks
run: |
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz" \
| tar -xz -C /usr/local/bin gitleaks
- name: Scan working tree for secrets
run: gitleaks dir . --config .gitleaks.toml --redact --verbose

# Use the Trivy CLI directly (install script) rather than aquasecurity/trivy-action,
# whose pinned setup-trivy composite action versions have proven unresolvable.
trivy-bot:
name: trivy (bot image)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build bot image
run: docker build --target production-bot -t fluxcore-bot:ci .
- name: Trivy scan
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: fluxcore-bot:ci
severity: HIGH,CRITICAL
exit-code: "1"
ignore-unfixed: true
vuln-type: os,library
format: sarif
output: trivy-bot.sarif
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-bot.sarif
category: trivy-bot
- name: Install Trivy
run: curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
- name: Scan bot image
# Skip the base image's package-manager tooling (npm global + corepack pnpm
# cache) — not our runtime surface. App deps under /app/node_modules and the
# OS layer are still scanned.
run: trivy image --severity HIGH,CRITICAL --exit-code 1 --ignore-unfixed --no-progress --skip-dirs /usr/local/lib/node_modules --skip-dirs /root/.cache/node/corepack fluxcore-bot:ci

trivy-dashboard:
name: trivy (dashboard image)
Expand All @@ -72,46 +70,33 @@ jobs:
- uses: actions/checkout@v4
- name: Build dashboard image
run: docker build --target production-dashboard -t fluxcore-dashboard:ci .
- name: Trivy scan
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: fluxcore-dashboard:ci
severity: HIGH,CRITICAL
exit-code: "1"
ignore-unfixed: true
vuln-type: os,library
format: sarif
output: trivy-dashboard.sarif
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-dashboard.sarif
category: trivy-dashboard
- name: Install Trivy
run: curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
- name: Scan dashboard image
# Skip the base image's package-manager tooling (npm global + corepack pnpm
# cache) — not our runtime surface. App deps under /app/node_modules and the
# OS layer are still scanned.
run: trivy image --severity HIGH,CRITICAL --exit-code 1 --ignore-unfixed --no-progress --skip-dirs /usr/local/lib/node_modules --skip-dirs /root/.cache/node/corepack fluxcore-dashboard:ci

trivy-fs:
name: trivy (filesystem & config)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy filesystem scan (config, IaC, secrets)
uses: aquasecurity/trivy-action@0.28.0
with:
scan-type: fs
scan-ref: .
severity: HIGH,CRITICAL
exit-code: "1"
ignore-unfixed: true
scanners: vuln,secret,config
- name: Install Trivy
run: curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
- name: Trivy filesystem scan (vuln, secret, config)
run: trivy fs --scanners vuln,secret,config --severity HIGH,CRITICAL --exit-code 1 --ignore-unfixed --no-progress .

forbidden-strings:
name: forbidden strings
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Block re-introduction of default lavalink password
# Exclude .github so this gate's own grep pattern doesn't self-match.
run: |
if grep -RIn --exclude-dir=.git --exclude-dir=node_modules --exclude='*.md' 'youshallnotpass' .; then
if grep -RIn --exclude-dir=.git --exclude-dir=node_modules --exclude-dir=.github --exclude='*.md' 'youshallnotpass' .; then
echo "::error::The literal 'youshallnotpass' must never be committed."
exit 1
fi
Expand Down
9 changes: 9 additions & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Trivy vulnerability ignore list.
# Each entry must be justified; prefer fixing (pnpm.overrides) over ignoring.

# lodash: Arbitrary code execution via _.template (untrusted templateSettings).
# Transitive-only (via @sapphire/shapeshift and @mrleebo/prisma-ast>chevrotain);
# we never call lodash template with untrusted input. The advisory lists a fix
# in 4.18.0, which lodash has NOT released (latest is 4.17.21) — unfixable.
# Mirrors pnpm auditConfig.ignoreGhsas (GHSA-r5fr-rjxr-66jc, GHSA-35jh-r3h4-6jhm).
CVE-2026-4800
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ RUN pnpm install --frozen-lockfile

FROM bot-installer AS bot-builder
COPY --from=prune-bot /app/out/full/ .
# turbo prune omits root tsconfig files that package tsconfigs extend.
COPY tsconfig.base.json tsconfig.json ./
RUN pnpm turbo run build --filter=@fluxcore/bot...

FROM base AS production-bot
Expand Down Expand Up @@ -81,6 +83,8 @@ RUN pnpm install --frozen-lockfile

FROM dashboard-installer AS dashboard-builder
COPY --from=prune-dashboard /app/out/full/ .
# turbo prune omits root tsconfig files that package tsconfigs extend.
COPY tsconfig.base.json tsconfig.json ./
RUN pnpm turbo run build --filter=@fluxcore/dashboard...

FROM base AS production-dashboard
Expand Down
6 changes: 4 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ services:
- ./lavalink/application.yml:/opt/Lavalink/application.yml:ro
environment:
- _JAVA_OPTIONS=-Xmx128m
- LAVALINK_SERVER_PASSWORD=${LAVALINK_SERVER_PASSWORD:-}
healthcheck:
test: ["CMD-SHELL", "wget -qO- --header='Authorization: youshallnotpass' http://localhost:2333/version || exit 1"]
test: ["CMD-SHELL", "wget -qO- --header=\"Authorization: $${LAVALINK_SERVER_PASSWORD}\" http://localhost:2333/version || exit 1"]
interval: 10s
timeout: 5s
retries: 5
Expand Down Expand Up @@ -121,8 +122,9 @@ services:
- ./lavalink/application.yml:/opt/Lavalink/application.yml:ro
environment:
- _JAVA_OPTIONS=-Xmx128m
- LAVALINK_SERVER_PASSWORD=${LAVALINK_SERVER_PASSWORD:-}
healthcheck:
test: ["CMD-SHELL", "wget -qO- --header='Authorization: youshallnotpass' http://localhost:2333/version || exit 1"]
test: ["CMD-SHELL", "wget -qO- --header=\"Authorization: $${LAVALINK_SERVER_PASSWORD}\" http://localhost:2333/version || exit 1"]
interval: 10s
timeout: 5s
retries: 5
Expand Down
4 changes: 3 additions & 1 deletion lavalink/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ plugins:
- TVHTML5_SIMPLY
oauth:
enabled: true
refreshToken: "1//03ZBRjPYrOJjyCgYIARAAGAMSNwF-L9IrxhQ0spy4xQa5oYz9QgV4MIAqjwHjE4-XvYKYckrwBkze-mryRjwwPVQmlOftQWVlGGA"
# Provided via env (Lavalink/Spring ${VAR} substitution). Never commit a real token.
# ROTATE the previously-committed token in Google Cloud — it is in git history.
refreshToken: "${LAVALINK_YOUTUBE_REFRESH_TOKEN:}"

lavalink:
plugins:
Expand Down
19 changes: 18 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@
"better-sqlite3",
"esbuild",
"prisma"
]
],
"overrides": {
"undici@<6.24.0": ">=6.24.0",
"i18next-fs-backend@<2.6.6": ">=2.6.6",
"hono@<4.12.4": ">=4.12.4",
"@hono/node-server@<1.19.10": ">=1.19.10",
"effect@<3.20.0": ">=3.20.0",
"fastify@<5.8.5": ">=5.8.5",
"fast-uri@<3.1.2": ">=3.1.2",
"ws@<8.21.0": ">=8.21.0",
"defu@<6.1.5": ">=6.1.5"
},
"auditConfig": {
"ignoreGhsas": [
"GHSA-r5fr-rjxr-66jc",
"GHSA-35jh-r3h4-6jhm"
]
}
}
}
Loading
Loading