Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 36 additions & 21 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,40 +74,25 @@ jobs:
username: ${{ secrets.username }}
password: ${{ secrets.password }}

- name: Build Docker Image
- name: Build Docker image
uses: docker/build-push-action@v6
with:
build-args: ${{ inputs.build-args }}
context: ${{ inputs.context }}
file: ${{ inputs.dockerfile }}
platforms: ${{ inputs.platforms }}
push: ${{ inputs.push }}
platforms: "linux/amd64"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security scan only covers one platform, not all pushed

High Severity

The security scan only runs on the linux/amd64 image (hardcoded at line 83), but the final push step uses ${{ inputs.platforms }} which defaults to "linux/amd64,linux/arm64". This means arm64 images (and any other non-amd64 platforms) are pushed to the registry without being scanned for vulnerabilities. Different architectures can have different base images with different vulnerabilities, defeating the purpose of failing builds on CRITICAL or HIGH vulnerabilities.

Additional Locations (1)

Fix in Cursor Fix in Web

load: true # Make the image available on runner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ load: true is not compatible with multi-platform builds. Docker can only load a single architecture image locally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see 0d18116

push: false # Don't push yet, wait for security checks
tags: ${{ inputs.image-name }}:${{ inputs.image-tag }}

- name: Build Docker Image as Tarball
if: ${{ inputs.security-scan }}
run: |
BUILD_ARGS=""
if [ -n "${{ inputs.build-args }}" ]; then
while IFS= read -r line; do
if [ -n "$line" ]; then
BUILD_ARGS="$BUILD_ARGS --build-arg $line"
fi
done <<< "${{ inputs.build-args }}"
fi
docker build $BUILD_ARGS -t ${{ inputs.image-name }}:${{ inputs.image-tag }} -f ${{ inputs.dockerfile }} ${{ inputs.context }}
docker save -o vuln-image.tar ${{ inputs.image-name }}:${{ inputs.image-tag }}

- name: Run Trivy vulnerability scanner
id: trivy
if: ${{ inputs.security-scan }}
uses: aquasecurity/trivy-action@0.29.0
uses: aquasecurity/trivy-action@0.33.1
with:
input: vuln-image.tar
image-ref: ${{ inputs.image-name }}:${{ inputs.image-tag }}
format: ${{ (inputs.security-report == 'sarif' && 'sarif') || 'table' }}
ignore-unfixed: true
vuln-type: "os,library"
severity: "CRITICAL,HIGH"
hide-progress: true
output: ${{ (inputs.security-report == 'sarif' && 'trivy-results.sarif') || 'trivy.txt' }}

Expand Down Expand Up @@ -196,3 +181,33 @@ jobs:
${{ steps.read_hadolint.outputs.report }}
```
</details>

- name: Fail build on CRITICAL or HIGH vulnerabilities
if: ${{ inputs.security-scan }}
uses: aquasecurity/trivy-action@0.33.1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trivy is executed twice (around line 88).
In my opinion, we can merge this into a single scan using exit-code: 1.
If we still want to publish the report before failing, we can use continue-on-error and then check the exit code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trivy is executed twice to allow for a full scan and a restrictive scan only on CRITICAL and HIGH.
This can be improved and is inspired by
https://github.com/aquasecurity/trivy-action?tab=readme-ov-file#skipping-setup-when-calling-trivy-action-multiple-times

with:
image-ref: ${{ inputs.image-name }}:${{ inputs.image-tag }}
format: ${{ (inputs.security-report == 'sarif' && 'sarif') || 'table' }}
ignore-unfixed: true
vuln-type: "os,library"
severity: "CRITICAL,HIGH"
hide-progress: true
skip-setup-trivy: true
exit-code: 1

- name: Build and push Docker image

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a double build. I think we can push the already built image after it has been scanned, without rebuilding the image again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only works if load can be used, in the other case, the tag is not created locally and the image is not available through docker client

if: ${{ inputs.push }}
uses: docker/build-push-action@v6
with:
build-args: ${{ inputs.build-args }}
context: ${{ inputs.context }}
file: ${{ inputs.dockerfile }}
platforms: ${{ inputs.platforms }}
push: true
tags: ${{ inputs.image-name }}:${{ inputs.image-tag }}
Comment on lines +198 to +207

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: Build and push Docker image
if: ${{ inputs.push }}
uses: docker/build-push-action@v6
with:
build-args: ${{ inputs.build-args }}
context: ${{ inputs.context }}
file: ${{ inputs.dockerfile }}
platforms: ${{ inputs.platforms }}
push: true
tags: ${{ inputs.image-name }}:${{ inputs.image-tag }}
- name: Push Docker image
if: ${{ inputs.push }}
run: docker push ${{ inputs.image-name }}:${{ inputs.image-tag }}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I do this, with a single platform build, multi-platform build will be broken.


- name: Cleanup files
if: always()
run: |
rm -f trivy.txt trivy-results.sarif
docker image rm -f ${{ inputs.image-name }}:${{ inputs.image-tag }}