Skip to content

🤖 ci: add code and image security scanning#88

Open
ThomasK33 wants to merge 2 commits intomainfrom
security-97r8
Open

🤖 ci: add code and image security scanning#88
ThomasK33 wants to merge 2 commits intomainfrom
security-97r8

Conversation

@ThomasK33
Copy link
Member

@ThomasK33 ThomasK33 commented Feb 14, 2026

Summary

Add repository and container security scanning by integrating CodeQL and Trivy into CI/release workflows.

Background

The repository already ran linting and vulnerability checks (gosec, govulncheck, Terraform Trivy config scan), but it did not yet provide first-class GitHub code scanning results or OCI image vulnerability scanning for publish/release paths.

Implementation

  • Added a new CodeQL workflow for Go code scanning on PRs, pushes to main, and a weekly schedule.
  • Added a Trivy filesystem scan job in CI for repository-level scanning.
  • Added a Trivy image scan job in CI that builds/scans the local Docker image.
  • Updated publish-main gating to include filesystem and image scanning jobs.
  • Added a post-publish Trivy scan for ghcr.io/coder/coder-k8s:main.
  • Added a release-workflow Trivy scan for ghcr.io/coder/coder-k8s:${{ github.event.release.tag_name }}.
  • Enabled GoReleaser image SBOM generation.

Validation

  • go tool actionlint
  • make build
  • make test
  • make lint
  • make verify-vendor

Risks

  • New Trivy gating can fail CI on newly disclosed HIGH/CRITICAL CVEs in base/runtime dependencies.
  • Additional scan jobs increase CI duration.

📋 Implementation Plan

Plan: Add code scanning + OCI image scanning

Context / Why

You want to add (1) code scanning and (2) OCI container image scanning to the coder-k8s repository, ideally as part of GitHub Actions CI/CD.

This repo already has good baseline security checks (gosec via golangci-lint, govulncheck, Trivy config scan for Terraform, zizmor for Actions). The main missing pieces are:

  • Image vulnerability scanning for the built/published ghcr.io/coder/coder-k8s images.
  • First-class “code scanning” results surfaced in GitHub’s Security UI (SARIF) rather than only console output.

Evidence (what we verified)

From repo inspection (Explore task):

  • .github/workflows/ci.yaml already runs:
    • golangci-lint with gosec enabled
    • govulncheck ./...
    • Trivy config scan for terraform/ (using aquasecurity/trivy-action@b6643a29...)
    • zizmor for workflow security
  • .github/workflows/release.yaml uses GoReleaser to publish artifacts/images.
  • .goreleaser.yaml builds and pushes ghcr.io/coder/coder-k8s and has dockers_v2.*.sbom: false.
  • Dockerfile.goreleaser is distroless/static:nonroot and copies in the built binary.

These files are sufficient to plan concrete changes to CI/CD for code + image scanning.

Implementation details (proposed changes)

1) Add GitHub CodeQL workflow (Go code scanning)

Goal: Add “code scanning” in the GitHub-native sense (SAST + Security tab integration).

Create: .github/workflows/codeql.yaml (new)

  • Triggers:
    • pull_request (default branches)
    • push to main
    • schedule weekly (optional but recommended)
  • Permissions:
    • security-events: write
    • contents: read
    • actions: read
  • Steps:
    • actions/checkout (SHA-pinned, match repo style)
    • github/codeql-action/init (Go)
    • Build step (either github/codeql-action/autobuild or explicit go build ./... with GOFLAGS=-mod=vendor)
    • github/codeql-action/analyze

Shape:

name: CodeQL
on:
  push:
    branches: [main]
  pull_request:
  schedule:
    - cron: '0 6 * * 1'
permissions:
  contents: read
  security-events: write
  actions: read
jobs:
  analyze:
    runs-on: depot-ubuntu-24.04-8
    steps:
      - uses: actions/checkout@<sha>
        with:
          persist-credentials: false
      - uses: github/codeql-action/init@<sha>
        with:
          languages: go
      - name: Build
        env:
          GOFLAGS: -mod=vendor
        run: go build ./...
      - uses: github/codeql-action/analyze@<sha>

Notes:

  • Keep all Actions SHA-pinned (this repo already pins).
  • If you expect external fork PRs, we should confirm CodeQL upload permissions behavior; otherwise this is fine.

2) Add Trivy filesystem scan (repo/code + secrets + config)

Goal: Complement CodeQL with quick repo scanning for known vulnerable dependencies, leaked secrets patterns, and misconfigurations.

Update: .github/workflows/ci.yaml

  • Add a new job (or add steps to existing lint job) using the already-pinned Trivy action.
  • Use scan-type: fs and scan the repo root.
  • Exclude vendor/ (since deps are scanned via govulncheck, and vendor/ can create noise/slowdowns).
  • Gate on HIGH,CRITICAL initially.

Shape:

- name: Trivy filesystem scan
  uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
  with:
    scan-type: fs
    scan-ref: .
    severity: HIGH,CRITICAL
    exit-code: '1'
    skip-dirs: vendor

Optional (recommended if you want results in the GitHub Security UI):

  • Output SARIF and upload it:
    • Trivy: format: sarif, output: trivy-fs.sarif
    • Upload: github/codeql-action/upload-sarif (SHA-pinned)

3) Add Trivy OCI image vulnerability scanning

Goal: Scan the built container image for vulnerabilities as part of CI/CD.

There are two places to do this:

3a) CI (pre-merge) image scan job

Update: .github/workflows/ci.yaml

  • Add image-scan job gated on the existing changes.outputs.publish == 'true' filter.
  • Build a local image (linux/amd64 is enough to start) with Dockerfile.goreleaser.
  • Run Trivy scan-type: image against the local image tag.

Shape:

image-scan:
  needs: changes
  if: github.event_name == 'merge_group' || needs.changes.outputs.publish == 'true'
  runs-on: depot-ubuntu-24.04-8
  steps:
    - uses: actions/checkout@<sha>
      with:
        persist-credentials: false
    - name: Build linux/amd64 binary
      env:
        GOFLAGS: -mod=vendor
        CGO_ENABLED: '0'
        GOOS: linux
        GOARCH: amd64
      run: |
        mkdir -p linux/amd64
        go build -o linux/amd64/coder-k8s ./
    - name: Build image (local)
      run: docker build -f Dockerfile.goreleaser -t coder-k8s:scan .
    - name: Trivy image scan
      uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
      with:
        scan-type: image
        image-ref: coder-k8s:scan
        severity: HIGH,CRITICAL
        exit-code: '1'

Optional: SARIF output + upload-sarif (same as filesystem scan).

3b) Post-publish verification scan (main + releases)

Update:

  • .github/workflows/ci.yaml publish-main job: add a Trivy image scan step for ghcr.io/coder/coder-k8s:main.
  • .github/workflows/release.yaml: add a Trivy image scan step for the release tag ghcr.io/coder/coder-k8s:${{ github.event.release.tag_name }}.

This ensures the image that actually gets published is scanned even if a pre-merge job is skipped.

4) Enable SBOM generation for releases (optional but strongly recommended)

Goal: Improve supply-chain posture and make scanning/auditing easier.

Update: .goreleaser.yaml

  • Turn on SBOM generation for the container image and/or release archives.

Proposed change:

  • In dockers_v2 entry, set sbom: true (instead of false) if supported by your GoReleaser version.
  • Optionally also add a top-level sboms: section to generate SBOMs for release artifacts.

5) Add ignore/config files for managing findings

Goal: Keep signal-to-noise high as scans are introduced.

Add (as needed):

  • Repo root .trivyignore for image/fs scans (keep Terraform-specific ignore in terraform/.trivyignore as-is).
  • (Optional) .trivy.yaml to centralize excludes and scanner settings.

6) Validation plan (what to run before merging)

After implementing in Exec mode:

  • go tool actionlint (or your existing workflow job) to validate workflow YAML.
  • Ensure CI passes for:
    • make test
    • make build
    • make lint
  • Smoke-test Trivy steps locally if desired (build image + run trivy).
Rationale / trade-offs
  • CodeQL provides “code scanning” in the GitHub ecosystem and catches classes of issues gosec won’t.
  • Trivy fs scan is fast and broad (secrets/config/vuln), but can be noisy; excluding vendor/ and using .trivyignore helps.
  • Image scanning on PRs requires building the image; the image is small (distroless + static binary), so runtime impact should be acceptable.
  • Post-publish scans are a safety net; pre-merge scans provide real gating.

Generated with mux • Model: openai:gpt-5.3-codex • Thinking: xhigh • Cost: $0.34

Add CodeQL code scanning and Trivy filesystem/image scanning across CI and release workflows.

Also gate publish-main on security scan jobs and enable GoReleaser image SBOM generation.

---

_Generated with `mux` • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh` • Cost: $0.34_

<!-- mux-attribution: model=openai:gpt-5.3-codex thinking=xhigh costs=0.34 -->
@ThomasK33
Copy link
Member Author

@codex review

Please review this PR for the new CodeQL + Trivy scanning workflows and publish/release image scanning integration.

@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1064447553

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Pin Go setup in CodeQL workflow and compute release image tag without a leading `v` before Trivy scanning.

---

_Generated with `mux` • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh` • Cost: $0.34_

<!-- mux-attribution: model=openai:gpt-5.3-codex thinking=xhigh costs=0.34 -->
@ThomasK33
Copy link
Member Author

@codex review

Addressed the two workflow comments:

  • release image scan now strips a leading v before scanning the GoReleaser version tag
  • CodeQL workflow now pins the Go toolchain via actions/setup-go

Please take another look.

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Keep it up!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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