Skip to content

Get artifact vulnerability reports

We can fetch the vulnerability report(s) for an artifact using get_artifact_vulnerability_reports. It returns a dict of HarborVulnerabilityReport objects indexed by MIME type. If no reports are found, the dict will be empty.

A HarborVulnerabilityReport is more comprehensive than the NativeReportSummary returned by get_artifact(..., with_scan_overview=True). It contains detailed information about the vulnerabilities found in the artifact.

Example

import asyncio
from harborapi import HarborAsyncClient

client = HarborAsyncClient(...)


async def main() -> None:
    report = await client.get_artifact_vulnerabilities(
        "library",
        "hello-world",
        "latest",
    )
    for mime_type, report in reports.items():
        print(mime_type)
        for vulnerability in report.vulnerabilities:
            print(
                vulnerability.id,
                vulnerability.severity,
                vulnerability.package,
            )

asyncio.run(main())

The dict returned by the method is a FirstDict object, which is a subclass of Python's built-in dict that provides a first() method to get the first value in the dict. We often only have a single vulnerability report for an artifact, so we can use the first() method to get the report directly:

report = await client.get_artifact_vulnerabilities(
    "library",
    "hello-world",
    "latest",
)
report = report.first()

Filtering vulnerabilities

The HarborVulnerabilityReport class provides a simple interface for filtering the vulnerabilities by severity. For example, if we only want to see vulnerabilities with a Severity of critical we can access the HarborVulnerabilityReport.critical attribute, which is a property that returns a list of VulnerabilityItem objects:

for vulnerability in report.critical:
    print(vulnerability.id)

Similarly, we can also get low, medium, and high severity vulnerabilities, as well as fixable and unfixable vulnerabilities:

for vulnerability in report.low:...
for vulnerability in report.medium:...
for vulnerability in report.high:...
for vulnerability in report.critical: ...
for vulnerability in report.fixable: ...
for vulnerability in report.unfixable: ...

Each VulnerabilityItem contains information about a vulnerability that affects the artifact. This includes information such as id, severity, package, version, description, links and more.

for vulnerability in report.vulnerabilities:
    print(
        vulnerability.id,
        vulnerability.severity,
        vulnerability.package,
        vulnerability.description,
        vulnerability.version,
    )
    if vulnerability.links:
        for link in vulnerability.links:
            print("\t", link)

The mime_type parameter

We can pass in a list of MIME types or a single MIME type to the mime_type parameter. The returned dict will only contain the vulnerability reports for the specified MIME types.

reports = await client.get_artifact_vulnerabilities(
    ...,
    mime_type=[
        "application/vnd.security.vulnerability.report; version=1.1",
        "application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0",
    ],
)
for mime_type, report in reports.items():
    print(report)

# OR

reports = await client.get_artifact_vulnerabilities(
    ...,
    mime_type="application/vnd.security.vulnerability.report; version=1.1",
)
reports.get("application/vnd.security.vulnerability.report; version=1.1")

Remember, the Artifact might not have a vulnerability report for the specified MIME type. In that case, the dict will be empty.

reports = await client.get_artifact_vulnerabilities(
    ...,
    mime_type=["Lots", "Of", "Mime", "Types"],
)
if not reports:
    print("No vulnerability reports found for the specified MIME types.")