The most surprising thing about Trivy scanning images in Harbor at push time is that it doesn’t actually scan at push time.
Harbor acts as a proxy for your container registry. When you push an image to Harbor, Harbor first stores that image locally. Only after the image is fully uploaded and stored within Harbor’s own storage does Harbor trigger Trivy to scan it. This means the scan is an asynchronous post-ingestion event, not a synchronous gate during the docker push operation itself.
Let’s see this in action. Imagine you have a simple Dockerfile:
FROM alpine:latest
RUN apk add --no-cache nginx
CMD ["nginx", "-g", "daemon off;"]
You build and tag it:
docker build -t my-registry.example.com/my-project/nginx:v1.0 .
Then you push it to Harbor:
docker push my-registry.example.com/my-project/nginx:v1.0
At this point, the docker push command will complete successfully. You won’t see any immediate Trivy output.
Now, if you go to your Harbor UI, navigate to your project, and select the nginx repository, you’ll see the v1.0 tag. Under the "Vulnerabilities" column, it will likely show "Scanning…" or a similar status. After a short while, this will update to show the scan results – the number of critical, high, medium, and low vulnerabilities found.
This asynchronous nature is key to understanding the integration. Harbor is designed to maintain the integrity of the push operation itself, ensuring that your CI/CD pipeline doesn’t hang indefinitely waiting for a potentially long-running scan. Instead, it decouples the image delivery from the security analysis.
Internally, Harbor uses a background worker process. When an image is successfully stored, a message is placed on a queue. A dedicated Trivy scanner worker picks up this message, retrieves the image from Harbor’s local storage, performs the scan, and then reports the results back to Harbor’s database. This database then updates the UI and can be used by Harbor’s policies to enforce security rules (e.g., blocking pulls of images with critical vulnerabilities).
The core levers you control are within Harbor’s configuration. You enable the Trivy scanner under "Administration" -> "System Settings" -> "Scanner". Here, you select "Trivy" as the adapter. Crucially, you also configure the "Scan On Push" setting. When this is enabled, Harbor automatically initiates the scanning process for newly pushed images. You can also configure which vulnerability databases Trivy should use (e.g., NVD, Red Hat, Debian) and set thresholds for policy enforcement.
The one thing most people don’t realize is how deeply integrated Trivy becomes within Harbor’s architecture. It’s not just a simple API call; Harbor manages the entire lifecycle of the scan, including fetching the image layers, running Trivy in a containerized environment (often managed by Harbor itself), and ingesting the JSON output into its own vulnerability database. This allows for fine-grained control over what gets scanned and how those results are used to protect your registry.
The next step in understanding Harbor’s security features is exploring how to configure and enforce vulnerability policies based on these scan results.