Skip to content

ci(security): add Trivy image scanning, OSSF Scorecard, and CodeQL security-extended #578

Description

@thewrz

This was written agentically; verify its assertions and edit accordingly:

Why

An audit of GitHub's code-scanning workflow catalog against WrzDJ's existing CI found that most offerings are redundant (we already run bandit, pip-audit, npm audit --audit-level=high ×3, ruff, ESLint, tsc, and CodeQL) or wrong-language/commercial. Three real gaps remain, and all three are closed by free, no-account, Apache-2.0-or-builtin tooling. Because every wrzonance repo is public, GitHub code scanning and Actions minutes are free and unmetered — there is no licensing cost to any of this.

Gap 1 — published container images are never scanned

docker-publish.yml pushes ghcr.io/wrzonance/wrzdj-api and wrzdj-web on every main/tag push. pip-audit and npm audit cover our dependencies; nothing in the pipeline sees the OS layer. A critical CVE in python:3.11-slim's Debian packages or node:26-alpine's apk set would ship to GHCR undetected.

Related: server/Dockerfile:1 and dashboard/Dockerfile:1 use floating tags, while bridge/Dockerfile:6 is correctly digest-pinned. SECURITY.md and the global dependency rules both require digest-pinned base images — two of three violate it.

Gap 2 — no regression gate on our own supply-chain posture

Every action in this repo is SHA-pinned and permissions: blocks are minimal. Nothing enforces that. The first uses: foo/bar@v3 an agent adds would pass CI silently.

Gap 3 — CodeQL is running the default query suite

.github/codeql/codeql-config.yml sets only paths-ignore; there is no queries: key, so we get the default pack rather than security-extended. This is capability we already pay nothing for and simply have not switched on.

What

Three additive changes, no new vendor and no new account:

  1. CodeQL security-extended — add a queries: key to .github/codeql/codeql-config.yml. Widens the taint-source/sink coverage of a scanner already wired into PR and weekly runs. Expect a one-time batch of lower-precision findings to triage.
  2. Trivy (Aqua, Apache-2.0) — scan both built images, upload SARIF to the Security tab. Runs fully in-runner; no API key. Start non-blocking, promote to a hard gate once the baseline is clean.
  3. OSSF Scorecard (OpenSSF, Apache-2.0) — weekly, SARIF to the Security tab. Catches unpinned actions, over-broad permissions:, and branch-protection drift.

Also in scope: digest-pin server/Dockerfile and dashboard/Dockerfile base images, matching bridge/Dockerfile.

Out of scope

  • Semgrep — overlaps security-extended heavily and is the noisiest option. Revisit only if a gap is felt after this lands.
  • 42Crunch API audit — plausible fit given server/openapi.json, but it is freemium and account-gated. Separate issue if wanted.
  • Every commercial scanner in the catalog (Snyk, Fortify, Checkmarx, Veracode, Black Duck, Sonar, …).

Explicitly not solved by this

None of these tools detect authorization-logic defects. The known IDOR class (a route accepting an attacker-supplied FK and authorizing on the wrong object) has no taint flow, no CVE, and no bad pattern to match — it is invisible to all three additions. That class needs adversarial review and authz integration tests; this issue must not be read as covering it.

Already done (no code change needed)

Free repo toggles flipped ahead of this issue: Dependabot security updates, secret-scanning validity checks, non-provider patterns, and AI detection are now all enabled.

Testing

  • zizmor clean on the new/changed workflow files
  • Trivy job runs on a PR and uploads SARIF; findings visible in the Security tab
  • Scorecard job completes and reports no unpinned actions
  • CodeQL security-extended run completes; new findings triaged (fixed or dismissed with reason)
  • Both Dockerfiles digest-pinned; ci.yml Docker Build Smoke Test still green
  • CI green

🤖 Co-authored by Claude Opus 5.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status
    Ready

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions