Feature Request
Add Grype (by Anchore) as an optional second vulnerability scanner alongside Trivy. Grype uses a different vulnerability database (Anchore Grype DB) and CVE matching algorithm, meaning it often finds vulnerabilities that Trivy misses and vice versa. Running both improves detection coverage — which is exactly what an OWASP security tool should do.
Why Grype?
| Feature |
Trivy |
Grype |
| Vulnerability DB |
Trivy DB (GitHub) |
Grype DB (Anchore) |
| SBOM support |
Yes |
Yes (CycloneDX, SPDX) |
| False positive rate |
Medium |
Low |
| OS packages |
Yes |
Yes |
| Language packages |
Yes |
Yes |
| JSON output |
Yes |
Yes |
| License |
Apache 2.0 |
Apache 2.0 |
Cross-referencing both scanners increases confidence — a CVE flagged by both is very likely real.
Proposed CLI Integration
# Use Grype instead of Trivy
docksec Dockerfile -i myapp:latest --scanner grype
# Use both (default when both installed)
docksec Dockerfile -i myapp:latest --scanner all
# Use only Trivy (current default)
docksec Dockerfile -i myapp:latest --scanner trivy
Implementation Plan
1. `setup_external_tools.py` — add Grype installation
def install_grype():
"""Install Grype vulnerability scanner."""
if platform.system() == "Darwin":
subprocess.run(["brew", "install", "anchore/grype/grype"], check=True)
elif platform.system() == "Linux":
subprocess.run(
["curl", "-sSfL", "https://raw.githubusercontent.com/anchore/grype/main/install.sh"],
# pipe to sh -s -- -b /usr/local/bin
)
2. `docker_scanner.py` — add Grype scan method
def scan_image_grype(self, image_name: str) -> dict:
"""Scan a Docker image using Grype and return structured results."""
result = subprocess.run(
["grype", image_name, "-o", "json", "--fail-on", "none"],
capture_output=True, text=True, timeout=self.config.trivy_timeout
)
return self._parse_grype_output(result.stdout)
def _parse_grype_output(self, json_output: str) -> list[dict]:
"""Normalize Grype JSON output to DockSec's internal vulnerability format."""
...
3. Deduplication
When both Trivy and Grype are used, deduplicate by CVE ID and merge metadata:
def _deduplicate_vulnerabilities(self, trivy_vulns, grype_vulns):
"""Merge and deduplicate vulnerabilities from multiple scanners."""
seen = {}
for v in trivy_vulns + grype_vulns:
cve_id = v["VulnerabilityID"]
if cve_id not in seen:
seen[cve_id] = v
else:
# Keep highest severity, add source tag
seen[cve_id]["sources"] = seen[cve_id].get("sources", ["trivy"]) + ["grype"]
return list(seen.values())
4. Report Enhancement
Add a "Scanner Coverage" section to reports showing which scanner found each CVE.
Acceptance Criteria
References
Feature Request
Add Grype (by Anchore) as an optional second vulnerability scanner alongside Trivy. Grype uses a different vulnerability database (Anchore Grype DB) and CVE matching algorithm, meaning it often finds vulnerabilities that Trivy misses and vice versa. Running both improves detection coverage — which is exactly what an OWASP security tool should do.
Why Grype?
Cross-referencing both scanners increases confidence — a CVE flagged by both is very likely real.
Proposed CLI Integration
Implementation Plan
1. `setup_external_tools.py` — add Grype installation
2. `docker_scanner.py` — add Grype scan method
3. Deduplication
When both Trivy and Grype are used, deduplicate by CVE ID and merge metadata:
4. Report Enhancement
Add a "Scanner Coverage" section to reports showing which scanner found each CVE.
Acceptance Criteria
References