aquasecurity / trivy-action

Runs Trivy as GitHub action to scan your Docker container image for vulnerabilities
Apache License 2.0
807 stars 234 forks source link

Unable to scan non-AMD64 container images #279

Open RichardoC opened 11 months ago

RichardoC commented 11 months ago

I've a workflow that builds ARM64 images then attempts to scan them with trivy, unfortunately because the host is AMD64 the images can't be found.

Is there a way to use docker buildx/etc to run trivy against these non-native architecture images?

Example workflow below, which fails with the following error

 Building SARIF report with options:  --vuln-type  os,library  ghcr.io/someimage:c3841be700f9cb2d97db3c41bf6c5ea104cc435f-distroless
2023-11-03T22:48:06.843Z    FATAL   image scan error: scan error: unable to initialize a scanner: unable to initialize a docker scanner: 4 errors occurred:
    * unable to inspect the image (ghcr.io/someimage:c3841be700f9cb2d97db3c41bf6c5ea104cc435f-distroless): Error response from daemon: No such image: ghcr.io/someimage:c3841be700f9cb2d97db3c41bf6c5ea104cc435f-distroless```

```yaml
name: Run per commit workflows

on:
  push:
    branches:
      - 'main'

jobs:
name: Build and publish ARM64 container images 📦 to GitHub Container Registry
    runs-on: ubuntu-latest
    steps:
      - name: Checkout main
        uses: actions/checkout@v4.1.0
        with:
             fetch-depth: 1
             fetch-tags: true
      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5.0.0
        with:
          images: ghcr.io/${{ github.repository }}
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3.0.0
        with:
          platforms: 'arm64'
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3.0.0

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3.0.0
        with:
          registry: ghcr.io
          # This is the user that triggered the Workflow. In this case, it will
          # either be the user whom created the Release or manually triggered
          # the workflow_dispatch.
          username: ${{ github.actor }}
          # `secrets.GITHUB_TOKEN` is a secret that's automatically generated by
          # GitHub Actions at the start of a workflow run to identify the job.
          # This is used to authenticate against GitHub Container Registry.
          # See https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret
          # for more detailed information.
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push distroless image
        uses: docker/build-push-action@v5.0.0
        with:
          file: Dockerfile-distroless
          context: .
          push: true # push the image to ghcr
          tags: |
            ghcr.io/someimage:${{github.sha}}-distroless
          labels: ${{ steps.meta.outputs.labels }}
          platforms: linux/arm64
          cache-from: type=gha
          cache-to: type=gha,mode=max
      - name: Run Trivy vulnerability scanner for distroless container
        uses: aquasecurity/trivy-action@0.13.1
        with:
          image-ref: 'ghcr.io/someimage:${{github.sha}}-distroless'
          format: 'sarif'
          output: 'distroless-results.sarif'
          github-pat: '${{ secrets.GITHUB_TOKEN }}'
      - name: Upload Trivy distroless scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: 'distroless-results.sarif'
          category: 'trivy-distroless-ARM64'
pbnj-dragon commented 9 months ago

I was able to work around this issue in my workflow by specifying the platform in trivy.yaml file.

Example:

  1. In trivy.yaml:

    image:
     platform: linux/arm64
  2. In GitHub Workflow file:

      - name: Run Trivy vulnerability scanner for distroless container
        uses: aquasecurity/trivy-action@0.13.1
        with:
          image-ref: 'ghcr.io/someimage:${{github.sha}}-distroless'
          format: 'sarif'
          output: 'distroless-results.sarif'
          github-pat: '${{ secrets.GITHUB_TOKEN }}'
          trivy-config: trivy.yaml
RichardoC commented 8 months ago

Thanks, that's a good workaround @pbnj-dragon though it would be fantastic to have cross-platform scanning

pbnj-dragon commented 8 months ago

Agreed.

I would like to see an input for platform, like:

- name: Run Trivy vulnerability scanner for distroless container
     uses: aquasecurity/trivy-action@0.13.1
     with:
       image-ref: 'ghcr.io/someimage:${{github.sha}}-distroless'
       platform: 'linux/arm64'
       format: 'sarif'
       output: 'distroless-results.sarif'
       github-pat: '${{ secrets.GITHUB_TOKEN }}'

That way, I can leverage Job Matrix as needed.

Although, I am not sure if image platform has that much effect on vulnerabilities (I could be wrong).

pbnj-dragon commented 8 months ago

I just came across this bit of documentation in the action's README:

You can use Trivy environment variables to set the necessary options (including flags that are not supported by Inputs, such as --secret-config).

Upon reading the docs, it seems that trivy respects environment variables like:

- name: Run Trivy vulnerability scanner for distroless container
     uses: aquasecurity/trivy-action@0.13.1
     with:
       image-ref: 'ghcr.io/someimage:${{github.sha}}-distroless'
       format: 'sarif'
       output: 'distroless-results.sarif'
       github-pat: '${{ secrets.GITHUB_TOKEN }}'
     env:
       TRIVY_PLATFORM: linux/arm64

Which effectively enables the same use-cases that having a dedicated platform: input would.

For example, you can scan the same image for different platforms, using a Job Matrix, like:

jobs:
  trivy-image:
    strategy:
      matrix:
        platforms: [ "linux/arm64", "linux/amd64" ]
    steps:
      - name: Run Trivy vulnerability scanner for distroless container
         uses: aquasecurity/trivy-action@0.13.1
         with:
           image-ref: 'ghcr.io/someimage:${{github.sha}}-distroless'
         env:
           TRIVY_PLATFORM: ${{ matrix.platform }}