Container Vulnerability Scanning with Six Scanners in One Pipeline.
HarborGuard runs Trivy, Grype, Syft, Dockle, OSV-Scanner, and Dive in parallel on every image. Findings are deduplicated, normalized, and ready for triage in under five minutes — without touching your CI build budget.
Trivy
0 critical, 2 high
Grype
2 high (same CVEs)
OSV-Scanner
1 additional medium
Dockle
Running as root
Syft
CycloneDX attached
Dive
76% efficiency
6
Scanners running in parallel
<5 min
End-to-end scan time
11+
Registries supported
25+
Language ecosystems in SBOM
What it does
One scan that runs all the tools you would have run separately.
Running a single scanner means choosing between coverage and precision. Trivy has the broadest OS and language coverage. Grype's SBOM-based matching is more accurate on language ecosystems. OSV-Scanner has earlier publication timestamps for many advisories. Dockle catches hardening failures that no CVE scanner covers. Syft generates the SBOM artifacts compliance frameworks require. Dive traces vulnerabilities back to the build step that introduced them.
Most security teams pick one or two tools, accept the coverage gaps, and manually maintain the toolchain. HarborGuard runs all six against every image in a single dispatch to an ephemeral sensor container. The sensor runs the scanners in parallel, merges findings by CVE ID so duplicates collapse, and POSTs a single normalized result envelope back to the platform.
The sensor dispatches to an ephemeral cloud worker in production (with dedicated CPU and memory) or to local Docker in development. Adapter selection is automatic — no code change required when moving between environments. Neither mode requires a Docker daemon on the host running the scan.
How it works
Container vulnerability scanning, step by step.
Connect a container registry
Add credentials for Docker Hub, ECR, GCR, ACR, GHCR, GitLab Registry, Harbor, JFrog Artifactory, Quay, Nexus, or any OCI-compliant endpoint. Credentials are encrypted with AES-256-GCM envelope encryption and realm-validated before attaching to scan requests.
HarborGuard resolves the image reference
The scan worker normalizes short image references to fully-qualified OCI refs. Docker Hub images get the docker.io/library/ prefix automatically. Private registry references are constructed from the stored registry URL and the image name.
An ephemeral sensor container is dispatched
In production, the scan worker dispatches an ephemeral cloud worker running an isolated scan sensor container with dedicated CPU and memory. In development, it dispatches to the local Docker daemon. The sensor pulls the target image directly from the registry — no Docker daemon on the scan host required.
Six scanners run in parallel against the image
Trivy (OS packages, language deps, secrets, license), Grype (SBOM-driven CVE matching), Syft (SBOM generation), Dockle (CIS Docker Benchmark hardening checks), OSV-Scanner (OSV.dev advisory feed), and Dive (layer efficiency analysis) all run simultaneously inside the sensor container.
Findings are deduplicated and normalized
The sensor produces a single results envelope. Duplicate CVEs found by multiple scanners are merged by (cveId, package, packageVersion), with all source scanner names preserved in the sources array. CVSS scores, severity ratings, and fixed version information are normalized into a unified schema.
Results are POSTed to the upload callback
The sensor POSTs the normalized envelope to the platform's scan-upload callback. The scan worker polls for the callback for up to two minutes after container exit, accommodating large payloads on slow networks.
Auto-triage dispatch and notification
On successful ingest, the triage pipeline automatically evaluates the findings against your severity threshold and dispatches triage runs for qualifying CVEs. Scan completion notifications route to your configured Slack, PagerDuty, email, or webhook channels.
The six scanners: what each one finds
Trivy
Broadest CVE + secret + license coverage
Trivy from Aqua Security scans OS packages, language dependencies across 20+ ecosystems, embedded secrets, license violations, and image misconfigurations. Its vulnerability database refreshes from NVD, GitHub Security Advisories, and Aqua's own feeds. HarborGuard runs Trivy in full-coverage mode (--scanners vuln,secret,license) on every image.
Coverage
- Alpine, Debian, Ubuntu, RHEL, Amazon Linux, SUSE, Photon, Wolfi
- npm, PyPI, Maven, RubyGems, NuGet, Cargo, Go modules, Composer, Hex
- Embedded secrets and credentials
- License compliance violations
Grype
SBOM-first vulnerability matching
Grype from Anchore consumes SBOMs (from Syft) and matches packages against the NVD, GitHub Security Advisories, Alpine secdb, and over a dozen other feeds. HarborGuard pipes Syft output directly into Grype for SBOM-first scanning, then cross-references findings with Trivy results. Per-engine attribution is preserved on every merged finding.
Coverage
- SBOMs in CycloneDX, SPDX, or Syft-native format
- OS packages across major distributions
- Language deps with stricter version constraints
- Cross-references NVD + GHSA + Alpine secdb
Syft
SBOM generation across 25+ ecosystems
Syft is the Software Bill of Materials generator for HarborGuard. Every scan produces a Syft-generated SBOM stored alongside the scan record, exportable in CycloneDX-JSON, CycloneDX-XML, SPDX-JSON, or SPDX Tag-Value. SBOMs are required evidence artifacts for SOC 2, FedRAMP, CMMC, and ISO 27001 controls. The SBOM also feeds directly into Grype for dual scanning without re-extracting layers.
Coverage
- deb, rpm, apk, alpm OS packages
- npm, yarn, pip, poetry, conda, RubyGems, Maven, Gradle, NuGet, Cargo, Go, Hex, Composer, Dart, Swift
- Binary fingerprints (Go, Rust, Java)
- CycloneDX-JSON, CycloneDX-XML, SPDX-JSON, SPDX-Tag-Value export
Dockle
CIS Docker Benchmark hardening linter
Dockle catches what CVE scanners miss: images built as root, missing HEALTHCHECK, leaked secrets in layers, use of ADD instead of COPY, and other Dockerfile violations mapped to CIS Docker Benchmark sections. HarborGuard routes Dockle findings into the CIS_DOCKER compliance framework controls automatically. Dockle hardening findings carry their own severity scale and surface in the scan detail alongside CVE findings.
Coverage
- Dockerfile USER, ENTRYPOINT, HEALTHCHECK checks
- Embedded secrets in image layers
- CIS Docker Benchmark §4 Image section
- SARIF output for GitHub Code Scanning integration
OSV-Scanner
OSV.dev advisory feed with lockfile precision
OSV-Scanner from Google cross-references lockfiles and package manifests against the OSV.dev database, which aggregates GHSA, PyPA, RustSec, Go vuln DB, and many ecosystem-specific advisory feeds. OSV's version-range model provides stronger accuracy for language-package advisories compared to NVD-only scanners. Findings are deduplicated against Trivy and Grype by CVE ID before entering the triage pipeline.
Coverage
- Lockfiles: package-lock.json, requirements.txt, Gemfile.lock, Cargo.lock, go.sum, composer.lock, pom.xml
- OSV.dev canonical version ranges (stronger than NVD for language ecosystems)
- Git-commit-pinned dependencies
- SLSA Level 3 compatible attestation output
Dive
Layer-by-layer efficiency analysis
Dive reveals the size contribution, file additions, and package introductions of every image layer. HarborGuard surfaces Dive output on the scan detail page so engineers can trace exactly which build step introduced a vulnerable package and identify wasted bytes (overwritten files, unnecessary tools). Smaller, leaner images have a smaller CVE attack surface by construction.
Coverage
- Per-layer file additions, modifications, and deletions
- Layer efficiency score (% wasted bytes)
- Image total size and layer count
- Correlate vulnerable package to introducing layer
Ephemeral cloud worker (cloud) adapter
In production, every scan dispatches an ephemeral cloud worker running an isolated scan sensor container. The worker is provisioned with dedicated CPU and memory so all six scanners run in parallel without resource contention. After the sensor POSTs its result envelope, the worker is destroyed. The added reliability of consistent, parallel results is worth more than the savings from under-provisioning.
The sensor uses container image transport tooling to pull the target image from the registry, so no Docker daemon is needed on the cloud worker itself. This enables scanning private ECR, GCR, and ACR images with standard credential forwarding to every scanner that has its own auth model.
Local Docker adapter (dev)
In development environments without cloud worker credentials, the scan worker automatically switches to the local Docker adapter. Scans run the same isolated scan sensor container via the local Docker daemon, with the same six scanners, the same result format, and the same callback protocol. The adapter switch is automatic — no code changes or configuration needed.
The local adapter is also available as a Docker-compose deployment for teams who want to run workers in containers on the local machine rather than natively on the host. Both paths produce identical scan results and are covered by the same integration tests.
Behind the scenes: the scan data flow
From the moment a scan is requested to the moment a triage run opens, the pipeline moves through a small set of well-defined steps. Each step is observable, each step is idempotent, and each step has a clear handoff to the next.
Scan request received
A scan is requested from the dashboard, the REST API, or a CI pipeline. The platform validates the image reference, scopes the work to your organization, and assigns the scan an ID.
Registry credentials decrypted
The scan worker looks up the registry record that owns the image, decrypts the credentials from AES-256-GCM envelope storage, and realm-validates that the credentials match the target host before attaching them to the dispatch.
Sensor dispatched to a cloud worker
An isolated scan sensor container is dispatched — to an ephemeral cloud worker in production, or to the local Docker daemon in development. The sensor pulls the image directly from the registry; no Docker daemon on the scan host is required.
Six scanners run in parallel
Inside the sensor, Trivy, Grype, Syft, Dockle, OSV-Scanner, and Dive run simultaneously against the pulled image layers. Each scanner produces native JSON output, normalized into a unified result schema.
Findings deduplicated and persisted
The sensor merges duplicate CVEs found by multiple scanners on the same package and version, then POSTs the unified envelope back to the platform. The platform deduplicates again across scans, captures the SBOM, and persists the finding rows.
Auto-triage and notifications fire
Findings that meet your severity threshold are queued for triage on the platform's job queue. Completion notifications route to your configured Slack, PagerDuty, email, or webhook channels.
Registry support
Explore related capabilities
Questions about container vulnerability scanning
What container registries does HarborGuard support?
HarborGuard supports Docker Hub, Amazon ECR, Google Container Registry (GCR), Azure Container Registry (ACR), GitHub Container Registry (GHCR), GitLab Registry, Harbor, JFrog Artifactory, Quay.io, Sonatype Nexus, and any OCI-compliant registry endpoint. Registry credentials are stored encrypted with AES-256-GCM envelope encryption and are validated at connection time by test-pulling a registry manifest. The platform also supports unauthenticated pulls for public images on any registry.
How does HarborGuard run six scanners without consuming my CI build minutes?
Scans are dispatched to ephemeral cloud workers entirely independent of your CI pipeline. Your CI runner makes a single API call to trigger the scan and can either wait for a webhook callback or poll for completion. The six scanners run in parallel inside an isolated scan sensor container with dedicated CPU and memory. Your CI build minutes are consumed only by the API call latency — typically under five minutes total. In development environments, scans dispatch to the local Docker daemon using the same sensor image.
How are findings from six different scanners deduplicated?
Trivy, Grype, and OSV-Scanner all scan the same image and often surface the same CVE from different advisory databases. The sensor's ingest pipeline merges findings by (cveId, package, packageVersion) within a single scan. A CVE found by all three scanners appears as one row in the vulnerability table, with all three scanner names listed in the sources field. CVSS scores and severity ratings are normalized — where scanners disagree on severity, the highest value is used. Dockle and Dive findings do not participate in CVE deduplication since they cover distinct concern classes (hardening checks and layer analysis).
What is SBOM generation and why does it matter?
A Software Bill of Materials (SBOM) is a machine-readable manifest of every package, library, and component inside a container image. HarborGuard generates SBOMs via Syft on every scan and stores them alongside the scan record. SBOMs are required for several compliance frameworks: SOC 2 CC7.1 (vulnerability detection evidence), FedRAMP SI-2 (flaw remediation), CMMC RM.2.142, and NIST 800-53 SA-17. SBOMs are also the input format for the Grype scanner, enabling SBOM-first dependency matching without re-extracting image layers. You can download SBOMs per scan in CycloneDX or SPDX format from the scan detail page or via the API.
Does scanning work for private registries that require authentication?
Yes. The scan worker resolves registry credentials before dispatching the sensor container. The credential resolution path validates that the image reference host matches the registry record host (realm-validation) before attaching credentials — this prevents ECR credentials from accidentally being sent to Docker Hub when image refs share a common host. Credentials are passed to the sensor container so all six scanners can authenticate independently. The sensor handles per-registry auth protocols including ECR token refresh.
What happens if the sensor container times out?
The sensor container has a configurable timeout (default 15 minutes, hard ceiling). If the container exits without POSTing a result envelope, the scan worker polls for the callback for up to two minutes post-exit before checking the database status. If the scan is still in IN_PROGRESS state at that point, the worker sets it to FAILED and dispatches a scan_failed notification. The worker explicitly re-reads the database status before writing FAILED to avoid a race condition where the sensor's POST was in-flight during the machine stop sequence — if status is already COMPLETED, the FAILED write is skipped.
Stop choosing between scanners
Start your 14-day trial. Six scanners on your first image in under five minutes.
Connect a registry, run your first scan, and get Trivy, Grype, Syft, Dockle, OSV-Scanner, and Dive results on the same image before your next coffee.