> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hiddenlayer.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Scan Report (V3)

Scan results use the v3 report schema.
The sections below describe the fields you typically use when reading CLI or API output.
For the full schema, see the [Get scan results](https://dev.hiddenlayer.ai/api/scanning-and-analysis/model-scanner/model-scanner/model-scanner-saas/get_scan_results) API in the HiddenLayer Developer Portal (Console login required). For a response without file-level results, see [Get scan result summary](https://dev.hiddenlayer.ai/api/scanning-and-analysis/model-scanner/model-scanner/model-scanner-saas/get_scan_result_summary).

## Report structure

| Section | Description |
| - | - |
| `scan_id`, `status`, `start_time`, `end_time`, `version`, `$schema_version` | Scan identity, lifecycle status (`pending`, `running`, `done`, `failed`, `canceled`), timing, and schema/scanner versions. |
| `inventory` | Model identity and scan request context (name, version, source, requested location, origin, provider details when available). |
| `intelligence` | Optional model intelligence such as country of origin, licenses, and usage policies. |
| `summary` | Aggregate finding counts, threat classifications when available, threat level, and scan coverage. Prefer these fields over deprecated top-level duplicates such as `detection_count` or `severity`. |
| `compliance` | Optional compliance evaluation status (`COMPLIANT` / `NONCOMPLIANT`) and related rule set metadata. |
| `file_results` | Per-file scan details, hashes, file type metadata, detections, advisories, and scan errors. |

Product documentation uses **threat level** for the rating exposed by API fields such as `severity` and `highest_severity`. These field names remain unchanged.

## Understanding scan results

Use the scan's `summary` to understand its findings, threat classifications, and coverage. The newer threat-summary fields described below are available in supported API responses; CLI field availability depends on the scanner version. See [CLI and API availability](#cli-and-api-availability). Scan status and policy compliance describe separate outcomes: whether scanning finished and whether the result satisfies the configured policy.

### Findings

A finding appears in a file's `detections` or `advisories` collection. The scanner determines which collection contains the finding; `threat_type` does not determine its placement. Findings with `threat_type: "vulnerable"` can appear in either collection, so check both when looking for vulnerabilities. For the meaning of category, threat type, and threat level, see [Finding Classification](https://docs.hiddenlayer.ai/docs/products/supply-chain/scan-results/finding_classification.md). This page explains how those values are represented and summarized in a report.

| Field | Meaning |
| - | - |
| `summary.findings_count` | Total findings: detections plus advisories. |
| `summary.detection_count` | Number of detections, excluding advisories. |
| `summary.advisory_count` | Number of advisories, excluding detections. This field can be omitted when the count is zero. |

Counts represent findings, not distinct files. A scan can have zero detections and still have advisories, including vulnerabilities.

### Threat classification

`summary.top_threat_type` selects the highest-priority classification present in the scan. Its priority order is independent of threat level:

`malicious` → `suspicious` → `unclassified` → `vulnerable` → `advisory` → `none`

See [Threat types](https://docs.hiddenlayer.ai/docs/products/supply-chain/scan-results/finding_classification.md#threat-types) for the four finding classifications. Two additional values describe report state:

* `unclassified`: a detection has a missing or unrecognized threat type, such as one produced before threat classification was available.
* `none`: the scan completed without findings. This does not establish that every file was successfully analyzed. It is not a group in `summary.threat_types`.

Advisories with missing or unrecognized threat types are grouped as `advisory`.

`summary.threat_types` provides a breakdown keyed by classification. Only groups containing findings are included; `none` is not a breakdown group. Each group contains:

* `count`: number of findings in the group.
* `highest_severity`: highest threat level within the group (`critical`, `high`, `medium`, or `low`), omitted if no finding has a ranked threat level.
* `categories`: unique, nonempty finding categories, when available.
* `mitre_atlas`: unique MITRE ATLAS tactic/technique pairs, when available.

For example, a scan can have a malicious detection with a Low threat level and a vulnerability advisory with a High threat level. Its top threat type is still `malicious`, while the vulnerability group's highest threat level is `high`:

```json theme={null}
{
  "summary": {
    "detection_count": 1,
    "advisory_count": 1,
    "findings_count": 2,
    "top_threat_type": "malicious",
    "highest_severity": "low",
    "threat_types": {
      "malicious": { "count": 1, "highest_severity": "low" },
      "vulnerable": { "count": 1, "highest_severity": "high" }
    }
  }
}
```

This is a summary excerpt, not a complete scan report.

### Scan threat level

`summary.highest_severity` is the legacy, detection-only threat level summary. It excludes advisories, even when an advisory has a threat level. Prefer `summary.threat_types` for threat level across both detections and advisories. The Console's threat level badges represent these values:

| `summary.highest_severity` | Console | Meaning |
| - | - | - |
| `critical` | Critical | At least one detection, the most severe being critical. |
| `high` | High | At least one detection, the most severe being high. |
| `medium` | Medium | At least one detection, the most severe being medium. |
| `low` | Low | At least one detection, the most severe being low. |
| `none` | None | Known file types were recognized and no detection threat level was found. Advisories can still be present. |
| `unknown` | Unknown | No detection threat level or known-file baseline was available, for example when only unknown file types were scanned. |

The older `summary.severity` and top-level `severity` fields are deprecated and use `safe` in place of `none`. Neither `none` nor `safe` means that there are no advisories or that the scan is policy-compliant.

### Scan status and coverage

| Field | Meaning |
| - | - |
| `status` | Scan lifecycle: `pending`, `running`, `done`, `failed`, or `canceled`. Read findings together with this status. |
| `summary.file_count` | Total file results counted by the scan, including files that may have failed or have unknown types. It is not a count of successfully analyzed files. |
| `summary.files_with_detections_count` | Number of files containing detections. Files with only advisories do not contribute. |
| `summary.files_failed_to_scan` | Number of files whose scan failed. |
| `summary.unknown_files` | Number of files reported with an unknown file type. |

A `done` scan or a zero finding count does not guarantee complete coverage. Check failed and unknown file counts before interpreting the absence of findings.

### Policy outcome

`compliance.status` is `COMPLIANT` or `NONCOMPLIANT`, according to the policy evaluation. It is separate from threat type and threat level: findings do not by themselves determine the policy outcome. `compliance.evaluated_at` records when that evaluation occurred. An absent compliance result does not mean `COMPLIANT`.

### CLI and API availability

#### CLI output

CLI v3 JSON is generated locally from the scan results. Its summary is computed even when the scan fails, so read counts together with `status`. The API completion rules below do not apply to locally generated CLI summaries.

Scanner versions using the earlier v3 summary format provide detection/advisory counts and `highest_severity`, but do not emit `top_threat_type`, `findings_count`, or `threat_types`. Do not expect these newer fields solely because the output uses the v3 schema. For these versions, detections plus advisories give the total finding count; an omitted `advisory_count` represents zero. Platform feature availability does not change an installed CLI's output format.

Policy compliance is a platform evaluation; local CLI output should not be assumed to contain it. After submitting results, retrieve the API report to read any available compliance result.

#### Enable threat-classification output

For scanner builds that support VRT output, set `HL_MODEL_SCANNER_VRT_OUTPUT=true` in the scanner process environment. In Docker, add the following option to your existing `docker run` command **before the image name**:

```sh theme={null}
-e HL_MODEL_SCANNER_VRT_OUTPUT=true
```

In builds with the opt-in feature, the default is `false`. Enabling it includes finding threat types, richer advisory metadata, and the summary's threat-type breakdown. It also enables threat-type CLI flags. Older builds may not support this setting; setting an environment variable does not upgrade the scanner.

This controls output, not rule definitions. It does not change a detection's threat level or category. Use a scanner build containing the updated rule metadata to obtain current category and threat level values.

#### API responses

Request `include_threat_types=true` to include `summary.top_threat_type`, `summary.findings_count`, and `summary.threat_types` when available. The deployment's threat-classification feature must also be enabled; without the query parameter or feature, these fields are omitted. Older stored reports can lack the findings count and breakdown even after that feature is enabled.

* `findings_count` and `threat_types` are populated for scans with `status: done`; they are omitted for other statuses.
* `top_threat_type` can describe findings received before completion. With no findings, it is `none` only for a completed scan; otherwise it is omitted.
* A completed scan with no findings has `findings_count: 0` when the newer summary is available. Its empty `threat_types` breakdown is omitted.
* A missing new field means the value is unavailable, not zero or `none`. Missing optional category, MITRE ATLAS, or threat level fields within a group do not negate that group's finding count.

Use the `summary` counts instead of the deprecated top-level `detection_count`, `file_count`, and `files_with_detections_count` fields.

### Other summary fields

| Field | Description |
| - | - |
| `summary.detection_categories` | Unique detection categories found in the scan. |
| `summary.advisory_categories` | Unique advisory categories found in the scan. |
| `summary.mitre_atlas` | Deduplicated MITRE ATLAS tactic/technique pairs across all detections. |
| `summary.referenced_models` | Deduplicated list of external artifact URIs (typically `ngc://...?file=...`) parsed from a NIM container's `model_manifest.yaml`. These URIs are informational; the referenced files are **not** scanned automatically. [Download artifacts with the NGC CLI](https://docs.hiddenlayer.ai/docs/products/supply-chain/cli/ngc_cli_download.md) and scan them separately. See [NIM Container Scanning](https://docs.hiddenlayer.ai/docs/products/supply-chain/cli/nim_container.md). |

## File results

Each entry in `file_results` describes one scanned file.

| Field | Description |
| - | - |
| `file_instance_id` | Unique ID for the file instance in this scan. |
| `file_location` | Full path or location of the file. |
| `status` | File scan status: `skipped`, `pending`, `running`, `done`, `failed`, or `canceled`. |
| `start_time` / `end_time` / `seen` | Timing for when the file scan started, ended, and was observed. |
| `details.md5` / `details.sha256` / `details.tlsh` | File hashes when available. |
| `details.file_size` / `details.file_size_bytes` | File size in human-readable form and bytes. |
| `details.file_type` | Detected file type (for example, `pickle`, `safetensors`, `keras`). |
| `details.file_type_details` | Format-specific metadata. Contents vary by file type; see [Type-specific evidence](#type-specific-evidence). |
| `detections` | Array of detections for this file. |
| `advisories` | Array of advisories for this file. |
| `file_error` | Error messages returned by the scanner for this file, if any. |

## Detections

Present when a file triggers a detection rule.

| Field | Description |
| - | - |
| `detection_id` | Unique identifier for the detection. |
| `rule_id` | Identifier of the rule that produced the detection (for example, `PICKLE_0055_202408`). |
| `risk` | Legacy classification (`MALICIOUS` or `SUSPICIOUS`) retained in older reports. Current scanner output omits this field. Use `threat_type` when available. |
| `threat_type` | Finding classification, when included in the output. See [Finding Classification](https://docs.hiddenlayer.ai/docs/products/supply-chain/scan-results/finding_classification.md#threat-types). |
| `category` | Vulnerability category (for example, Arbitrary Code Execution). |
| `description` | Why the detection was raised. |
| `likelihood` / `impact` / `severity` | Likelihood, impact, and threat level (`critical`, `high`, `medium`, `low`) for the finding. |
| `mitre_atlas` | Related MITRE ATLAS tactics and techniques. |
| `owasp` | Related OWASP labels. |
| `cve` / `cwe` / `cwe_href` | Related CVE and CWE identifiers, plus a CWE URL when available. |
| `technical_blog_href` / `technical_blog_hrefs` | Links to HiddenLayer technical blog posts related to the finding. |
| `rule_details` | Optional rule lifecycle notes (for example, deprecated or superseded). |

## Advisories

The `advisories` collection contains findings emitted as advisories by the scanner. An advisory can carry a threat type and threat level; its collection does not imply `threat_type: "advisory"`. See [Finding Classification](https://docs.hiddenlayer.ai/docs/products/supply-chain/scan-results/finding_classification.md) for their meaning.

| Field | Description |
| - | - |
| `advisory_id` | Unique identifier for the advisory. |
| `rule_id` | Identifier of the rule that produced the advisory. |
| `category` | Advisory category (for example, Model Reference). |
| `description` | Why the advisory was raised. |

## Type-specific evidence

`file_results[].details.file_type_details` includes extra fields for some model formats.
Use these fields to understand format metadata that often contextualizes detections.

| File type | Evidence fields | What they tell you |
| - | - | - |
| GGUF | `subtype` | Format subtype metadata for the GGUF file. |
| Keras | `subtype`, `keras_version`, `pickle_modules`, `keras_class_name`, `keras_date_saved_at`, `keras_module` | Keras version and module/class metadata. `pickle_modules` lists embedded pickle modules that can relate to arbitrary code execution findings. |
| NumPy | `subtype`, `numpy_arrays`, `numpy_shape` | Number of arrays and their shapes in the NumPy file. |
| RDS | `subtype`, `rds_encoding`, `rds_min_reader_version`, `rds_version`, `rds_writer_version` | R serialization version and encoding metadata for the RDS file. |
| Pickle | `subtype`, `pickle_modules`, `pickle_header` (when present) | Libraries/modules referenced by the pickle and header metadata such as pickle version. Useful when reviewing code-execution related detections. |

> [!NOTE]
>
> Not every file type populates `file_type_details`. Empty objects are normal for formats that do not expose additional metadata.

## Related guides

* [Finding Classification](https://docs.hiddenlayer.ai/docs/products/supply-chain/scan-results/finding_classification.md) explains categories, threat types, and threat levels.
* [AI Bill of Materials (AIBOM)](https://docs.hiddenlayer.ai/docs/products/supply-chain/aibom/overview.md) describes the model inventory output and its CycloneDX representation.
* [Remediation Guide](https://docs.hiddenlayer.ai/docs/products/supply-chain/remediation-guide/overview.md) provides category-specific response guidance.
