The rise of containerisation technologies like Docker and Kubernetes has transformed software development and deployment. Containers offer portability, scalability, and rapid deployment. However, they also introduce security risks if vulnerabilities within container images go undetected. Integrating container image scanning into the build process is a critical DevSecOps practice to prevent deploying vulnerable workloads to production.
In this blog, we will explore why container image scanning is essential, the best practices for integrating it effectively into build pipelines, tools and examples, and how public cloud users and individual developers can implement this approach for secure software delivery.
Why is Container Image Scanning Critical?
Container images are often built using base images pulled from public registries like Docker Hub. These base images may contain outdated libraries, known vulnerabilities, or misconfigurations that attackers can exploit once the container is deployed.
For example:
-
A developer pulls an outdated Ubuntu image containing an old version of
OpenSSLvulnerable to CVE-2014-0160 (Heartbleed). -
An application image includes unnecessary tools like
curlorwget, expanding its attack surface. -
Images include secrets or SSH keys that get exposed publicly.
Container image scanning identifies such vulnerabilities, outdated dependencies, malware, and policy violations before deployment, reducing security incidents in production environments.
Best Practices for Integrating Image Scanning into the Build Process
1. Adopt a “Shift Left” Approach
Scanning container images should not be an afterthought post-deployment. Integrate scanning as early as possible in the Continuous Integration (CI) pipeline to catch issues before images are pushed to registries.
Example:
During code commits, trigger image builds and scans within Jenkins, GitLab CI, or GitHub Actions workflows. If critical vulnerabilities are found, fail the pipeline to prevent vulnerable images from progressing to later stages.
2. Use Trusted Base Images
Start secure by design. Always:
-
Use minimal, well-maintained base images (e.g. Alpine, Distroless) to reduce attack surface.
-
Prefer images from official repositories with security commitments.
-
Regularly update base images and rebuild dependent application images to inherit security patches.
Example:
Google’s Distroless images contain only application binaries and runtime dependencies, eliminating shells and package managers, making them ideal for production security.
3. Integrate Automated Scanning Tools into CI/CD Pipelines
Select security scanning tools that seamlessly integrate with your build pipelines. Popular tools include:
-
Trivy: Open-source scanner for vulnerabilities and misconfigurations.
-
Anchore Engine: Policy-based image scanning.
-
Aqua Trivy or Aqua Enterprise: Advanced scanning with runtime protection.
-
Clair: Static analysis of vulnerabilities in Docker and OCI images.
-
Snyk Container: Developer-friendly scanning with remediation suggestions.
-
Twistlock (Palo Alto Prisma Cloud): Enterprise-grade scanning integrated into CI/CD and registries.
Example:
A GitLab pipeline using Trivy:
This ensures images are scanned on each build, and the pipeline fails if vulnerabilities exceed defined thresholds.
4. Define and Enforce Vulnerability Policies
Not all vulnerabilities are equally severe. Define policies such as:
-
Block builds with Critical or High vulnerabilities.
-
Allow Medium vulnerabilities only if no fix is available and with risk approval.
-
Document and track exceptions for known issues with compensating controls.
Example:
Using Aqua or Anchore policies, you can enforce rules to block images containing CVSS scores above a threshold, ensuring consistent security posture across teams.
5. Perform Multi-Stage Scanning
Scan at multiple stages:
-
Source Code Analysis: Scan code dependencies using SCA tools like Snyk or OWASP Dependency-Check before building images.
-
Build-time Scanning: Scan built images in CI pipelines before pushing to registries.
-
Registry Scanning: Continuously scan images stored in container registries to detect newly disclosed vulnerabilities.
-
Runtime Scanning: Monitor running containers for newly published CVEs that affect deployed images.
This multi-layered approach ensures no stage becomes a blind spot.
6. Remove Secrets and Unnecessary Packages
Secrets, API keys, and SSH keys should never be baked into images. Use secrets managers like HashiCorp Vault, AWS Secrets Manager, or Kubernetes Secrets instead. Also:
-
Remove package managers (e.g.
apt,apk) from final images to prevent installation of unauthorized tools in production. -
Use multi-stage builds to compile in one stage and copy only required binaries to the final image.
Example:
A Go application built using multi-stage Dockerfile:
This results in a minimal final image with reduced attack surface and no build tools.
7. Incorporate Container Signing and Provenance Verification
After scanning and building, sign container images using tools like cosign or Docker Content Trust to ensure integrity and authenticity.
Example:
Sign an image using cosign:
Verify signature before deployment:
This prevents tampering between build and production.
8. Monitor and Update Continuously
New vulnerabilities are discovered daily. Scanning should be continuous, not one-time.
-
Enable registry scanning for images stored in AWS ECR, GCR, or Docker Hub.
-
Schedule periodic re-scans of all images.
-
Automate rebuilds when base images are updated to incorporate security patches.
9. Educate Developers on Secure Container Practices
Security is a shared responsibility. Conduct periodic training on:
-
Writing secure Dockerfiles.
-
Minimising image layers.
-
Handling secrets securely.
-
Interpreting vulnerability scan results and prioritising remediation.
How Can the Public and Individual Developers Use Image Scanning?
While enterprises integrate scanning into CI/CD pipelines, public cloud users and individual developers can adopt:
A. CLI-based Local Scanning
Install Trivy locally to scan images before pushing to registries.
This is lightweight and prevents uploading vulnerable images to Docker Hub or ECR.
B. GitHub Actions for Open Source Projects
GitHub provides free security scanning for public repositories. Adding a GitHub Action for Trivy or Snyk automates scanning on every pull request.
Example:
GitHub Action snippet:
C. Free Tier of Cloud Scanning Tools
Cloud providers like AWS, GCP, and Azure offer integrated scanning features within container registries. For small projects, these free scans can protect public-facing workloads.
Conclusion
Integrating container image scanning into the build process is no longer optional – it is an essential pillar of modern DevSecOps. By scanning images early, using trusted minimal base images, enforcing policies, and automating continuous scans, organisations and developers can eliminate vulnerabilities before they reach production.
Security is most effective when built into development workflows rather than bolted on later. With the proliferation of containerised applications, adopting these best practices ensures that your deployments remain resilient against known threats, maintain compliance, and safeguard customer trust in an increasingly complex threat landscape.
Embracing proactive security scanning is not just about compliance – it is about building software that is secure by design, reliable by default, and trusted by everyone who depends on it.