From b87b3d4acdf811ea1dd4455b1ecc0e84c77d5092 Mon Sep 17 00:00:00 2001 From: croway Date: Wed, 9 Sep 2026 14:14:44 +0200 Subject: [PATCH] CAMEL-24502: Least privilege for scheduled workflows and pin Maven wrapper downloads Adapts the main branch fix (#1930) for camel-spring-boot-4.22.x, whose copies of automatic-sync-main.yml and generate-sbom-main.yml had diverged from main's since the branch was cut (older actions/setup-java tag), so a straight cherry-pick conflicted and was aborted in favor of hand-applying the pattern. Both workflows still check out and target `main` (ref: main / base: main), exactly as before this change - that pre-existing quirk is a separate, non-security concern left untouched here. automatic-sync-main.yml is schedule-only, so it never actually runs from this non-default branch; generate-sbom-main.yml additionally declares workflow_dispatch, so it can be manually dispatched against this branch and is a real, reachable instance of the permission gap. Both are hardened for consistency and defense in depth: - permissions: {} declared at the workflow level. - The single job is split into `build` (contents: read; checks out and builds apache/camel then camel-spring-boot, so it must not hold any write grant) and `create-pull-request` (contents: write, pull-requests: write; applies the regenerated diff and opens the PR, running no third-party build code). - Every `uses:` reference is pinned to a full commit SHA with the existing version tag kept as a trailing comment (no version bumps). .mvn/wrapper/maven-wrapper.properties on this branch points at the exact same distributionUrl/wrapperUrl as main's pre-fix file, so it gained the same distributionSha256Sum and wrapperSha256Sum, independently recomputed with shasum -a 256 and cross-checked against the .sha1 files published alongside those artifacts on repo.maven.apache.org. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01U1BUa8bjo4rWycCm2nQVzo --- .github/workflows/automatic-sync-main.yml | 60 ++++++++++++++++++++-- .github/workflows/generate-sbom-main.yml | 61 +++++++++++++++++++++-- .mvn/wrapper/maven-wrapper.properties | 2 + 3 files changed, 114 insertions(+), 9 deletions(-) diff --git a/.github/workflows/automatic-sync-main.yml b/.github/workflows/automatic-sync-main.yml index eaea3eadd451..33d98d848925 100644 --- a/.github/workflows/automatic-sync-main.yml +++ b/.github/workflows/automatic-sync-main.yml @@ -21,21 +21,28 @@ on: schedule: # Run at midnight every day - cron: '0 0 * * *' + +# No grants by default, every job opts in to exactly what it needs. +permissions: {} + jobs: build: name: Sync Camel Spring Boot Main Branch if: github.repository == 'apache/camel-spring-boot' runs-on: ubuntu-latest + # Builds apache/camel and camel-spring-boot, so it must not hold any write grant. + permissions: + contents: read steps: - name: Checkout Camel project - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: apache/camel persist-credentials: false ref: main path: camel - name: Set up JDK - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 with: distribution: 'temurin' java-version: 17 @@ -44,15 +51,60 @@ jobs: run: ./mvnw -V --no-transfer-progress -Dquickly clean install working-directory: ${{ github.workspace }}/camel - name: Checkout Camel-spring-boot project - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: ref: main persist-credentials: false fetch-depth: 0 - name: Build Camel-spring-boot Project run: ./mvnw -V --no-transfer-progress clean install -DskipTests + - name: Collect regenerated sources + # Capture the regenerated tree as a patch: it carries additions, modifications + # and deletions, ignores build output via .gitignore, and excludes the nested + # apache/camel checkout. + run: | + git add --all -- ':!camel' + git diff --cached --binary > "${RUNNER_TEMP}/sync.patch" + git reset --quiet + echo "Patch size: $(wc -c < "${RUNNER_TEMP}/sync.patch") bytes" + - name: Upload regenerated sources + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: regenerated-sources + path: ${{ runner.temp }}/sync.patch + if-no-files-found: error + retention-days: 1 + + create-pull-request: + name: Create Sync Pull Request + needs: build + if: github.repository == 'apache/camel-spring-boot' + runs-on: ubuntu-latest + # Only this job, which runs no third party build, holds the write grants. + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout Camel-spring-boot project + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: main + persist-credentials: false + fetch-depth: 0 + - name: Download regenerated sources + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: regenerated-sources + path: ${{ runner.temp }}/sync + - name: Apply regenerated sources + run: | + if [ -s "${RUNNER_TEMP}/sync/sync.patch" ]; then + git apply --3way --whitespace=nowarn "${RUNNER_TEMP}/sync/sync.patch" + else + echo "Nothing was regenerated, no changes to apply" + fi - name: Create Pull Request - uses: peter-evans/create-pull-request@v8.1.1 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: base: main token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/generate-sbom-main.yml b/.github/workflows/generate-sbom-main.yml index aed092a9b4d6..fea1ed1ae43b 100644 --- a/.github/workflows/generate-sbom-main.yml +++ b/.github/workflows/generate-sbom-main.yml @@ -22,22 +22,28 @@ on: # Every 24 hours - cron: '30 17 * * 0' workflow_dispatch: - + +# No grants by default, every job opts in to exactly what it needs. +permissions: {} + jobs: build: name: Sync Camel Spring Boot Main Branch if: github.repository == 'apache/camel-spring-boot' runs-on: ubuntu-latest + # Builds apache/camel and camel-spring-boot, so it must not hold any write grant. + permissions: + contents: read steps: - name: Checkout Camel project - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: apache/camel persist-credentials: false ref: main path: camel - name: Set up JDK - uses: actions/setup-java@v5 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5 with: distribution: 'temurin' java-version: 17 @@ -46,15 +52,60 @@ jobs: run: ./mvnw -B -V --no-transfer-progress -Dquickly install working-directory: ${{ github.workspace }}/camel - name: Checkout Camel-spring-boot project - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: ref: main persist-credentials: false fetch-depth: 0 - name: Build Camel-spring-boot Project for generating SBOM run: ./mvnw -V --no-transfer-progress clean install -DskipTests -Psbom + - name: Collect regenerated sources + # Capture the regenerated tree as a patch: it carries additions, modifications + # and deletions, ignores build output via .gitignore, and excludes the nested + # apache/camel checkout. + run: | + git add --all -- ':!camel' + git diff --cached --binary > "${RUNNER_TEMP}/sync.patch" + git reset --quiet + echo "Patch size: $(wc -c < "${RUNNER_TEMP}/sync.patch") bytes" + - name: Upload regenerated sources + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: regenerated-sources + path: ${{ runner.temp }}/sync.patch + if-no-files-found: error + retention-days: 1 + + create-pull-request: + name: Create Sync Pull Request + needs: build + if: github.repository == 'apache/camel-spring-boot' + runs-on: ubuntu-latest + # Only this job, which runs no third party build, holds the write grants. + permissions: + contents: write + pull-requests: write + steps: + - name: Checkout Camel-spring-boot project + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: main + persist-credentials: false + fetch-depth: 0 + - name: Download regenerated sources + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: regenerated-sources + path: ${{ runner.temp }}/sync + - name: Apply regenerated sources + run: | + if [ -s "${RUNNER_TEMP}/sync/sync.patch" ]; then + git apply --3way --whitespace=nowarn "${RUNNER_TEMP}/sync/sync.patch" + else + echo "Nothing was regenerated, no changes to apply" + fi - name: Create Pull Request - uses: peter-evans/create-pull-request@v8.1.1 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: base: main token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index ec95f42f3163..03b0f55107b7 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,4 +1,6 @@ wrapperVersion=3.3.4 distributionType=bin distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip +distributionSha256Sum=0d7125e8c91097b36edb990ea5934e6c68b4440eef4ea96510a0f6815e7eeadb wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.4/maven-wrapper-3.3.4.jar +wrapperSha256Sum=4e2fbf6554bc8a4702cdfdd3bef464f423393d784ddbb037216320ce55d5e4e1