imageazure-devopstrivy

How to run trivy image scan inside Azure DevOps


I want to run trivy sbom generator for a number of images, pushed to Azure Container registry from Azure DevOps pipeline.

My task looks like

- task: AzureCLI@2
  inputs:
    azureSubscription: 'MySubscription'
    scriptType: bash
    scriptLocation: inlineScript
    inlineScript: |
      az acr login --name ACR_Name
    
      docker run --rm -v $(System.DefaultWorkingDirectory):/src aquasec/trivy image --format cyclonedx --output /src/sbom.json ACR_Name.azurecr.io/IMAGENAME:latest

Unfortunately, it does not work that way with the exception

2024-11-12T12:24:45Z FATAL Fatal error image scan error: scan error: unable to initialize a scanner: unable to initialize an image scanner: unable to find the specified image "ACR_NAME/IMAGENAME:latest" in ["docker" "containerd" "podman" "remote"]: 4 errors occurred:

  • docker error: unable to inspect the image (...): Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
  • containerd error: containerd socket not found: /run/containerd/containerd.sock
  • podman error: unable to initialize Podman client: no podman socket found: stat podman/podman.sock: no such file or directory
  • remote error: GET https://ACR_NAME/oauth2/token?scope=repository%3A...%3Apull&service=...: UNAUTHORIZED: authentication required, visit https://aka.ms/acr/authorization for more information.

At the same time I can run docker pull IMAGENAME from inside this script as expected. I even tried to run it prior to running trivy, but it looks like it does not use local images (result is exactly the same)

Is it possible to "pass" authorization inside the container?


Solution

  • According to documentation here

    You should create service principal with AcrPull permissions

    export SP_DATA=$(az ad sp create-for-rbac --name TrivyTest --role AcrPull --scope "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.ContainerRegistry/registries/<registry_name>")
    

    Then you need these credentials:

    # must set TRIVY_USERNAME empty char
    export AZURE_CLIENT_ID$(echo $SP_DATA | jq -r .appId)
    export AZURE_CLIENT_SECRET$(echo $SP_DATA | jq -r .password)
    export AZURE_TENANT_ID$(echo $SP_DATA | jq -r .tenant)
    

    and you should be able to run it on this way:

    - task: AzureCLI@2
      inputs:
        azureSubscription: 'MySubscription'
        scriptType: bash
        scriptLocation: inlineScript
        inlineScript: |
          az acr login --name ACR_Name
        
          docker run --rm -v $(System.DefaultWorkingDirectory):/src \
             -e AZURE_CLIENT_ID=$AZURE_CLIENT_ID \
             -e AZURE_CLIENT_SECRET=$AZURE_CLIENT_SECRET \
             -e AZURE_TENANT_ID=$AZURE_TENANT_ID \
             aquasec/trivy image --format cyclonedx --output /src/sbom.json ACR_Name.azurecr.io/IMAGENAME:latest
        env:
          AZURE_CLIENT_ID: $(AZURE_CLIENT_ID)
          AZURE_CLIENT_SECRET: $(AZURE_CLIENT_SECRET)
          AZURE_TENANT_ID: $(AZURE_TENANT_ID)
    

    I assumed you stored credentials in secrets in variable group which you linked to the pipeline.

    And if you want to install trivy on the agent instead of using docker image you can check this tutorial.