Trivy (tri pronounced like trigger, vy pronounced like envy) is a simple and comprehensive vulnerability scanner for containers. A software vulnerability is a glitch, flaw, or weakness present in the software or in an Operating System. Trivy detects vulnerabilities of OS packages (Alpine, RHEL, CentOS, etc.) and application dependencies (Bundler, Composer, npm, yarn etc.). Trivy is easy to use. Just install the binary and you’re ready to scan. All you need to do for scanning is to specify an image name of the container.



  • Detect comprehensive vulnerabilities
    • OS packages (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, Debian, Ubuntu, Amazon Linux and Distroless)
    • Application dependencies (Bundler, Composer, Pipenv, Poetry, npm, yarn and Cargo)
  • Simple
  • Easy installation
    • apt-get install, yum install and brew install is possible (See Installation)
    • No pre-requisites such as installation of DB, libraries, etc. (The exception is that you need rpm installed to scan images based on RHEL/CentOS. This is automatically included if you use our installers or the Trivy container image. See Vulnerability Detection for background information.)
  • High accuracy
    • Especially Alpine Linux and RHEL/CentOS
    • Other OSes are also high
  • DevSecOps
    • Suitable for CI such as Travis CI, CircleCI, Jenkins, etc.
    • See CI Example

Quick Start

Simply specify an image name (and a tag). The latest tag should be avoided as problems occur with the image cache. See Clear image caches.



For example:

$ trivy python:3.4-alpine


Replace [YOUR_CACHE_DIR] with the cache directory on your machine.

$ docker run --rm -v [YOUR_CACHE_DIR]:/root/.cache/ aquasec/trivy [YOUR_IMAGE_NAME]


Scan an image

Simply specify an image name (and a tag).

$ trivy knqyf263/vuln-image:1.2.3

Filter the vulnerabilities by severities

$ trivy --severity HIGH,CRITICAL ruby:2.3.0

Skip update of vulnerability DB

Trivy always updates its vulnerability database when it starts operating. This is usually fast, as it is a difference update. But if you want to skip even that, use the --skip-update option.

$ trivy --skip-update python:3.4-alpine3.9

Update only specified distributions

By default, Trivy always updates its vulnerability database for all distributions. Use the --only-update option if you want to name specified distributions to update.

$ trivy --only-update alpine,debian python:3.4-alpine3.9
$ trivy --only-update alpine python:3.4-alpine3.9

Only download vulnerability database

You can also ask Trivy to simply retrieve the vulnerability database. This is useful to initialize workers in Continuous Integration systems. In the first run, the --only-update option is silently ignored.

$ trivy --download-db-only
$ trivy --download-db-only --only-update alpine

Ignore unfixed vulnerabilities

By default, Trivy also detects unpatched/unfixed vulnerabilities. This means you can’t fix these vulnerabilities even if you update all packages. If you would like to ignore them, use the --ignore-unfixed option.

$ trivy --ignore-unfixed ruby:2.3.0

Specify exit code

By default, Trivy exits with code 0 even when vulnerabilities are detected. Use the --exit-code option if you want to exit with a non-zero exit code.

$ trivy --exit-code 1 python:3.4-alpine3.9

This option is useful for CI/CD. In the following example, the test will fail only when a critical vulnerability is found.

$ trivy --exit-code 0 --severity MEDIUM,HIGH ruby:2.3.0
$ trivy --exit-code 1 --severity CRITICAL ruby:2.3.0

Ignore the specified vulnerabilities

Use .trivyignore.

$ cat .trivyignore
# Accept the risk

# No impact in our settings

$ trivy python:3.4-alpine3.9

Specify cache directory

$ trivy --cache-dir /tmp/trivy/ python:3.4-alpine3.9

Clear image caches

The --clear-cache option removes image caches. This option is useful if the image which has the same tag is updated (such as when using latest tag).

$ trivy --clear-cache python:3.7


The --reset option removes all caches and database. After this, it takes a long time as the vulnerability database needs to be rebuilt locally.

$ trivy --reset

Continuous Integration (CI)

Scan your image built in Travis CI/CircleCI. The test will fail if a vulnerability is found. When you don’t want to fail the test, specify --exit-code 0 .

Note: It will take a while for the first time (faster by cache after the second time).

Travis CI

$ cat .travis.yml
  - docker


  - docker build -t trivy-ci-test:${COMMIT} .
  - export VERSION=$(curl --silent "" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
  - wget${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
  - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
  - ./trivy --exit-code 0 --severity HIGH --no-progress --auto-refresh trivy-ci-test:${COMMIT}
  - ./trivy --exit-code 1 --severity CRITICAL --no-progress --auto-refresh trivy-ci-test:${COMMIT}
    - $HOME/.cache/trivy



$ cat .circleci/config.yml
      - image: docker:18.09-git
      - checkout
      - setup_remote_docker
      - restore_cache:
          key: vulnerability-db
      - run:
          name: Build image
          command: docker build -t trivy-ci-test:${CIRCLE_SHA1} .
      - run:
          name: Install trivy
          command: |
            apk add --update curl
                curl --silent "" | \
                grep '"tag_name":' | \
                sed -E 's/.*"v([^"]+)".*/\1/'

            tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
            mv trivy /usr/local/bin
      - run:
          name: Scan the local image with trivy
          command: trivy --exit-code 0 --no-progress --auto-refresh trivy-ci-test:${CIRCLE_SHA1}
      - save_cache:
          key: vulnerability-db
            - $HOME/.cache/trivy
  version: 2
      - build



$ cat .gitlab-ci.yml
  - test

  stage: test
  image: docker:stable-git
    - docker build -t trivy-ci-test:${CI_COMMIT_REF_NAME} .
    - export VERSION=$(curl --silent "" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
    - wget${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
    - tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
    DOCKER_DRIVER: overlay2
  allow_failure: true
    - docker:stable-dind
    - ./trivy --exit-code 0 --severity HIGH --no-progress --auto-refresh trivy-ci-test:${CI_COMMIT_REF_NAME}
    - ./trivy --exit-code 1 --severity CRITICAL --no-progress --auto-refresh trivy-ci-test:${CI_COMMIT_REF_NAME}
      - $HOME/.cache/trivy

Authorization for Private Docker Registry

Trivy can download images from a private registry, without installing Docker or any other 3rd party tools. That’s because it’s easy to run in a CI process.

All you have to do is install Trivy and set ENV vars. But, I can’t recommend using ENV vars in your local machine to you.

Docker Hub

Docker Hub needs TRIVY_AUTH_URL, TRIVY_USERNAME and TRIVY_PASSWORD. You don’t need to set ENV vars when download from public repository.


Amazon ECR (Elastic Container Registry)

Trivy uses AWS SDK. You don’t need to install aws CLI tool. You can use AWS CLI’s ENV Vars.

GCR (Google Container Registry)

Trivy uses Google Cloud SDK. You don’t need to install gcloud command.

If you want to use target project’s repository, you can settle via GOOGLE_APPLICATION_CREDENTIAL.

# must set TRIVY_USERNAME empty char
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json

Self Hosted Registry (BasicAuth)

BasicAuth server needs TRIVY_USERNAME and TRIVY_PASSWORD.


# if you want to use 80 port, use NonSSL
export TRIVY_NON_SSL=true

Vulnerability Detection

OS Packages

The unfixed/unfixable vulnerabilities mean that the patch has not yet been provided on their distribution.

OSSupported VersionsTarget PackagesDetection of unfixed vulnerabilities
Alpine Linux2.2 - 2.7, 3.0 - 3.10Installed by apkNO
Red Hat Universal Base Image7, 8Installed by yum/rpmYES
Red Hat Enterprise Linux6, 7, 8Installed by yum/rpmYES
CentOS6, 7Installed by yum/rpmYES
Amazon Linux1, 2Installed by apt/apt-get/dpkgNO
Debian GNU/Linuxwheezy, jessie, stretch, busterInstalled by apt/apt-get/dpkgYES
Ubuntu12.04, 14.04, 16.04, 18.04, 18.10, 19.04Installed by apt/apt-get/dpkgYES
DistrolessAnyInstalled by apt/apt-get/dpkgYES

RHEL, CentOS and Amazon Linux package information is stored in a binary format, and Trivy uses the rpm executable to parse this information when scanning an image based on RHEL or CentOS. The Trivy container image includes rpm, and the installers include it as a dependency. If you installed the trivy binary using wget or curl, or if you build it from source, you will also need to ensure that rpm is available.


Application Dependencies

Trivy automatically detects the following files in the container and scans vulnerabilities in the application dependencies.

  • Gemfile.lock
  • Pipfile.lock
  • poetry.lock
  • composer.lock
  • package-lock.json
  • yarn.lock
  • Cargo.lock

The path of these files does not matter.


Image Tar format

Trivy scans a tar image with the following format.

  • Docker Image Specification (
    • Moby Project (
    • Buildah, Podman (
    • img (
  • Kaniko
    • Kaniko (

Data source

  • PHP
  • Python
  • Ruby
  • Node.js
  • Rust


  trivy - A simple and comprehensive vulnerability scanner for containers
  trivy [options] image_name
  --format value, -f value    format (table, json) (default: "table")
  --input value, -i value     input file path instead of image name
  --severity value, -s value  severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL")
  --output value, -o value    output file name
  --exit-code value           Exit code when vulnerabilities were found (default: 0)
  --skip-update               skip db update
  --only-update value         update db only specified distribution (comma separated)
  --reset                     remove all caches and database
  --clear-cache, -c           clear image caches
  --quiet, -q                 suppress progress bar and log output
  --no-progress               suppress progress bar
  --ignore-unfixed            display only fixed vulnerabilities
  --refresh                   refresh DB (usually used after version update of trivy)
  --auto-refresh              refresh DB automatically when updating version of trivy
  --debug, -d                 debug mode
  --vuln-type value           comma-separated list of vulnerability types (os,library) (default: "os,library")
  --cache-dir value           cache directory (default: "/path/to/cache")
  --help, -h                  show help
  --version, -v               print the version

Comparison with other scanners


Easy to useAccuracySuitable
for CI
Anchore Engine
Docker Hub×××

vs Clair

Clair uses alpine-secdb. However, the purpose of this database is to make it possible to know what packages has backported fixes. As README says, it is not a complete database of all security issues in Alpine.

Trivy collects vulnerability information in Alpine Linux from Alpine Linux aports repository. Then, those vulnerabilities will be saved on vuln-list.

alpine-secdb has 6959 vulnerabilities (as of 2019/05/12). vuln-list has 11101 vulnerabilities related to Alpine Linux (as of 2019/05/12). There is a difference in detection accuracy because the number of vulnerabilities is nearly doubled.

In addition, Trivy analyzes the middle layers as well to find out which version of the library was used for static linking.

Clair can not handle the following cases because it analyzes the image after applying all layers.

RUN apk add --no-cache sqlite-dev \
 && wget https://xxx/yyy.tar.gz \
 && tar zxvf yyy.tar.gz && cd yyy \
 && make && make install \
 && apk del sqlite-dev

And as many people know, it is difficult to select a Clair client because many clients are deprecated.

Finally, Trivy can also detect vulnerabilities in application dependent libraries such as Bundler, Composer, Pipenv, etc.

vs Anchore Engine

Similar to Clair, there is a difference in detection accuracy on Alpine Linux. Then, as noted above, Anchore Engine does not detect unfixable vulnerabilities on RHEL/CentOS, whereas Trivy does.

Also, Anchore Engine needs some steps to start scanning. Trivy is much easier to use.

vs Quay, Docker Hub, GCR

As Quay seems to use Clair internally, it has the same accuracy as Clair. Docker Hub can scan only official images. GCR hardly detects vulnerabilities on Alpine Linux. Also, it is locked to a specific registry.

Trivy can be used regardless of the registry, and it is easily integrated with CI/CD services.


On 19 August 2019, Trivy’s repositories moved from knqyf263/trivy to aquasecurity/trivy. If you previously installed Trivy you should update any scripts or package manager records as described in this section.


If you have a script that installs Trivy (for example into your CI pipelines) you should update it to obtain it from the new location by replacing knqyf263/trivy with aquasecurity/trivy.

For example:

# Before
$ wget${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz

# After
$ wget${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz


$ apt-get remove --purge trivy
$ sed -i s/knqyf263/aquasecurity/g /etc/apt/sources.list.d/trivy.list
$ apt-get update
$ apt-get install trivy

Share this post


Welcome to my personal blog to share my knowledge
Cyber Security, Ethical Hacking, Web & Network Auditing, Reverse Engineering and Cryptography
This website don't use analytics tracking and is ads-free. JavaScript is enabled .


Contact Form : Connect with Us

    Ricochet : ricochet:3ka6l4q255cakeirgxupsl5i4lw3qpk5gmngtv5amax64hckuovgozyd

2023 © 0x1 | Cyber Security Consulting - Copyright All Rights Reserved