What is Grype?
Grype is an open-source vulnerability scanner for container images, filesystems, and software development life cycle (SDLC) artifacts. Developed by Anchore, Grype is purpose-built to identify known security vulnerabilities in operating system packages and application dependencies. It works by comparing the contents of an image or directory against comprehensive vulnerability databases such as the National Vulnerability Database (NVD), GitHub Security Advisories, and distro-specific feeds.
Unlike some heavier scanners, Grype is designed to be fast, easy to integrate into CI/CD pipelines, and works directly with common formats like Docker images, OCI archives, SBOMs (Software Bill of Materials) in SPDX or CycloneDX format, and raw directories. It is written in Go and ships as a single static binary, making deployment straightforward across any environment.
Key Features at a Glance
- Scans container images, directories, and SBOM files
- Supports multiple vulnerability databases with daily updates
- Produces structured output (JSON, table, CycloneDX, SARIF)
- Works offline with database caching
- Deeply integrates with Syft for SBOM generation
- Low false-positive rate through intelligent package-to-CVE matching
Why Grype Matters
đ Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Modern applications are assembled from thousands of open-source components and base operating system packages. Every layer introduces potential vulnerabilities. A typical Docker image may inherit vulnerabilities from the base OS, from language-level dependencies, and from statically linked binaries. Grype gives developers and security teams a unified lens into all of these layers at once.
Grype matters because it shifts vulnerability detection leftâinto the development cycleârather than waiting for a deployment audit. By scanning images before they reach production, teams can block vulnerable builds, patch dependencies proactively, and maintain compliance with frameworks such as PCI DSS, HIPAA, and SOC 2. Its speed and accuracy also make it suitable for real-time admission control in Kubernetes environments.
Installation and Setup
Grype ships as a single binary with no runtime dependencies. You can install it via package managers, download it from GitHub releases, or use the official Docker image. Here are the most common approaches:
Via Homebrew (macOS/Linux)
brew tap anchore/grype
brew install grype
Via curl (Linux/macOS)
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
This script fetches the latest release and places the binary in the specified directory. Verify the installation with:
grype version
Docker-based usage
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock anchore/grype:latest your-image:tag
Mounting the Docker socket allows Grype to pull and scan images directly. For air-gapped environments, you can pre-load the vulnerability database and pass it as a volume.
Configuration
Grype's behavior is controlled through a YAML configuration file, environment variables, and command-line flags. The default configuration file location is ~/.grype/config.yaml. You can generate a fresh configuration file to see all available options:
grype config --output yaml > ~/.grype/config.yaml
Configuration File Structure
A typical configuration file looks like this:
# ~/.grype/config.yaml
db:
# Where the vulnerability database is stored
dir: ~/.grype/db
# Auto-update the database on each run
auto-update: true
# Validate database age (in days)
max-db-age: 5
check:
# Severity threshold: negligible, low, medium, high, critical
fail-on-severity: high
# Whether to show CVE details
show-cve-detail: true
scan:
# Exclude certain paths from scanning
exclude-paths:
- "/usr/share/doc/**"
- "**/node_modules/**"
# Only scan specific OS/distro types
distro-preference:
- debian
- alpine
log:
level: warn
file: ~/.grype/logs/grype.log
Environment Variables
Every configuration key can be overridden with an environment variable using the prefix GRYPE_ and converting dots/colons to underscores:
# Set the database auto-update to false
export GRYPE_DB_AUTO_UPDATE=false
# Set the fail-on-severity threshold
export GRYPE_CHECK_FAIL_ON_SEVERITY=critical
# Specify a custom database path
export GRYPE_DB_DIR=/mnt/grype-db
Database Management
Grype relies on a local vulnerability database. On first run, it downloads the database automatically. You can also manage it explicitly:
# Download or update the database
grype db update
# Check database status
grype db status
# List available vulnerability sources
grype db list
For CI/CD pipelines, it's a best practice to cache the database or use a pre-seeded database volume to avoid repeated downloads.
How to Use Grype
Grype accepts several input types: container images, Docker archives, directories, and SBOM files. Here are practical examples for each scenario.
Scanning a Container Image
The most common use case: scan a Docker image directly from a registry or local cache.
# Scan a public image
grype nginx:1.25
# Scan with severity filtering
grype nginx:1.25 --fail-on high
# Output JSON for pipeline consumption
grype nginx:1.25 -o json > results.json
# Output as CycloneDX vulnerability report
grype nginx:1.25 -o cyclonedx-xml > results.xml
Scanning a Local Directory
Grype can scan a filesystem path directly, which is useful for scanning build artifacts before containerization:
grype dir:/path/to/your/project
# Scan the current directory
grype dir:.
Scanning an SBOM File
If you have already generated an SBOM (for example, with Syft), Grype can consume it directly:
# Generate an SBOM with Syft
syft nginx:1.25 -o spdx-json > nginx.spdx.json
# Scan the SBOM with Grype
grype sbom:./nginx.spdx.json
This decouples inventory gathering from vulnerability scanningâideal for staged pipelines where SBOM generation happens once and scanning happens multiple times against updated vulnerability data.
Using Grype with Syft in a Pipeline
A powerful pattern combines Syft and Grype in a single pipeline step:
# Pipe Syft output directly into Grype
syft your-image:latest -o json | grype
# Or capture both SBOM and vulnerabilities
syft your-image:latest -o spdx-json > sbom.json
grype sbom:./sbom.json -o json > vulnerabilities.json
Ignoring and Accepting Vulnerabilities
Not every vulnerability is exploitable in your context. Grype provides mechanisms to suppress specific findings.
Inline ignores via a YAML file:
# .grype/ignores.yaml
ignore:
- vulnerability: CVE-2023-12345
package: libssl
reason: "Not exploitable in our configurationâwe use TLS 1.3 exclusively"
target: nginx:1.25
- vulnerability: GHSA-xxxx-xxxx-xxxx
package: lodash
reason: "Only used in dev builds, not present in production image"
Apply it with:
grype nginx:1.25 --ignore-file .grype/ignores.yaml
Output Formats and Integration
Grype supports multiple output formats that plug directly into different ecosystems:
# Table format (default, human-readable)
grype alpine:latest
# JSON format
grype alpine:latest -o json
# CycloneDX XML/JSON
grype alpine:latest -o cyclonedx-json
grype alpine:latest -o cyclonedx-xml
# SARIF for GitHub Code Scanning integration
grype alpine:latest -o sarif > grype-results.sarif
For GitHub Actions, you can upload SARIF results directly:
name: Container Vulnerability Scan
on: [push]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan image with Grype
run: |
grype your-image:latest -o sarif > grype-results.sarif
- name: Upload SARIF to GitHub
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: grype-results.sarif
Best Practices
1. Keep the Vulnerability Database Fresh
The database is the brain of Grype. An outdated database misses newly disclosed vulnerabilities. Configure automatic updates and set a maximum database age that aligns with your risk tolerance:
# In config.yaml
db:
auto-update: true
max-db-age: 1 # Fail if database is older than 1 day
In air-gapped environments, set up a cron job to pull the database on a schedule and distribute it to scanning nodes.
2. Fail Builds on Severity Thresholds
Integrate Grype into CI/CD with a strict pass/fail policy. Use --fail-on to break the build when vulnerabilities exceed a threshold:
grype your-image:latest --fail-on high
This returns a non-zero exit code when any vulnerability at "high" or "critical" severity is found. Combine with --fail-on-severity in the config file for consistent enforcement across teams.
3. Generate and Store SBOMs as Build Artifacts
Rather than scanning images directly every time, generate an SBOM with Syft at build time and store it as an immutable artifact. Then scan the SBOM with Grype. This decouples inventory from vulnerability analysis and lets you re-scan the same SBOM as new CVEs emerge:
# Build step
syft your-image:latest -o spdx-json > sbom.spdx.json
# Archive sbom.spdx.json as a build artifact
# Later, scan the SBOM
grype sbom:sbom.spdx.json -o json > vuln-report.json
4. Maintain a Curated Ignore File
Not all vulnerabilities are relevant. Maintain a version-controlled ignore file that documents why specific vulnerabilities are suppressed. Require a reason for each entry and review the file regularly:
ignore:
- vulnerability: CVE-2024-XXXX
package: openssl
reason: "We pin OpenSSL to a patched version via overlay"
reviewed-by: "security-team"
review-date: "2025-01-15"
Treat the ignore file like codeâreview it in pull requests and expire entries after a set period.
5. Use Grype in Admission Controllers
For Kubernetes, integrate Grype into admission webhooks to block deployment of vulnerable images. Tools like Anchore Enterprise, OPA, or custom webhooks can call Grype and reject pods that exceed your severity policy. A minimal example using a validating webhook:
# Extract image digest from the admission request
# Run Grype against the image
grype "${IMAGE_DIGEST}" --fail-on critical
# If exit code != 0, deny the admission request
6. Combine with Policy-as-Code
Grype's JSON output can be consumed by policy engines such as OPA (Open Policy Agent) or Kyverno. Write Rego policies that encode organizational rules beyond simple severity thresholdsâfor example, blocking images older than 30 days or requiring vendor-specific patches:
# Example OPA policy snippet
deny[msg] {
vuln := input.matches[_]
vuln.vulnerability.severity == "Critical"
not ignored_vulns[vuln.vulnerability.id]
msg := sprintf("Critical vulnerability %s found in %s", [vuln.vulnerability.id, vuln.artifact.name])
}
7. Leverage Distro-Specific Scanning
Grype automatically detects the Linux distribution in a container image and uses the appropriate vulnerability feed. For multi-stage builds or distroless images, ensure the base OS layers are scanned. If Grype misidentifies the distro, you can hint it:
grype your-image:latest --distro debian:12
8. Parallelize and Cache in CI/CD
Database download is often the slowest part of a Grype scan. Cache the database directory (~/.grype/db) across CI runs using build cache mechanisms (e.g., GitHub Actions cache, CircleCI save_cache). For monorepos with many images, run Grype scans in parallel and aggregate results.
# GitHub Actions cache example
- name: Cache Grype DB
uses: actions/cache@v4
with:
path: ~/.grype/db
key: grype-db-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
9. Tag Images with Scan Results
In production pipelines, tag container images with metadata about their vulnerability status. This creates an auditable chain and prevents operators from accidentally deploying unscanned images:
# After a successful scan
docker tag your-image:latest your-image:scanned-high-pass
# Push both tags
docker push your-image:latest
docker push your-image:scanned-high-pass
10. Regularly Review and Rotate Policies
Vulnerability management is not a one-time setup. Schedule quarterly reviews of your Grype configuration: revisit severity thresholds, prune stale ignore entries, update database freshness windows, and align policies with evolving compliance requirements. Automate reminders with calendar tickets or dashboard metrics that show policy effectiveness over time.
Conclusion
Grype is a fast, flexible, and highly integrable vulnerability scanner that fits naturally into modern containerized development workflows. From the developer's local environment to the CI/CD pipeline and all the way to Kubernetes admission control, Grype provides consistent, actionable vulnerability intelligence. By following the setup patterns and best practices outlined in this tutorialâkeeping the database fresh, failing builds on defined severity thresholds, maintaining curated ignore files, generating and storing SBOMs, and integrating with policy enginesâyou can build a robust vulnerability management program that catches risks early, reduces alert fatigue, and keeps production deployments secure. The key is to treat vulnerability scanning not as a checkbox activity but as an ongoing, policy-driven practice embedded throughout the software delivery lifecycle.