# Container Image Vulnerability Scanner (`smg-nextgen-ltd/av-405-container-image-risk-scan`) Actor

Scan public Docker and OCI container images for known vulnerabilities with Grype. Get the immutable image digest, structured vulnerability evidence, and an optional deterministic PASS/BLOCK decision for CI/CD, deployment, and agent workflows

- **URL**: https://apify.com/smg-nextgen-ltd/av-405-container-image-risk-scan.md
- **Developed by:** [SMG NextGen Ventures Ltd](https://apify.com/smg-nextgen-ltd) (community)
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$490.00 / 1,000 completed scans

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/actors/running/actors-in-store.md#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

### Container image vulnerability scanner for CI and agents

Scan a public Docker or OCI container image for known vulnerabilities without installing or maintaining a scanner. AV-405 resolves the requested tag to an immutable image digest, analyzes the image with **Grype 0.104.1**, and returns structured vulnerability evidence plus an optional deterministic **PASS/BLOCK** policy decision.

Use it before deployment, before an autonomous agent executes a third-party container, or anywhere a CI/CD pipeline needs a machine-readable container security gate.

#### Quick start

Input one public image reference and, optionally, the severity threshold that should block it:

```json
{
  "image": "alpine:3.20.0",
  "block_if": "high"
}
```

`block_if` can be `low`, `medium`, `high`, or `critical`. If omitted, AV-405 returns evidence only and leaves the policy decision unset.

A completed `BLOCK` result is still a successfully completed scan. It means one or more known vulnerabilities met or exceeded your requested threshold; it does not mean the Actor failed.

### What you get

Each successful scan returns:

- the requested image reference;
- the immutable image digest actually scanned;
- Grype version and vulnerability-database provenance;
- vulnerability counts by severity;
- fix availability where reported by Grype;
- optional PASS/BLOCK decision and blocking count;
- native structured Grype findings for downstream automation;
- runtime and image-size metadata.

The target container is **never executed**. AV-405 reads image layers for analysis only.

### Common use cases

#### CI/CD container security gate

Call AV-405 before deployment and reject an image automatically when the returned policy decision is `BLOCK`.

#### Agent and tool procurement checks

An autonomous agent can inspect a third-party image before selecting or executing it, using the exact immutable digest and structured vulnerability evidence rather than a human-facing report.

#### Dependency and supplier verification

Use AV-405 as a lightweight independent check when a workflow pulls images from public container registries.

### API and automation

AV-405 is designed for machine use through normal Apify Actor runs and APIs. The input and output are structured JSON, making the Actor suitable for CI jobs, orchestration tools and agent workflows.

Example input:

```json
{
  "image": "nginx:1.27",
  "block_if": "critical"
}
```

A successful response includes `requestedImage`, `scannedImage`, `imageDigest`, `engine`, `summary`, `policy`, and the native Grype `result` object.

### Pricing

**$0.49 per successfully completed scan.**

AV-405 uses pay-per-event pricing. The billable event is `completed-scan`, charged once only after a successful scan result is persisted. Invalid inputs and failed scans do not trigger the completed-scan event.

### Current scope and limits

AV-405 deliberately keeps V0 narrow:

- public registries only;
- Linux `amd64` images;
- no private registry credentials;
- no container execution;
- no remediation service, dashboard, SBOM hosting or continuous monitoring;
- registry preflight is bounded;
- scanner runtime is capped at 240 seconds;
- compressed image-layer processing is bounded;
- output is bounded at 25 MB.

Very large vulnerability result sets can exceed the current output or platform dataset-item limits. In that case the run fails and no `completed-scan` charge is triggered.

PASS means no known finding met the selected blocking threshold in that scan. It is **not** a security certification or a guarantee that the image is vulnerability-free. Vulnerability databases change over time, so results can also change even when the image digest does not.

### Reproducibility and trust

AV-405 records the immutable image digest, scanner version and vulnerability-database metadata with each successful result. The scanner is pinned to **Grype 0.104.1** for this release, and the source release has been regression-tested and benchmarked on the Apify platform.

The service is operated by **SMG NextGen Ventures Ltd** as part of the Autonomous Ventures programme.

# Actor input Schema

## `image` (type: `string`):

One public image reference or sha256 digest; linux/amd64 only. No credentials or local files.

## `block_if` (type: `string`):

BLOCK when a known vulnerability has this severity or greater. Omit for report only.

## Actor input object example

```json
{
  "image": "alpine:3.20.0",
  "block_if": "high"
}
```

# Actor output Schema

## `result` (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 = {
    "image": "alpine:3.20.0",
    "block_if": "high"
};

// Run the Actor and wait for it to finish
const run = await client.actor("smg-nextgen-ltd/av-405-container-image-risk-scan").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 = {
    "image": "alpine:3.20.0",
    "block_if": "high",
}

# Run the Actor and wait for it to finish
run = client.actor("smg-nextgen-ltd/av-405-container-image-risk-scan").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "image": "alpine:3.20.0",
  "block_if": "high"
}' |
apify call smg-nextgen-ltd/av-405-container-image-risk-scan --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,smg-nextgen-ltd/av-405-container-image-risk-scan"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/XHQMV6MwYrvSO4dMK/builds/MJqKn0dqecoTda4NB/openapi.json
