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
9 changes: 4 additions & 5 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ Comprehensive CI pipeline that runs on:
- Builds for `linux/amd64` and `linux/arm64`
- Pushes to Harbor registry
- Tags with version and `latest`
- Runs Trivy security scan on image
- Uploads Trivy results to GitHub Security
- Triggers the informational Grype vulnerability scan on the pushed image (SARIF-only, does not gate the pipeline)

6. **CI Success** - Overall status check
- Aggregates results from all jobs
Expand All @@ -49,7 +48,7 @@ Comprehensive CI pipeline that runs on:

- **Dependency Caching**: Go modules and build cache are cached automatically
- **Code Coverage**: Generated and uploaded to Codecov
- **Security Scanning**: gosec (code) and Trivy (container images)
- **Security Scanning**: gosec (code) and Grype (container images, informational)
- **Multi-platform Builds**: Docker images for amd64 and arm64
- **Build Metadata**: Version, commit SHA, and build time injected into binaries

Expand Down Expand Up @@ -102,8 +101,8 @@ git push origin v1.0.0
This triggers:
- Full CI pipeline
- Docker multi-platform build
- Push to Harbor registry
- Trivy security scan
- Push to Docker Hub registry
- Informational Grype security scan (non-blocking)

## Local Testing

Expand Down
42 changes: 34 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ jobs:
permissions:
security-events: write
contents: read
outputs:
tag: ${{ steps.tag.outputs.TAG }}
steps:
- name: Checkout code
uses: actions/checkout@v5
Expand Down Expand Up @@ -265,17 +267,41 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run Trivy security scan on image
uses: aquasecurity/trivy-action@v0.35.0
# Grype vulnerability scan - INFORMATIONAL (SARIF/report only, no build gate).
# Replaces the former Trivy scan. Uses anchore/scan-action (grype engine) IN-LINE
# rather than the org reusable grype-scan.yml for two reasons:
# 1. ci.yml is pull_request-triggered, and a private-repo reusable `uses:` fails to
# resolve at workflow-LOAD time on pull_request events, which fails the ENTIRE run
# at startup (0 jobs). A job-level `if:` does not help (resolution precedes `if`).
# 2. node-doctor publishes images to Docker Hub (docker.io/supporttools), not Harbor,
# so the reusable workflow's keyless Harbor pull is the wrong mechanism anyway.
# anchore/scan-action uses the public grype vuln DB (not the org's self-hosted air-gapped
# mirror) — acceptable here since the scanned image is public on Docker Hub.
# Runs only on tag builds, matching the `docker` job that produces the image.
grype-scan:
name: Grype Scan (informational)
runs-on: ubuntu-latest
needs: [docker]
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: read
security-events: write
steps:
- name: Grype scan (anchore/scan-action)
id: grype
uses: anchore/scan-action@v6
with:
image-ref: ${{ env.REGISTRY }}/node-doctor:${{ steps.tag.outputs.TAG }}
format: 'sarif'
output: 'trivy-results.sarif'

- name: Upload Trivy results to GitHub Security
image: docker.io/supporttools/node-doctor:${{ needs.docker.outputs.tag }}
fail-build: false
severity-cutoff: high
output-format: sarif
- name: Upload SARIF to GitHub Security
if: always()
continue-on-error: true
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: trivy-results.sarif
sarif_file: ${{ steps.grype.outputs.sarif }}
category: grype

# Summary job - provides overall status
ci-success:
Expand Down
15 changes: 15 additions & 0 deletions .grype.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# .grype.yaml — Grype config + vulnerability suppressions for node-doctor.
#
# Read by the org-wide reusable Grype scan workflow
# (SupportTools/ci-runners/.github/workflows/grype-scan.yml), wired here as an
# INFORMATIONAL scan (blocking: false) that replaces the former Trivy scan.
#
# FORMAT — each suppression MUST document why it is acceptable + an expected fix:
# ignore:
# - vulnerability: CVE-2024-99999 # false positive in musl; fixed alpine 3.21; resolve 2025-04-01
#
# REVIEW POLICY: review monthly; suppressions are temporary; remove once the base
# image carries the upstream fix. Permanent suppressions need explicit approval.
#
# Currently no vulnerabilities are suppressed.
ignore: []
Loading