From 1f6495a1da46aeacdfdf4cfcfa3924df647d717e Mon Sep 17 00:00:00 2001 From: FrankApiyo Date: Tue, 24 Mar 2026 16:33:51 +0300 Subject: [PATCH 1/4] fix: pin trivy-action and setup-trivy to commit SHAs Pin to immutable commit hashes instead of mutable tags to mitigate supply-chain risk from the Trivy security incident (2026-03-19). - trivy-action: 57a97c7e (v0.35.0) - setup-trivy: 3fb12ec1 (v0.2.6) Ref: https://github.com/aquasecurity/trivy/discussions/10425 --- .github/workflows/ci.yml | 6 +++--- .github/workflows/ecr-image-build.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54f20adb6a..eaffdde676 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -184,7 +184,7 @@ jobs: optional_packages=PyYAML django-redis ${{ secrets.ECR_OPTIONAL_PACKAGES }} - name: Install Trivy - uses: aquasecurity/setup-trivy@v0.2.6 + uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6 if: github.event_name == 'pull_request' || github.event_name == 'push' with: version: v0.69.1 @@ -206,7 +206,7 @@ jobs: trivy vex repo download - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 # v0.34.0 + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 if: github.event_name == 'pull_request' || github.event_name == 'push' with: version: "v0.69.1" @@ -236,7 +236,7 @@ jobs: wget -q "$url" -O html.tpl - name: Run Trivy vulnerability scanner (HTML report) - uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 # v0.34.0 + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 if: github.event_name == 'pull_request' || github.event_name == 'push' with: version: "v0.69.1" diff --git a/.github/workflows/ecr-image-build.yml b/.github/workflows/ecr-image-build.yml index 8608d244f9..6462a42fbc 100644 --- a/.github/workflows/ecr-image-build.yml +++ b/.github/workflows/ecr-image-build.yml @@ -152,7 +152,7 @@ jobs: docker buildx imagetools inspect ${{ env.docker_repo }} - name: Install Trivy - uses: aquasecurity/setup-trivy@v0.2.6 + uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6 with: version: v0.69.1 cache: true @@ -172,7 +172,7 @@ jobs: trivy vex repo download - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 # v0.34.0 + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 with: version: "v0.69.1" image-ref: ${{ env.docker_repo }} @@ -201,7 +201,7 @@ jobs: wget -q "$url" -O html.tpl - name: Run Trivy vulnerability scanner (HTML report) - uses: aquasecurity/trivy-action@c1824fd6edce30d7ab345a9989de00bbd46ef284 # v0.34.0 + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 with: version: "v0.69.1" image-ref: ${{ env.docker_repo }} From 45c1bfe36b669ee9afc76554c8d866d9d9a796cd Mon Sep 17 00:00:00 2001 From: Ukang'a Dickson Date: Tue, 24 Mar 2026 16:44:29 +0300 Subject: [PATCH 2/4] fix: bump trivy to v0.69.3, SHA-pin all actions in CI workflows Upgrade trivy binary from v0.69.1 to v0.69.3 (latest safe release). Pin all remaining GitHub Actions to immutable commit SHAs to prevent supply chain attacks via mutable tag refs. Ref: GHSA-69fq-xp46-6x23 --- .github/workflows/ci.yml | 32 ++++++++++----------- .github/workflows/ecr-image-build.yml | 40 +++++++++++++-------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaffdde676..6bf4ccbb86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,10 +19,10 @@ jobs: fail-fast: false steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Setup python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: "3.10" architecture: "x64" @@ -99,16 +99,16 @@ jobs: --health-retries 5 steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Setup Java - uses: actions/setup-java@v4 + uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 with: distribution: "adopt" java-version: "8" - name: Setup python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: "3.10" architecture: "x64" @@ -154,14 +154,14 @@ jobs: run: echo "IS_PUBLIC_REPO=$(if [ ${{ github.event.repository.private }} = false ]; then echo true; else echo false; fi)" >> $GITHUB_ENV - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Update apt sources run: sudo apt-get update - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: onaio/onadata tags: | @@ -169,7 +169,7 @@ jobs: type=ref,event=pr - name: Build Docker image - uses: docker/build-push-action@v6 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . file: ./docker/onadata-uwsgi/Dockerfile.ubuntu @@ -187,7 +187,7 @@ jobs: uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6 if: github.event_name == 'pull_request' || github.event_name == 'push' with: - version: v0.69.1 + version: v0.69.3 cache: true - name: Configure Trivy VEX Hub with DHI advisories @@ -209,7 +209,7 @@ jobs: uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 if: github.event_name == 'pull_request' || github.event_name == 'push' with: - version: "v0.69.1" + version: "v0.69.3" image-ref: ${{ steps.meta.outputs.tags }} format: sarif ignore-unfixed: false @@ -220,7 +220,7 @@ jobs: - name: Cache Trivy HTML template id: cache-template - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: github.event_name == 'pull_request' || github.event_name == 'push' with: path: html.tpl @@ -239,7 +239,7 @@ jobs: uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 if: github.event_name == 'pull_request' || github.event_name == 'push' with: - version: "v0.69.1" + version: "v0.69.3" image-ref: ${{ steps.meta.outputs.tags }} format: "template" template: "@html.tpl" @@ -250,7 +250,7 @@ jobs: trivy-config: trivy.yaml - name: Upload Trivy SARIF as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: github.event_name == 'pull_request' || github.event_name == 'push' with: name: trivy-sarif-results @@ -258,7 +258,7 @@ jobs: retention-days: 30 - name: Upload Trivy HTML report as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: github.event_name == 'pull_request' || github.event_name == 'push' with: name: trivy-html-report @@ -266,7 +266,7 @@ jobs: retention-days: 30 - name: Upload vulnerability scan results - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@256d634097be96e792d6764f9edaefc4320557b1 # v4 if: (github.event_name == 'push' || github.event_name == 'pull_request') && env.IS_PUBLIC_REPO == 'true' with: sarif_file: "trivy_results.sarif" @@ -343,7 +343,7 @@ jobs: echo "EOF" >> $GITHUB_ENV - name: Send Slack Notification - uses: slackapi/slack-github-action@v1.23.0 + uses: slackapi/slack-github-action@007b2c3c751a190b6f0f040e47ed024deaa72844 # v1.23.0 if: github.event_name == 'push' || github.event_name == 'pull_request' with: payload: | diff --git a/.github/workflows/ecr-image-build.yml b/.github/workflows/ecr-image-build.yml index 6462a42fbc..ddfab3c7c5 100644 --- a/.github/workflows/ecr-image-build.yml +++ b/.github/workflows/ecr-image-build.yml @@ -29,13 +29,13 @@ jobs: echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@ff717079ee2060e4bcee96c4779b553acc87447c # v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -43,11 +43,11 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 + uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950 # v2 - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ${{ steps.login-ecr.outputs.registry }}/onaio/onadata tags: | @@ -63,7 +63,7 @@ jobs: - name: (Ubuntu) Build and push id: docker-build-ubuntu - uses: docker/build-push-action@v6 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . file: ./docker/onadata-uwsgi/Dockerfile.ubuntu @@ -93,7 +93,7 @@ jobs: touch "/tmp/digests/${digest#sha256:}" - name: Upload digest - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: digests-${{ env.PLATFORM_PAIR }} path: /tmp/digests/* @@ -106,17 +106,17 @@ jobs: - build steps: - name: Download digests - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: path: /tmp/digests pattern: digests-* merge-multiple: true - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@ff717079ee2060e4bcee96c4779b553acc87447c # v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -124,11 +124,11 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 + uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950 # v2 - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: ${{ steps.login-ecr.outputs.registry }}/onaio/onadata tags: | @@ -154,7 +154,7 @@ jobs: - name: Install Trivy uses: aquasecurity/setup-trivy@3fb12ec12f41e471780db15c232d5dd185dcb514 # v0.2.6 with: - version: v0.69.1 + version: v0.69.3 cache: true - name: Configure Trivy VEX Hub with DHI advisories @@ -174,21 +174,21 @@ jobs: - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 with: - version: "v0.69.1" + version: "v0.69.3" image-ref: ${{ env.docker_repo }} format: "sarif" output: "trivy-results.sarif" trivy-config: trivy.yaml - name: Upload Trivy scan result to Github security lab - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@256d634097be96e792d6764f9edaefc4320557b1 # v4 with: sarif_file: "trivy-results.sarif" continue-on-error: true - name: Cache Trivy HTML template id: cache-template - uses: actions/cache@v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: html.tpl key: trivy-html-template-v1 @@ -203,7 +203,7 @@ jobs: - name: Run Trivy vulnerability scanner (HTML report) uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0 with: - version: "v0.69.1" + version: "v0.69.3" image-ref: ${{ env.docker_repo }} format: "template" template: "@html.tpl" @@ -211,14 +211,14 @@ jobs: trivy-config: trivy.yaml - name: Upload Trivy SARIF as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: trivy-sarif-results path: trivy-results.sarif retention-days: 30 - name: Upload Trivy HTML report as artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: trivy-html-report path: trivy-results.html @@ -294,7 +294,7 @@ jobs: echo "EOF" >> $GITHUB_ENV - name: Send Slack Notification - uses: slackapi/slack-github-action@v1.26.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { From b4e5e873b39e8751d21da4413d0e74236587b1cd Mon Sep 17 00:00:00 2001 From: Ukang'a Dickson Date: Tue, 24 Mar 2026 16:44:37 +0300 Subject: [PATCH 3/4] fix: SHA-pin all actions in Docker build workflows Pin all third-party GitHub Actions to immutable commit SHAs in docker-image-build.yml and ecr-image-build-alpine.yml to prevent supply chain attacks via mutable tag references. --- .github/workflows/docker-image-build.yml | 12 ++++++------ .github/workflows/ecr-image-build-alpine.yml | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/docker-image-build.yml b/.github/workflows/docker-image-build.yml index 28d1fff499..1d015fea20 100644 --- a/.github/workflows/docker-image-build.yml +++ b/.github/workflows/docker-image-build.yml @@ -15,23 +15,23 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Login to DockerHub - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5 with: images: onaio/onadata tags: | @@ -40,7 +40,7 @@ jobs: - name: Build and push id: docker_build - uses: docker/build-push-action@v6 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . file: ./docker/onadata-uwsgi/Dockerfile.ubuntu diff --git a/.github/workflows/ecr-image-build-alpine.yml b/.github/workflows/ecr-image-build-alpine.yml index 5a69212a0b..b6b611c32c 100644 --- a/.github/workflows/ecr-image-build-alpine.yml +++ b/.github/workflows/ecr-image-build-alpine.yml @@ -27,18 +27,18 @@ jobs: echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: ref: ${{ github.event.inputs.version }} - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@ff717079ee2060e4bcee96c4779b553acc87447c # v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -46,7 +46,7 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 + uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950 # v2 - name: Setup SSH Agent and add Github to known hosts env: @@ -59,7 +59,7 @@ jobs: - name: Build and push Alpine image id: docker-build-alpine - uses: docker/build-push-action@v5 + uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5 with: context: . file: ./docker/onadata-uwsgi/Dockerfile.alpine @@ -86,7 +86,7 @@ jobs: needs: build-alpine steps: - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@v4 + uses: aws-actions/configure-aws-credentials@ff717079ee2060e4bcee96c4779b553acc87447c # v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -94,10 +94,10 @@ jobs: - name: Login to Amazon ECR id: login-ecr - uses: aws-actions/amazon-ecr-login@v2 + uses: aws-actions/amazon-ecr-login@c962da2960ed15f492addc26fffa274485265950 # v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Create multi-arch manifest run: | From 5b63f9a4a10047f2e17a4caa8bf1ed2dd74bfd23 Mon Sep 17 00:00:00 2001 From: Ukang'a Dickson Date: Tue, 24 Mar 2026 16:44:45 +0300 Subject: [PATCH 4/4] chore: add dependabot for GitHub Actions updates Enable weekly automated PRs for GitHub Actions version updates to keep SHA pins current. --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e3cb25d2ab..8af9db9b00 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,3 +11,14 @@ updates: - "ukanga" - "KipSigei" - "DavisRayM" + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + commit-message: + prefix: "chore(ci)" + reviewers: + - "ukanga" + - "KipSigei" + - "DavisRayM"