How do you scan container images in a private registry with Trivy?
Quick Answer
Trivy scans private registry images by authenticating via Docker's credential helpers, environment variables (TRIVY_USERNAME and TRIVY_PASSWORD), or the docker login session. For cloud registries like ECR, GCR, and ACR, Trivy supports native credential providers and IAM-based authentication without storing static credentials.
Detailed Answer
Think of scanning a private registry image like accessing a members-only library. You cannot just walk in and start reading books. You need a membership card (credentials) that the librarian (registry) validates before granting access to the collection. Different libraries accept different types of identification: some want a username and password, others accept a digital membership token, and premium libraries like the ones run by AWS and Google let you use your government-issued ID (IAM role) for seamless entry without carrying a separate card.
Trivy supports scanning images from private container registries by leveraging the same credential mechanisms used by Docker and container runtimes. The simplest method is to run docker login against the registry before invoking Trivy. Docker login stores credentials in the ~/.docker/config.json file, and Trivy reads this file automatically when it needs to pull an image. This works for any registry that supports Docker's v2 API, including Harbor, Nexus, JFrog Artifactory, GitLab Container Registry, and GitHub Container Registry. For the payments-api stored in a private Harbor instance, running docker login harbor.internal.company.com followed by trivy image harbor.internal.company.com/payments/payments-api:v2.3.1 is all that is needed. Trivy uses the stored credentials to authenticate and pull the image layers for analysis.
For CI/CD pipelines where interactive docker login is not practical, Trivy supports environment variable authentication through TRIVY_USERNAME and TRIVY_PASSWORD. These variables are set in the pipeline's secret management system and consumed by Trivy at runtime without writing credentials to disk. This approach is preferred in Jenkins, GitLab CI, and GitHub Actions where secrets are injected as environment variables. Trivy also supports registry-specific credential files through the TRIVY_REGISTRY_TOKEN environment variable for token-based authentication and the --registry-token CLI flag. For organizations using Docker credential helpers like docker-credential-ecr-login for AWS ECR or docker-credential-gcr for Google GCR, Trivy integrates transparently because it reads the credHelpers configuration from Docker's config.json and delegates authentication to the appropriate helper binary.
Cloud-native registries provide the most seamless authentication experience. For AWS ECR, Trivy can use the AWS credential chain including instance profiles, environment variables, and shared credential files, meaning an EC2 instance or ECS task with the appropriate IAM role can scan ECR images without any explicit credential configuration. The order-processing-service team running their CI pipeline on an EC2 build agent simply needs the ecr:GetDownloadUrlForLayer, ecr:BatchGetImage, and ecr:GetAuthorizationToken IAM permissions attached to the instance profile. For Google GCR and Artifact Registry, Trivy uses Application Default Credentials, so a GKE workload or Cloud Build step with the appropriate service account can scan images natively. Azure ACR supports similar integration through managed identities and the az acr login command. These cloud-native patterns eliminate static credentials entirely, which is a significant security improvement over username and password pairs that can be leaked or rotated improperly.
A critical gotcha is scanning images that use manifest lists (multi-architecture images). When you push a manifest list to a registry, the single tag resolves to different image digests depending on the platform. By default, Trivy scans the image matching the host platform, which in a CI pipeline is typically linux/amd64. If your user-auth-service also runs on ARM nodes, vulnerabilities specific to the ARM image variant will not be detected unless you explicitly specify the platform with --platform linux/arm64. Another common issue is registry rate limiting. Docker Hub enforces pull rate limits for unauthenticated and free-tier users, and a CI pipeline scanning multiple images can exhaust the limit quickly. Always authenticate to Docker Hub even for public images to get higher rate limits, and consider using a pull-through cache registry like Harbor to avoid hitting Docker Hub directly. Finally, ensure that the Trivy process has network access to the registry from the CI runner. In environments with network policies or proxy servers, configure the HTTPS_PROXY environment variable and ensure the registry's TLS certificate is trusted by the system's certificate store.