Harbor Registry with Trivy Vulnerability Scanning - 夜莺博客

Harbor Registry with Trivy Vulnerability Scanning

A private registry without image scanning is a distribution point for known CVEs. Harbor ships with a pluggable interrogation service, and since 2.2 the default scanner is the Harbor Scanner Adapter for Trivy — the same vulnerability database used by the standalone trivy CLI, exposed through Harbor's own API. This guide covers a working deployment, the project-level scan policies that actually prevent bad images reaching a cluster, and the API calls you need for automation.

Deploy Harbor with Trivy Enabled

helm repo add harbor https://helm.goharbor.io
helm repo update
helm install harbor harbor/harbor   --create-namespace   --namespace harbor   --set trivy.enabled=true   --set trivy.skipUpdate=false   --set persistence.enabled=true

kubectl -n harbor get pods
kubectl -n harbor get svc harbor-trivy

The chart registers the adapter automatically under Administration → Interrogation Services → Scanners and marks it as default. If you are running the docker-compose deployment, the Trivy adapter container is part of the standard bundle; verify with docker ps | grep trivy and confirm its URL (http://trivy-adapter:8080) matches the scanner entry.

Scanner Settings Worth Understanding

  • SCANNER_TRIVY_SEVERITY — comma-separated severities to report; the default UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL keeps noise visible in the UI.
  • SCANNER_TRIVY_IGNORE_UNFIXED — set to true to hide vulnerabilities with no upstream fix; invaluable when a base image is pinned.
  • SCANNER_TRIVY_INSECURE — skips registry certificate verification, needed only for a self-signed private registry.
  • SCANNER_TRIVY_TIMEOUT — default 5 minutes; large images in a slow network need it raised, otherwise scans fail as "timed out".
  • SCANNER_TRIVY_SKIP_UPDATE — leave false unless you run an air-gapped deployment with a mirrored Trivy DB, or you will scan against a stale database.

Project Policy: Scan on Push and Block on Severity

Per project, enable Automatically scan images on push and optionally Prevent vulnerable images from running. The second setting is what turns scanning into enforcement: the registry tags the artifact with a vulnerability state, and the cluster's admission controller (or a policy engine) refuses to deploy anything above your severity threshold. A common production policy is to block CRITICAL only, warn on HIGH, and enable automatic rescan so a newly published CVE is detected on images that passed weeks ago.

Automate with the Harbor API

# list configured scanners
curl -s -u "admin:$HARBOR_PW" https://registry.example.com/api/v2.0/scanners | jq

# set the project scanner
curl -s -X PUT "https://registry.example.com/api/v2.0/projects/42/scanner"   -u "admin:$HARBOR_PW" -H "Content-Type: application/json"   -d '{"uuid":""}'

# trigger a scan for one artifact
curl -s -X POST   "https://registry.example.com/api/v2.0/projects/app/repositories/backend/artifacts/sha256:abc123.../scan"   -u "admin:$HARBOR_PW" -H "Content-Type: application/json"   -d '{"scan_type":"vulnerability"}'

# read the report
curl -s -u "admin:$HARBOR_PW"   "https://registry.example.com/api/v2.0/projects/app/repositories/backend/artifacts/sha256:abc123.../additions/vulnerabilities"   | jq '.critical_cnt, .high_cnt'

Wrap the last call in CI: fail the pipeline when .critical_cnt > 0 so developers see the problem before the image is ever promoted to production registries.

Operating Notes from Real Deployments

  • Database freshness: Trivy DB updates are rate-limited by GitHub for unauthenticated downloads; configure a token (SCANNER_TRIVY_GITHUB_TOKEN) if you scan hundreds of images daily.
  • Storage: scan reports are small, but rescanning every tag on every DB update is not free. Prefer rescanning only tags referenced by a running workload.
  • Base image choice dominates results: switching from a full Debian image to distroless or Alpine typically removes most OS-level findings, which is a better long-term fix than allow-listing CVEs.
  • Exemptions need an owner and an expiry: a CVE allow-list entry with no review date becomes permanent by accident.

Related reading: Kubernetes Ingress TLS with cert-manager and Idempotent Ansible configuration for IOS XR.

原文链接:https://github.com/aquasecurity/harbor-scanner-trivy