The On-Demand Scanning API lets you scan images stored locally on your computer
or remotely in Artifact Registry. This gives you granular
control over the containers you want to scan for vulnerabilities. You can use
On-Demand Scanning to scan images in your CI/CD pipeline before deciding whether to
store them in a registry. See the [Pricing page](https://cloud.google.com/artifact-analysis/pricing#ods)
for pricing information.

This page describes how to manually scan container images with On-Demand Scanning.

> [!NOTE]
> **Note:** On-Demand Scanning runs in a Linux environment and in macOS. On-Demand Scanning is not supported on Windows.

## Before you begin

1. Add the **local-extract** component to your Google Cloud CLI
   installation

   **Using the Google Cloud CLI Component Manager**

   The component manager will prompt you to install the required components the first time you
   run the scanning command.

   **Using your system package manager**
   - For Debian/Ubuntu:

     ```bash
     sudo apt install google-cloud-sdk-local-extract
         
     ```
   - For Red Hat/Fedora/CentOS:

     ```bash
     sudo dnf install google-cloud-sdk-local-extract
         
     ```

     Alternatively, you can replace `dnf` with `yum` in
     the previous command.
2. [Grant the IAM role](https://docs.cloud.google.com/iam/docs/granting-changing-revoking-access) **On-Demand Scanning Admin** to the user or service account that you are going to use with On-Demand Scanning. If you are using the owner account of the project to run the scans, you can skip this step.

### Required roles


To get the permissions that
you need to View package scan results,

ask your administrator to grant you the
following IAM roles on the project:

- [Container Scanner Service Agent](https://docs.cloud.google.com/iam/docs/roles-permissions/containerscanning#containerscanning.ServiceAgent) (`roles/containerscanning.ServiceAgent`)
- [Container Analysis Occurrences Viewer](https://docs.cloud.google.com/iam/docs/roles-permissions/containeranalysis#containeranalysis.occurrences.viewer) (`roles/containeranalysis.occurrences.viewer`)
- [Container Analysis Notes Viewer](https://docs.cloud.google.com/iam/docs/roles-permissions/containeranalysis#containeranalysis.notes.viewer) (`roles/containeranalysis.notes.viewer`)
- [Artifact Registry Reader](https://docs.cloud.google.com/iam/docs/roles-permissions/artifactregistry#artifactregistry.reader) (`roles/artifactregistry.reader`)


For more information about granting roles, see [Manage access to projects, folders, and organizations](https://docs.cloud.google.com/iam/docs/granting-changing-revoking-access).


You might also be able to get
the required permissions through [custom
roles](https://docs.cloud.google.com/iam/docs/creating-custom-roles) or other [predefined
roles](https://docs.cloud.google.com/iam/docs/roles-overview#predefined).

## Scanning a container image

- Local scan:

      gcloud artifacts docker images scan IMAGE_URI \
          [--location=(us,europe,asia)] [--async]

  For a local image, use one of the following formats for the
  <var translate="no">IMAGE_URI</var>:
  - `REPOSITORY:TAG`
  - `REPOSITORY`
- Remote scan:

      gcloud artifacts docker images scan IMAGE_URI \
          --remote [--location=(us,europe,asia)] [--async]

  For a remote image, use one of the following formats for the
  <var translate="no">IMAGE_URI</var>:
  - `HOSTNAME/PROJECT_ID/REPOSITORY_ID/IMAGE_ID@sha256:HASH`
  - `HOSTNAME/PROJECT_ID/REPOSITORY_ID/IMAGE_ID:HASH`
  - `HOSTNAME/PROJECT_ID/REPOSITORY_ID/IMAGE_ID`
  - `HOSTNAME/PROJECT_ID/IMAGE_ID@sha256:HASH`
  - `HOSTNAME/PROJECT_ID/IMAGE_ID:HASH`
  - `HOSTNAME/PROJECT_ID/IMAGE_ID`

  For images in Artifact Registry the <var translate="no">IMAGE_URI</var> must include the
  `REPOSITORY_ID`.

For both local and remote scans, you can use the following optional flags:

- `--location` is a flag to manually select the multi-region where the
  scanning takes place. Choosing a multi-region closer to your physical
  location minimizes latency. The available locations are: `us`, `europe` and
  `asia`. The default location is `us`.

- `--async` is a flag to run the scanning process asynchronously.
  If you omit this flag your terminal will block until the scanning process is
  complete.

### Synchronous scanning

The following example shows the output of a synchronous scan, without the
`--async` flag:

```
$ gcloud artifacts docker images scan ubuntu:latest


✓ Scanning container image
  ✓ Locally extracting packages and versions from local container image
  ✓ Remotely initiating analysis of packages and versions
  ✓ Waiting for analysis operation to complete [projects/my-project/locations/us/operations/87d2e137-1d1c-4790-8e5e-daf6c96ae7d7]
Done.
done: true
metadata:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesMetadata
  createTime: '2021-01-05T23:03:04.185261Z'
  resourceUri: ubuntu:latest
name: projects/my-project/locations/us/operations/87d2e137-1d1c-4790-8e5e-daf6c96ae7d7
response:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesResponse
  scan: projects/my-project/locations/us/scans/2fe2bfb8-f0c5-4dd6-a8c8-38961869767a
```

Use the scan name to [retrieve the vulnerability results](https://docs.cloud.google.com/artifact-analysis/docs/scan-os-on-demand#retrieve).
The scan name is the value of `scan` in the last line of the output message.

### Asynchronous scanning

The following example shows the output of performing an asynchronous scan:

```
$ gcloud artifacts docker images scan ubuntu:latest --async


✓ Scanning container image
  ✓ Locally extracting packages and versions from local container image
  ✓ Remotely initiating analysis of packages and versions
Done.
Check operation [projects/cloud-project/locations/us/operations/2e1a6b1f-16e5-4427-ac86-72c998a3dd16] for status.
metadata:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesMetadata
  createTime: '2021-01-05T23:04:54.393510Z'
  resourceUri: ubuntu:latest
name: projects/my-project/locations/us/operations/2e1a6b1f-16e5-4427-ac86-72c998a3dd16
```

This launches a long-running operation and returns its ID without blocking your
terminal. Use the operation ID, the value of `name` in the last line of the
output message, to [poll the operation](https://docs.cloud.google.com/artifact-analysis/docs/scan-os-on-demand#polling-lro).

### Polling the long-running operation

Use the operation ID, from the output of they asynchronous scanning command, to
check the operation status.

    gcloud artifacts docker images get-operation LRO_ID

Where <var translate="no">LRO_ID</var> is the long-running operation ID.

Continuing with the example of the [asynchronous scanning section](https://docs.cloud.google.com/artifact-analysis/docs/scan-os-on-demand#async-ods),
to check the status of the operation:

```
$ gcloud artifacts docker images get-operation \
  projects/cloud-project/locations/us/operations/2e1a6b1f-16e5-4427-ac86-72c998a3dd16

done: true
metadata:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesMetadata
  createTime: '2021-01-05T23:04:54.393510Z'
  resourceUri: ubuntu:latest
name: projects/my-project/locations/us/operations/2e1a6b1f-16e5-4427-ac86-72c998a3dd16
response:
  '@type': type.googleapis.com/google.cloud.ondemandscanning.v1.AnalyzePackagesResponse
  scan: projects/my-project/locations/us/scans/2fe2bfb8-f0c5-4dd6-a8c8-38961869767a
```

If the output includes the line `done: true`, the scanning operation is
completed. Use the scan name to retrieve the vulnerability results
The name is the value of `scan` in the last line of the output message

## Retrieve the scan results

To retrieve the scanning results after the scanning operation is completed, use
the following command:

    gcloud artifacts docker images list-vulnerabilities SCAN_NAME [--limit=X]

Where:

- <var translate="no">SCAN_NAME</var> is the scan name. You can find it at the bottom of the output when you [poll the long-running operation](https://docs.cloud.google.com/artifact-analysis/docs/scan-os-on-demand#polling-lro), after the scanning is finished.
- `--limit=X` is an optional flag that limits the number of occurrences shown in the output. `X` is a numeric value.

For example:

```
gcloud artifacts docker images list-vulnerabilities \
projects/my-project/locations/us/scans/2fe2bfb8-f0c5-4dd6-a8c8-38961869767a

createTime: '2021-01-05T23:05:42.956227Z'
kind: VULNERABILITY
name: projects/my-project/locations/us/occurrences/f82a1efd-a261-4973-acbd-f9854d8b8135
noteName: projects/goog-vulnz/notes/CVE-2018-1000654
resourceUri: ubuntu:latest
updateTime: '2021-01-05T23:05:42.956227Z'
vulnerability:
  cvssScore: 7.1
  cvssv3:
    attackComplexity: ATTACK_COMPLEXITY_LOW
    attackVector: ATTACK_VECTOR_NETWORK
    availabilityImpact: IMPACT_HIGH
    baseScore: 7.2
    confidentialityImpact: IMPACT_HIGH
    exploitabilityScore: 1.2
    impactScore: 5.9
    integrityImpact: IMPACT_HIGH
    privilegesRequired: PRIVILEGES_REQUIRED_HIGH
    scope: SCOPE_UNCHANGED
    userInteraction: USER_INTERACTION_NONE
  effectiveSeverity: MEDIUM
```

The output of this command is a
[list of occurrences in the Grafeas format](https://docs.cloud.google.com/artifact-analysis/docs/reference/rest/v1/projects.locations.occurrences#Occurrence.VulnerabilityOccurrence).
In this case, it shows a medium-severity vulnerability found in the image.

The scanning results are available for 48 hours after the scanning operation is
completed.

## What's next

- [Use the On-Demand Scanning API in your Cloud Build pipeline](https://docs.cloud.google.com/artifact-analysis/docs/ods-cloudbuild).
- [Use Artifact Analysis](https://docs.cloud.google.com/artifact-analysis/docs/container-scanning-overview) to scan and continuously update vulnerability information for your images stored in Artifact Registry.