# Grype Vulnerability Matcher (`ayeeyee/grype-vulnerability-matcher`) Actor

Scan a container image or git repository for known CVEs using Grype, Anchore open-source vulnerability scanner. Get severity-scored matches from Critical to Negligible, cross-referenced against the latest vulnerability database. $0.79 per completed scan; failed scans are never charged.

- **URL**: https://apify.com/ayeeyee/grype-vulnerability-matcher.md
- **Developed by:** [Virtual Footprint LLC](https://apify.com/ayeeyee) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $790.00 / 1,000 scan completeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

<p align="center">
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAwIiBoZWlnaHQ9IjMyMCIgdmlld0JveD0iMCAwIDEyMDAgMzIwIiByb2xlPSJpbWciIGFyaWEtbGFiZWxsZWRieT0idGl0bGUgZGVzYyI+CiAgPHRpdGxlIGlkPSJ0aXRsZSI+R3J5cGUgVnVsbmVyYWJpbGl0eSBNYXRjaGVyPC90aXRsZT4KICA8ZGVzYyBpZD0iZGVzYyI+UmVhbCBDVkUgbWF0Y2hlcyBmcm9tIE5WRCwgR0hTQSwgYW5kIGRpc3RybyBmZWVkczwvZGVzYz4KICA8ZGVmcz4KICAgIDxsaW5lYXJHcmFkaWVudCBpZD0iZWRnZSIgeDE9IjAiIHkxPSIwIiB4Mj0iMSIgeTI9IjEiPgogICAgICA8c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiM2NjMzOTkiIHN0b3Atb3BhY2l0eT0iMC4xOCIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM2NjMzOTkiIHN0b3Atb3BhY2l0eT0iMCIvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICA8L2RlZnM+CiAgPHJlY3Qgd2lkdGg9IjEyMDAiIGhlaWdodD0iMzIwIiByeD0iMjYiIGZpbGw9IiMwYTBkMTIiLz4KICA8cmVjdCB3aWR0aD0iMTIwMCIgaGVpZ2h0PSIzMjAiIHJ4PSIyNiIgZmlsbD0idXJsKCNlZGdlKSIvPgogIDxyZWN0IHg9IjAuNSIgeT0iMC41IiB3aWR0aD0iMTE5OSIgaGVpZ2h0PSIzMTkiIHJ4PSIyNS41IiBmaWxsPSJub25lIiBzdHJva2U9IiMxYzIxMjkiIHN0cm9rZS13aWR0aD0iMSIvPgoKICA8ZyBpZD0idGl0bGUtYmxvY2siIHRyYW5zZm9ybT0idHJhbnNsYXRlKDU2IDY0KSI+CiAgICA8cmVjdCB4PSIwIiB5PSItMjgiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgcng9IjIiIGZpbGw9IiM2NjMzOTkiLz4KICAgIDx0ZXh0IHg9IjIwIiB5PSItMjAiIGZvbnQtZmFtaWx5PSJ1aS1tb25vc3BhY2UsIFNGTW9uby1SZWd1bGFyLCBNZW5sbywgbW9ub3NwYWNlIiBmb250LXNpemU9IjEyIiBmaWxsPSIjNjYzMzk5Ij5TRUNVUklUWSBTQ0FOTkVSICYjMTgzOyBSRUFMIERBVEEsIE5PIEZBQlJJQ0FUSU9OPC90ZXh0PgogICAgPHRleHQgeD0iMCIgeT0iMjYiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIFNlZ29lIFVJLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjQwIiBmb250LXdlaWdodD0iODAwIiBmaWxsPSIjZmZmZmZmIj5HcnlwZSBWdWxuZXJhYmlsaXR5IE1hdGNoZXI8L3RleHQ+CiAgICA8dGV4dCB4PSIwIiB5PSI2MCIgZm9udC1mYW1pbHk9Ii1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgU2Vnb2UgVUksIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IiNjOWQxZDkiPlJlYWwgQ1ZFIG1hdGNoZXMgZnJvbSBOVkQsIEdIU0EsIGFuZCBkaXN0cm8gZmVlZHM8L3RleHQ+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEwMCkiPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAwKSI+CiAgICAgIDx0ZXh0IHg9IjAiIHk9IjAiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIFNlZ29lIFVJLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjI4IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjZmZmZmZmIj4zMzc8L3RleHQ+CiAgICAgIDx0ZXh0IHg9IjAiIHk9IjIwIiBmb250LWZhbWlseT0iLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCBTZWdvZSBVSSwgc2Fucy1zZXJpZiIgZm9udC1zaXplPSIxMiIgZmlsbD0iIzhiOTQ5ZSI+Q1ZFcyBmb3VuZDwvdGV4dD4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE1MCAwKSI+CiAgICAgIDx0ZXh0IHg9IjAiIHk9IjAiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIFNlZ29lIFVJLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjI4IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjZmZmZmZmIj4xNjwvdGV4dD4KICAgICAgPHRleHQgeD0iMCIgeT0iMjAiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIFNlZ29lIFVJLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjEyIiBmaWxsPSIjOGI5NDllIj5Dcml0aWNhbDwvdGV4dD4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAwKSI+CiAgICAgIDx0ZXh0IHg9IjAiIHk9IjAiIGZvbnQtZmFtaWx5PSItYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIFNlZ29lIFVJLCBzYW5zLXNlcmlmIiBmb250LXNpemU9IjI4IiBmb250LXdlaWdodD0iNzAwIiBmaWxsPSIjZmZmZmZmIj4zMzcvMzM3PC90ZXh0PgogICAgICA8dGV4dCB4PSIwIiB5PSIyMCIgZm9udC1mYW1pbHk9Ii1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgU2Vnb2UgVUksIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIGZpbGw9IiM4Yjk0OWUiPkFkdmlzb3J5IGxpbmtzPC90ZXh0PgogICAgPC9nPgogICAgPC9nPgogIDwvZz4KCiAgPGcgaWQ9InByb2plY3QtcHJvb2YiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcwMCA3NikiPgogICAgPHJlY3QgeD0iLTI0IiB5PSItNDAiIHdpZHRoPSI0NzAiIGhlaWdodD0iMjIwIiByeD0iMTQiIGZpbGw9IiMwZDExMTciIHN0cm9rZT0iIzFjMjEyOSIgc3Ryb2tlLXdpZHRoPSIxIi8+CiAgICA8dGV4dCB4PSIwIiB5PSItMTQiIGZvbnQtZmFtaWx5PSJ1aS1tb25vc3BhY2UsIFNGTW9uby1SZWd1bGFyLCBNZW5sbywgbW9ub3NwYWNlIiBmb250LXNpemU9IjExIiBmaWxsPSIjOGI5NDllIj4kIGFwaWZ5IGNhbGwgZ3J5cGUtdnVsbmVyYWJpbGl0eS1tYXRjaGVyPC90ZXh0PgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAxNikiPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAwKSI+CiAgICAgIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgcng9IjIiIGZpbGw9IiNmZjVmNTYiLz4KICAgICAgPHRleHQgeD0iMTgiIHk9IjkiIGZvbnQtZmFtaWx5PSJ1aS1tb25vc3BhY2UsIFNGTW9uby1SZWd1bGFyLCBNZW5sbywgbW9ub3NwYWNlIiBmb250LXNpemU9IjEyIiBmaWxsPSIjYzlkMWQ5Ij5DVkUtMjAyNS0xNTQ2NyAgbGlic3NsM3Q2NCAgMy41LjEtMStkZWIxM3UxPC90ZXh0PgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAyNikiPgogICAgICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHJ4PSIyIiBmaWxsPSIjZmY1ZjU2Ii8+CiAgICAgIDx0ZXh0IHg9IjE4IiB5PSI5IiBmb250LWZhbWlseT0idWktbW9ub3NwYWNlLCBTRk1vbm8tUmVndWxhciwgTWVubG8sIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxMiIgZmlsbD0iI2M5ZDFkOSI+Q1ZFLTIwMjYtNTQ1MCAgIGxpYmMtYmluICAgIDIuNDEtMTI8L3RleHQ+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDUyKSI+CiAgICAgIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgcng9IjIiIGZpbGw9IiNmZjlmNDMiLz4KICAgICAgPHRleHQgeD0iMTgiIHk9IjkiIGZvbnQtZmFtaWx5PSJ1aS1tb25vc3BhY2UsIFNGTW9uby1SZWd1bGFyLCBNZW5sbywgbW9ub3NwYWNlIiBmb250LXNpemU9IjEyIiBmaWxsPSIjYzlkMWQ5Ij5DVkUtMjAyMy0zNjYzMiAgcHl0aG9uICAgICAgMy45LjI1PC90ZXh0PgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCA3OCkiPgogICAgICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHJ4PSIyIiBmaWxsPSIjNTFjZjY2Ii8+CiAgICAgIDx0ZXh0IHg9IjE4IiB5PSI5IiBmb250LWZhbWlseT0idWktbW9ub3NwYWNlLCBTRk1vbm8tUmVndWxhciwgTWVubG8sIG1vbm9zcGFjZSIgZm9udC1zaXplPSIxMiIgZmlsbD0iI2M5ZDFkOSI+c2NhbiBjb21wbGV0ZSAmIzE4MzsgMzM3IGZpbmRpbmdzICYjMTgzOyAwIGZhYnJpY2F0ZWQ8L3RleHQ+CiAgICA8L2c+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4=" width="100%" alt="grype-vulnerability-matcher hero banner">
</p>

<p align="center">
  <a href="https://github.com/anchore/grype"><img src="https://img.shields.io/badge/powered%20by-Grype-663399?style=for-the-badge" alt="Powered by Grype"></a>
  <img src="https://img.shields.io/badge/License-Apache--2.0-555555?style=for-the-badge" alt="Apache 2.0">
  <img src="https://img.shields.io/badge/Vuln%20Data-NVD%20%C2%B7%20GHSA%20%C2%B7%20distro-F86606?style=for-the-badge" alt="Multi-source DB">
</p>

<p align="center">
  <a href="#why-a-second-scanner-alongside-trivy">Why a second scanner</a> &bull;
  <a href="#use-cases">Use cases</a> &bull;
  <a href="#input">Input</a> &bull;
  <a href="#output">Output</a> &bull;
  <a href="#pricing">Pricing</a>
</p>

## Grype Vulnerability Matcher

**A second, independent CVE scanner for any container image or public repo — real matches from NVD, GHSA, and distro feeds.**

> **Verified live** against `python:3.9-slim`: 337 real matches found (16 Critical, 94 High, 123 Medium, 14 Low, 54 Negligible, 36 Unknown), each with severity, fix state, and a working data-source link — no invented CVE IDs.

### Why a second scanner alongside Trivy

Grype and Trivy use overlapping but not identical vulnerability databases and matching logic. Findings that show up in one but not the other are common in practice — running both against the same target is a legitimate cross-check, and multi-scanner coverage is a real requirement for many compliance programs, not redundancy for its own sake.

### What you get

- Real CVE matches from Grype's combined NVD, GitHub Security Advisories, and Linux-distro vulnerability feeds — nothing invented or templated.
- Severity, installed version, fix state, and fixed-version-if-available on every match.
- A `scan_summary` row with totals by severity so you don't have to count rows yourself.
- Works against both container images and public git repos, auto-detecting which one you gave it.
- Only charges on a successfully completed scan — a bad target or clone failure isn't billed.

### How it works

```
target (image or repo URL)
   |
   v
scanType auto-detected (image vs repo)
   |
   v
git clone --depth 1  (repo targets only)
   |
   v
grype <target> -o json   (DB baked in at build time, no runtime download)
   |
   v
severity/fixable filters applied
   |
   v
one dataset row per match + one scan_summary row
```

### Use cases

- **Second-opinion CVE check** — run alongside Trivy on the same image and diff the two match lists before a release ships.
- **Compliance programs that require multi-scanner coverage** — some frameworks explicitly ask for more than one vulnerability data source.
- **Base image comparison** — compare Grype's match count across candidate base images before standardizing.
- **Public repo dependency audit** — point it at a git URL to check for known-vulnerable dependencies without cloning locally.

### Input

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `target` | string | yes | Container image (`nginx:1.19`) or git repo URL |
| `scanType` | string | no | `image` or `repo` — auto-detected if left blank |
| `severityFilter` | array | no | Restrict results to given severities |
| `onlyFixable` | boolean | no | Skip vulnerabilities with no available fix |

```json
{ "target": "python:3.9-slim", "severityFilter": ["Critical", "High"] }
```

### Output

One row per real CVE match (ID, severity, package, installed version, fix state and version, data source), plus one `scan_summary` row with totals by severity.

#### Sample output

Three real findings from the live-verification run above (338 total rows: 337 matches + 1 summary):

```json
{
  "findingType": "vulnerability",
  "target": "python:3.9-slim",
  "vulnerabilityId": "CVE-2025-15467",
  "severity": "Critical",
  "pkgName": "libssl3t64",
  "installedVersion": "3.5.1-1+deb13u1",
  "pkgType": "deb",
  "fixState": "fixed",
  "fixedVersions": ["3.5.4-1~deb13u2"],
  "dataSource": "https://security-tracker.debian.org/tracker/CVE-2025-15467",
  "description": "Issue summary: Parsing CMS AuthEnvelopedData or EnvelopedData message with maliciously crafted AEAD parameters can trigger a stack buffer overflow..."
}
```

And the `scan_summary` row from the same run:

```json
{
  "findingType": "scan_summary",
  "target": "python:3.9-slim",
  "scanType": "image",
  "totalMatches": 337,
  "totalReturned": 337,
  "severityCounts": { "Critical": 16, "High": 94, "Medium": 123, "Negligible": 54, "Low": 14, "Unknown": 36 },
  "status": "COMPLETED",
  "scannedAt": "2026-08-01T16:56:36.573416+00:00"
}
```

### Pricing

Pay per completed scan (Pay-Per-Event) — **$0.79 per scan**, charged once the scan finishes regardless of how many matches are found. Failed scans are never charged.

### Frequently asked questions

**How is this different from the Trivy Actor?**
Different underlying tool, different vulnerability database composition (NVD/GHSA/distro feeds vs. Trivy's own aggregated sources), different matching logic. They frequently agree but not always — that's the point of running both.

**Does it need a fresh database download on every run?**
No — the vulnerability database is updated and baked into the Docker image at build time, and the Actor is explicitly configured to skip runtime database checks (`GRYPE_DB_AUTO_UPDATE=false`), so every run scans immediately instead of waiting on a network fetch.

**Can I scan a private image or repo?**
No — only public registries and public git URLs are supported; there's no credential input for private targets.

**What if there are zero matches?**
You get zero `vulnerability` rows and a `scan_summary` row with `totalMatches: 0` — a clean target isn't padded with findings to look more substantial.

### Limitations

- Only public container images and public git repos are supported.
- The vulnerability database reflects the image's build time, not the live moment of your scan — refreshed periodically, not on every run.
- `onlyFixable` filters out real findings that don't yet have a fix available; leave it off if you want the complete picture including unfixed CVEs.

### Related Actors

Part of a five-Actor security scanning catalog: [Trivy Security Scanner](https://apify.com/ayeeyee/trivy-security-scanner) (CVEs + secrets + misconfigurations in one scan), [Gitleaks Secret Scanner](https://apify.com/ayeeyee/gitleaks-secret-scanner) (full git-history secret detection), [Syft SBOM Generator](https://apify.com/ayeeyee/syft-sbom-generator) (CycloneDX/SPDX bill of materials), [OSV-Scanner Vulnerability Checker](https://apify.com/ayeeyee/osv-scanner-vulnerability-checker) (lockfile-based OSV.dev checks).

### Start scanning

Give it a container image or a public repo URL and run it — add `severityFilter` if you only care about Critical/High, or `onlyFixable` if you only want actionable results.

# Actor input Schema

## `target` (type: `string`):

Container image reference (e.g. "nginx:1.19") or git repository URL to scan for known CVEs.

## `scanType` (type: `string`):

image or repo. Auto-detected from the target if left empty.

## `severityFilter` (type: `array`):

Only return matches at these severities. Empty = all severities.

## `onlyFixable` (type: `boolean`):

When enabled, skip vulnerabilities with no available fixed version.

## Actor input object example

```json
{
  "target": "python:3.9-slim",
  "scanType": "",
  "severityFilter": [],
  "onlyFixable": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "target": "python:3.9-slim"
};

// Run the Actor and wait for it to finish
const run = await client.actor("ayeeyee/grype-vulnerability-matcher").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "target": "python:3.9-slim" }

# Run the Actor and wait for it to finish
run = client.actor("ayeeyee/grype-vulnerability-matcher").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "target": "python:3.9-slim"
}' |
apify call ayeeyee/grype-vulnerability-matcher --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ayeeyee/grype-vulnerability-matcher",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/q3ujLiAdKCqD6rUeT/builds/bvna1OUoRyOXClGhQ/openapi.json
