name: Security Checks # Same shape as lint.yaml: scoped on PR via path detection, runs everything # when called from another workflow (e.g. release). on: pull_request: workflow_call: # Read-only by default — every job here just scans the source tree and # reports findings. Override at the job level if a future job ever # needs to write back (it shouldn't). permissions: contents: read # Silence Dagger's Cloud upload and analytics paths globally. env: DAGGER_NO_NAG: "1" DAGGER_CLOUD_TOKEN: "" DO_NOT_TRACK: "1" # Every job here only checks out + scans; none push or need git write # access, so each checkout sets `persist-credentials: false` to keep the # GITHUB_TOKEN out of the workspace's .git/config (zizmor "artipacked"). jobs: changes: name: Detect changed paths if: github.event_name == 'pull_request' runs-on: ubuntu-latest outputs: go: ${{ steps.filter.outputs.go }} deps: ${{ steps.filter.outputs.deps }} chart: ${{ steps.filter.outputs.chart }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4 id: filter with: filters: | go: - '**/*.go' - 'go.mod' - 'go.sum' - 'dagger/**' deps: - 'go.mod' - 'go.sum' - 'dagger/**' chart: - 'chart/**' - 'dagger/**' # Secret leak detection. Always runs — any file can leak. Routed # through the Dagger Module's `Gitleaks` function (see CLAUDE.md for # why this isn't gitleaks-action). secrets: name: Secret leaks (Gitleaks) runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: # gitleaks scans the working tree, not git history — shallow. fetch-depth: 1 persist-credentials: false - uses: ./.github/actions/dagger with: args: gitleaks # Reachability-based vulnerability check for Go code. Routed through # the Dagger Module so the govulncheck version + flags stay aligned # with `task security:govulncheck` locally — single source of truth # in dagger/security.go (the `govulncheckPath` const in dagger/base.go). govulncheck: name: Reachable vulnerabilities (govulncheck) needs: changes if: | always() && (github.event_name != 'pull_request' || needs.changes.outputs.go == 'true') runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 1 persist-credentials: false - uses: ./.github/actions/dagger with: args: govulncheck # Filesystem scan: Go module deps + lockfiles. Catches CVEs that # govulncheck would miss because they don't lie on a reachable path. # Routed through the Dagger Module's `Trivy` function — same Trivy # version + same flags locally and in CI. vuln-deps: name: Vulnerable dependencies (Trivy) needs: changes if: | always() && (github.event_name != 'pull_request' || needs.changes.outputs.deps == 'true') runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - uses: ./.github/actions/dagger with: args: trivy --scan-type=fs # Helm/Kubernetes misconfig scan against the rendered chart. chart-misconfig: name: Chart misconfiguration (Trivy) needs: changes if: | always() && (github.event_name != 'pull_request' || needs.changes.outputs.chart == 'true') runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - uses: ./.github/actions/dagger with: args: trivy --scan-type=config --scan-ref=chart