Scan images with twistcli

Scan container images with twistcli.

Command reference

The
twistcli
command has several subcommands. Use the
twistcli images scan
subcommand to invoke the scanner.

NAME

twistcli images scan
 — Scan an image for vulnerabilities and compliance issues. The image must reside on the system where twistcli runs. If not, retrieve the image with
docker pull
before scanning it. Twistcli does not pull images for you.

SYNOPSIS

twistcli images scan [OPTIONS] [IMAGE]

DESCRIPTION

The
twistcli images scan
function collects information about the packages and binaries in the container image, and then sends it to Console for analysis.
Data collected by twistcli includes:
  • Packages in the image.
  • Files installed by each package.
  • Hashes for files in the image.
After Console analyzes the image for vulnerabilities,
twistcli
:
  • Outputs a summary report.
  • Exits with a pass or fail return value.
Scan results can be retrieved in JSON format from the Console using API calls.
To specify an image to scan, use either the image ID, or repository name and tag. The image should be present on the system, having either been built or pulled there. If a repository is specified without a tag,
twistcli
looks for an image tagged
latest
.
When invoking
twistcli
, the last parameter should be the image to scan. If you list options after the image, they will be ignored.

OPTIONS

  • --address
    URI
    --
    Required. Complete URI for Console, including the protocol and port. Only the HTTPS protocol is supported. By default, Console listens to HTTPS on port 8083, although your administrator can configure Console to listen on a different port.
  • -u
    ,
    --user
    USERNAME
    --
    Username to access Console. If not provided, the
    TWISTLOCK_USER
    environment variable will be used if defined, or "admin" is used as the default.
  • -p
    ,
    --password
    PASSWORD
    --
    Password for the user specified with
    -u
    ,
    --user
    . If not specified on the command-line, the
    TWISTLOCK_PASSWORD
    environment variable will be used if defined, or otherwise will prompt for the user’s password before the scan runs.
  • --project
    PROJECT NAME
    --
    Interface with a specific supervisor Console to retrieve policy and publish results.
    Example: --project "Tenant Console"
  • --output-file
    FILENAME
    --
    Write the results of the scan to a file in JSON format.
    Example: --output-file examplescan
  • --ci
    --
    Evaluate the CI Policy and store results in the Console.
  • --details
    --
    Show all vulnerability details.
  • --containerized
    --
    Run the scan from inside the container.
  • --custom-labels
    --
    Include the image custom labels in the results.
  • --docker-address
    DOCKER_CLIENT_ADDRESS
    --
    Docker daemon listening address (default:
    unix:///var/run/docker.sock
    ) [$DOCKER_CLIENT_ADDRESS].
  • --docker-tlscacert
    PATH
    --
    Path to Docker client CA certificate.
  • --docker-tlscert
    PATH
    --
    Path to Docker client Client certificate.
  • --docker-tlskey
    PATH
    --
    Path to Docker client Client private key.
  • --tlscacert
    PATH
    --
    Path to Prisma Cloud CA certificate file. If no CA certificate is specified, the connection to Console is insecure.
  • --podman-path
    PATH
    --
    Forces twistcli to use Podman. To use the default installation path, set as
    podman
    . Otherwise, provide the appropriate path.
  • --include-js-dependencies
    --
    Include javascript package dependencies.
  • --token
    TOKEN
    --
    Token to use for Prisma Cloud Console authentication. Tokens can be retrieved from the API endpoint
    api/v1/authenticate
    or from the
    Manage > Authenticate > User Certificates
    page in Console.

RETURN VALUE

The exit code is 0 if
twistcli
finds no vulnerabilities or compliance issues. Otherwise, the exit code is 1.
The criteria for passing or failing a scan is determined by the CI vulnerability and compliance policies set in Console. The default CI vulnerability policy alerts on all CVEs detected. The default CI compliance policy alerts on all critical and high compliance issues.
There are two reasons why
twistcli
might return an exit code of 1.
  • The scan failed because the scanner found issues that violate your CI policy.
  • Twistcli failed to run due to an error.
Although the return value is ambiguous — you cannot determine the exact reason for the failure by just examining the return value — this setup supports automation. From an automation process perspective, you expect that the entire flow will work. If you scan an image, with or without a threshold, either it works or it does not work. If it fails, for whatever reason, you want to fail everything because there is a problem.

Scan results

Scan reports can viewed in Prisma Cloud Console, but only when you pass the
--ci
flag to
twistcli
. This flag is designed to minimize clutter in the Console UI, since many people might be using
twistcli
for scanning, but everyone will need to share it with the larger team in Console. To view scan reports in Console, go to
Monitor > Vulnerabilities > Images > CI
or
Monitor > Compliance > Images > CI
.
You can also retrieve scan reports in JSON format using the Prisma Cloud API. The following example curl command calls the API with basic auth. You’ll need to apply some filtering with tools like
jq
to extract specific reports from the response. For more information on accessing the API, see Accessing the API.
$ curl \ -u <USER> \ -o scan_results.json \ 'https://<COMPUTE_CONSOLE>/api/v1/scans'
If you are using assigned collections, then specify the collection in a query parameter:
$ curl \ -u <USER> \ -o scan_results.json \ 'https://<COMPUTE_CONSOLE>/api/v1/scans?collections=<COLLECTION_NAME>'

Output

The twistcli tool can output scan results to several places:
  • stdout.
  • File. Scan results are saved in JSON format.
  • Console. Scan results can be viewed under
    Monitor > Vulnerabilities > Twistcli Scans
    .
You can simultaneously output scan results to a file and to Console by passing the appropriate flags to twistcli. By default, twistcli writes scan results to stdout.
To write scan results to stdout in tabular format, pass the
--details
flag to twistcli.
To write scan results to a file in JSON format, pass the
--output-file
flag to twistcli.
To publish scan results to Console, pass the
--ci
flag to twistcli.

API

The API returns comprehensive information for each scan report, including the full list of packages, files, and vulnerabilities. For more information, see the API documentation.

Running scans from inside the container

By default, twistcli is run from outside the container image. In some cases, you might need to copy twistcli to the container’s file system, and then run the scanner from inside the container. One reason you might want to run the scanner this way is when your build platform doesn’t give you access to the Docker socket. CodeFresh is an example of such a platform.
There are some shortcomings with this scanning from inside a container, so you should only use this approach when no other approach is viable. The shortcomings are:
  • Automating the scan in your continuous integration pipeline is more difficult.
  • Image metadata, such as registry, repository, and tag aren’t available in the scan report. When twistcli is run from outside the container, this information is retrieved from the Docker API.
  • The image ID isn’t available in the scan report because it cannot be determined when the scan is run from inside a container.
  • The scan report won’t show a layer-by-layer analysis of the image.

Usage

When running the scanner from inside a container, you need to properly orient it by passing it the
--containerized
flag. There are a couple of ways to run twistcli with the
--containerized
flag: build-time and run-time.
For security reasons, Prisma Cloud recommends that you create a user with the
CI User
role for running scans.

Build-time invocation

After building an image, run it. Mount the host directory that holds the twistcli binary, pass the Prisma Cloud Console user credentials to the container with environment variables, then run the scanner inside the container. The <REPORT_ID> is a user defined string that uniquely identifies the scan report in the Console UI.
$ docker run \ -v /PATH/TO/TWISTCLIDIR:/tools \ -e TW_USER=<USER> \ -e TW_PASS=<PASSWORD> \ -e TW_CONSOLE=<CONSOLE_ADDR> \ --entrypoint="" \ <IMAGE> \ /tools/twistcli images scan \ --containerized \ --details \ --user=$TW_USER \ --password=$TW_PASS \ --address=$TW_CONSOLE \ <REPORT_ID>
Rather than username and password, twistcli can also authenticate to Console with a token. Your API token can be found in Console under
Manage > Authentication > User Certificates > API token
. For security reasons, API tokens expire.
$ docker run \ -v /PATH/TO/TWISTCLI_DIR:/tools \ -e TW_TOKEN=<TOKEN> \ -e TW_CONSOLE=<CONSOLE_ADDR> \ --entrypoint="" \ <IMAGE> \ /tools/twistcli images scan \ --containerized \ --details \ --token=$TW_TOKEN \ --address=$TW_CONSOLE \ <REPORT_ID>

Run-time invocation

If you have access to the orchestrator, you can exec into the running container to run the twistcli scanner. Alternatively, you could SSH to the container. Once you have a shell on the running container, invoke the scanner:
$ ./twistcli images scan \ --address=<COMPUTE_CONSOLE> \ --user=<USER> \ --password=<PASSWORD> \ --containerized \ <REPORT_ID>
To invoke the scanner with a token:
$ ./twistcli images scan \ --address=<COMPUTE_CONSOLE> \ --token=<TOKEN> \ --containerized \ <REPORT_ID>

Simple scan

Scan an image with
twistcli
and print the summary report to stdout.
  1. Scan an image named myimage/latest.
    $ twistcli images scan \ -u api \ -p api \ --address <COMPUTE_CONSOLE> \ myimage/latest
    Command output:
    simple_scan.png

Scan with detailed report

You can have
twistcli
generate a detailed report for each scan. The following procedure shows you how to scan an image with
twistcli
, and then retrieve the results from Console.
Assume that the username and password for Console is api/api.
  1. Scan an image named ian/app:1.0.
    $ twistcli images scan \ -u api \ -p api \ --address <COMPUTE_CONSOLE> \ --details \ test/myapp:latest
    Sample command output (results have been truncated):
    detailed_scan.png
  2. This generates output to stdout with the result of your scan. If you need to retrieve the results of your scan in JSON format, this can be done using the API.
    1. You will be making API calls. For more information, refer to Accessing the API.
    2. Call the API with authentication (demonstrated here using Basic authentication) to fetch the results of the scan.
      $ curl \ -o scan_results.json \ -H 'Authorization: Basic YXBpOmFwaQ==' \ 'https://<COMPUTE_CONSOLE>/api/v1/scans?search={image name}&limit=1&reverse=true&type=twistcli'
    3. Format the scan results into human-readable format.
      $ python -m json.tool scan_results.json > scan_results_pp.json
    4. Inspect the results.
      Open
      scan_results_pp.json
      to view the results. Vulnerability information can be found in the list
      cveVulnerabilities
      , while compliance results can be found in the list
      complianceVulnerabilities
      to find the start of the list of vulnerabilities.
      { { "_id": "5bd72249a0dd0e12f9b17b22", "hostname": "jacob-repro-2", "info": { "allCompliance": {}, "complianceDistribution": { "critical": 0, "high": 1, "low": 0, "medium": 0, "total": 1 }, "complianceVulnerabilities": [ { "cause": "", "cve": "", "cvss": 0, "description": "", "exploit": "", "id": 41, "layerTime": 0, "link": "", "packageName": "", "packageVersion": "", "published": 0, "riskFactors": null, "severity": "high", "status": "", "templates": [], "text": "", "title": "(CIS_Docker_CE_v1.1.0 - 4.1) Image should be created with a non-root user", "twistlock": false, "type": "image", "vecStr": "" }, ... ], "cveVulnerabilities": [ { "cause": "", "cve": "CVE-2018-6485", "cvss": 9.8, "description": "An integer overflow in the implementation of the posix_memalign in memalign functions in the GNU C Library (aka glibc or libc6) 2.26 and earlier could cause these functions to return a pointer to a heap area that is too small, potentially leading to heap corruption.", "exploit": "", "id": 46, "layerTime": 1539910074, "link": "https://people.canonical.com/~ubuntu-security/cve/2018/CVE-2018-6485", "packageName": "libc6 (glibc)", "packageVersion": "2.27-3ubuntu1", "published": 1517495340, "riskFactors": { "Attack complexity: low": {}, "Attack vector: network": {}, "Medium severity": {}, "Recent vulnerability": {} }, "severity": "medium", "status": "needed", "templates": [], "text": "", "title": "", "twistlock": false, "type": "image", "vecStr": "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, ... ], ...

Scan images built with Jenkins in an OpenShift environment

If you are building and deploying images on OpenShift Container Platform (OCP), and you are utilizing their Jenkins infrastructure, then invoke a scan with the
twistcli hosts scan
command, not the
twistcli images scan
command.
You can scan images generated by Jenkins with the OpenShift plugin by invoking
twistcli
from a build hook. Build hooks let you inject custom logic into the build process. They run your commands inside a temporary container instantiated from build output image. Build hooks are called when the last layer of the image has been committed, but before the image is pushed to a registry. An non-zero exit code fails the build. A zero exit code passes the build, and allows it to proceed to the next step.
To call
twistcli
from a build hook:
  1. Download
    twistcli
    into your build environment. Depending on your build strategy, one option is to download it as an external artifact using a
    save-artifacts
    S2I script.
  2. In your
    BuildConfig
    , call
    twistcli
    as a
    script
    from the
    postCommit
    hook.
    $ twistcli hosts scan \ --user <USER> \ --password <PASSWORD> \ --address <COMPUTE_CONSOLE> \ --skip-docker \ --include-3rd-party
    Where the
    --skip-docker
    option skips all Docker compliance checks such as the Docker daemon configuration and the
    --include-3rd-party
    option scans application-specific files such as Java JARs.

Scan images when the Docker socket isn’t in the default location

The twistcli scanner uses the Docker API, so it must be able to access the socket where the Docker daemon listens. If your Docker socket isn’t in the default location, use the
--docker-address
option to tell twistcli where to find it:
  • --docker-address
    PATH
    --
    Path to the Docker socket. By default, twistcli looks for the Docker socket in
    unix:///var/run/docker.sock
    .
    $ ./twistcli images scan \ --address=<COMPUTE_CONSOLE> \ --user=<TW_USER> \ --password=<TW_PASSWORD> \ --docker-address unix:///<PATH/TO>/docker.sock \ <IMAGE>

Scan Podman/CRI images

Podman is a daemon-less container engine for developing, managing, and running OCI containers on Linux. The twistcli tool can use the preinstalled Podman binary to scan CRI images.
  • --podman-path
    PATH
    --
    Forces twistcli to use Podman. To use the default installation path, specify
    podman
    . Otherwise, provide the appropriate path.
    $ ./twistcli images scan \ --address=<COMPUTE_CONSOLE> \ --user=<TW_USER> \ --password=<TW_PASSWORD> \ --podman-path podman

Recommended For You