Enhance Code Security with GitHub Actions: Automatically Commenting PRs with Docker Scans

Enhance Code Security with GitHub Actions: Automatically Commenting PRs with Docker Scans

To raise the security awareness of our development team, we’ve integrated a mechanism into our CI using GitHub Actions to conduct security scans on Docker images and automatically add those results as comments to pull requests (PRs).

Overview of the scan-and-comment Job

This job automates a series of steps: checking out the code, building the Docker image, performing the security scan, formatting the results, and finally, posting comments to the PR. We use Trivy for scanning vulnerabilities in Docker images. More details about Trivy can be found in a separate article.

Read about Trivy’s vulnerability scanning

Details of the scan-and-comment Job

Below is the complete CI workflow after adding the scan-and-comment job:

name: backend-ci
on:
push:
branches:
main
staging
develop
pull_request:
types:
opened
paths:
backend/**”
workflow_dispatch: # For manual execution

jobs:
setup:
# Details omitted for brevity

test:
# Details omitted for brevity

lint:
# Details omitted for brevity

tsc:
# Details omitted for brevity

scan-and-comment:
runs-on: ubuntu-latest
if: github.event_name == ‘pull_request’ && github.event.action == ‘opened’
steps:
name: Checkout code
uses: actions/checkout@v4

name: Build Docker Image
run: docker build –build-arg ENV=prod -t local-image:latest -f ./backend/Dockerfile.ecs ./backend

name: Scan image with Trivy
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: local-image:latest
format: table”
severity: CRITICAL,HIGH”
output: trivy-result.txt

name: Check Trivy result file
run: cat trivy-result.txt

name: Format Trivy Scan Result
run: |
if [ -s trivy-result.txt ]; then
echo -e “## Vulnerability Scan Resultsn<details><summary>Details</summary>nn“`n$(cat trivy-result.txt)n“`n</details>” > formatted-trivy-result.md
else
echo -e “## Vulnerability Scan ResultsnNo vulnerabilities were detected.” > formatted-trivy-result.md
fi

name: Comment PR with Trivy scan results
uses: marocchino/sticky-pull-request-comment@v2
with:
path: formatted-trivy-result.md

name: Clean up Trivy result file
run: rm -f trivy-result.txt formatted-trivy-result.md

1. Code Checkout

This job is executed only when a PR is newly created (if: github.event_name == ‘pull_request’ && github.event.action == ‘opened’), ensuring that it does not trigger on syncs or reopens.

scan-and-comment:
runs-on: ubuntu-latest
if: github.event_name == ‘pull_request’ && github.event.action == ‘opened’
steps:
name: Checkout code
uses: actions/checkout@v4

2. Docker Image Build

The Docker image is built using the same settings as the production environment, enhancing the precision of the security scans.

name: Build Docker Image
run: docker build –build-arg ENV=prod -t local-image:latest -f ./backend/Dockerfile.ecs ./backend

Below is the Dockerfile used for the build. It’s configured for production builds, specifying the ENV=prod parameter to improve security scan accuracy.

FROM node:20.15.0 AS builder

WORKDIR /app

COPY package*.json ./
COPY yarn.lock ./

# Install dependencies ignoring Husky
# Do not use production mode here for yarn build
RUN yarn install –frozen-lockfile –ignore-scripts

COPY . .

RUN yarn build

ARG ENV

# If staging or production environment, remove node_modules and reinstall in production mode
RUN if [ $ENV = “prod” ] || [ $ENV = “stg” ]; then
rm -rf node_modules && yarn install –frozen-lockfile –ignore-scripts –production;
fi

FROM node:20.15.0-slim

WORKDIR /app

COPY –from=builder /app/dist ./dist
COPY –from=builder /app/node_modules ./node_modules
COPY –from=builder /app/package.json ./package.json

EXPOSE 8080

CMD [“node”, “dist/main”]

3. Image Scan with Trivy

Trivy is used to perform the security scan, and the results are saved in a text file.

name: Scan image with Trivy
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: local-image:latest
format: table”
severity: CRITICAL,HIGH”
output: trivy-result.txt

name: Check Trivy result file
run: cat trivy-result.txt

https://github.com/aquasecurity/trivy-action/tree/master/

4. Format Trivy Scan Results

Based on the scan results, a detailed comment format is created.

name: Format Trivy Scan Result
run: |
if [ -s trivy-result.txt ]; then
echo -e “## Vulnerability Scan Resultsn<details><summary>Details</summary>nn“`n$(cat trivy-result.txt)n“`n</details>” > formatted-trivy-result.md
else
echo -e “## Vulnerability Scan ResultsnNo vulnerabilities were detected.” > formatted-trivy-result.md
fi

5. Comment on PR with Trivy Scan Results

The formatted scan results are posted as a comment on the PR.

name: Comment PR with Trivy scan results
uses: marocchino/sticky-pull-request-comment@v2
with:
path: formatted-trivy-result.md

6. Cleanup

Finally, the used files are deleted to maintain a clean environment.

name: Clean up Trivy result file
run: rm -f trivy-result.txt formatted-trivy-result.md

Conclusion

In conclusion, integrating the scan-and-comment job within our CI pipeline using GitHub Actions enhances our security posture by ensuring Docker images are scanned for vulnerabilities at every critical PR juncture. This automation not only streamlines our security checks but also fosters an environment where security consciousness is an integral part of the development process, maintaining high standards across all deployments.

Please follow and like us:
Pin Share