From 9662aca1a827f4d14f00e7a1a033054eca9c4e61 Mon Sep 17 00:00:00 2001 From: Thomson Thomas Date: Wed, 21 Oct 2026 10:59:42 -0400 Subject: [PATCH] ci(workflows): enforce security checks for GitHub Actions Resolve existing workflow security findings before making the scan fail on new findings. Pin action references, restrict token permissions and checkout credentials, and add a seven-day dependency update cooldown. Remove unused dependency automerge and code-analysis workflows while retaining the shared linter update workflow. #agentic --- .github/dependabot.yml | 12 +++-- .github/workflows/dependabot-automerge.yml | 12 ----- .github/workflows/pull-request.yml | 59 +++++++++++++--------- .github/workflows/release-draft.yml | 7 ++- .github/workflows/sonarcloud.yml | 16 ------ .github/workflows/trunk-upgrade.yml | 19 +++++-- .github/workflows/zizmor.yml | 6 +-- 7 files changed, 62 insertions(+), 69 deletions(-) delete mode 100644 .github/workflows/dependabot-automerge.yml delete mode 100644 .github/workflows/sonarcloud.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0385aab4..55316768 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,16 +1,18 @@ version: 2 updates: - package-ecosystem: gradle - directory: "/android" + directory: '/android' schedule: interval: daily labels: - dependabot open-pull-requests-limit: 10 ignore: - - dependency-name: "com.google.firebase:firebase-messaging" + - dependency-name: 'com.google.firebase:firebase-messaging' commit-message: - prefix: "chore" + prefix: 'chore' + cooldown: + default-days: 7 - package-ecosystem: github-actions directory: / schedule: @@ -19,4 +21,6 @@ updates: labels: - dependabot commit-message: - prefix: "chore" + prefix: 'chore' + cooldown: + default-days: 7 diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml deleted file mode 100644 index 35e3c222..00000000 --- a/.github/workflows/dependabot-automerge.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: "Dependabot Automerge" - -on: - workflow_run: - workflows: ["Build and Test"] - types: - - completed - -jobs: - automerge-dependabot: - name: "Automerge Dependabot PR" - uses: mParticle/mparticle-workflows/.github/workflows/dependabot-automerge.yml@main diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 21f370ac..d47ecae1 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -10,9 +10,6 @@ concurrency: permissions: contents: read - pull-requests: read - checks: write - id-token: write jobs: trunk-check: @@ -24,8 +21,10 @@ jobs: pull-requests: read steps: - name: Checkout - uses: actions/checkout@v7 - - uses: actions/setup-node@v7.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: 24 cache: yarn @@ -33,15 +32,17 @@ jobs: - name: Install node modules run: yarn install --frozen-lockfile - name: Trunk Check - uses: trunk-io/trunk-action@v1 + uses: trunk-io/trunk-action@04ba50e7658c81db7356da96657e6e77f220bfa3 # v1.3.1 js-tests: name: 'JS Tests' runs-on: ubuntu-latest steps: - name: 'Checkout' - uses: actions/checkout@v7 - - uses: actions/setup-node@v7.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: 24 cache: yarn @@ -60,7 +61,9 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout' - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: 'Run Android Unit Tests' working-directory: android run: ./gradlew test @@ -70,7 +73,9 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout' - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: 'Run Android lint' working-directory: android run: ./gradlew lint @@ -80,7 +85,9 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout' - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: 'Run Android kotlin lint' working-directory: android run: ./gradlew ktlintCheck @@ -90,8 +97,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 - - uses: actions/setup-node@v7.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: 24 cache: yarn @@ -133,15 +142,17 @@ jobs: MP_USE_COCOAPODS: ${{ matrix.ios_deps == 'cocoapods' && '1' || '0' }} steps: - name: Checkout - uses: actions/checkout@v7 - - uses: actions/setup-node@v7.1.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: node-version: 24 cache: yarn cache-dependency-path: yarn.lock - name: Set up Xcode - uses: maxim-lobanov/setup-xcode@v1.7.0 + uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 with: # Avoid `latest-stable` (Xcode 17+ / Swift 6 defaults) breaking RoktUXHelper # source builds until Rokt pins are updated upstream. @@ -151,7 +162,7 @@ jobs: run: echo "TOOLCHAINS=com.apple.dt.toolchain.XcodeDefault" >> $GITHUB_ENV - name: Setup iOS Simulator - uses: futureware-tech/simulator-action@v6 + uses: futureware-tech/simulator-action@c768f52966d5f70335ec77881f9806b24a52f80e # v6 id: simulator with: model: iPhone 16 @@ -200,12 +211,14 @@ jobs: - name: Build iOS sample app and run native unit tests working-directory: sample/ios + env: + SIMULATOR_UDID: ${{ steps.simulator.outputs.udid }} run: | bundle exec pod install set -o pipefail && xcodebuild -workspace MParticleSample.xcworkspace \ -configuration Debug \ -scheme MParticleSample \ - -destination 'id=${{ steps.simulator.outputs.udid }}' \ + -destination "id=$SIMULATOR_UDID" \ -derivedDataPath ios/build \ -UseModernBuildSystem=YES \ test \ @@ -246,11 +259,9 @@ jobs: - ios-sample-app - js-tests name: Notify GChat - uses: ROKT/rokt-workflows/.github/workflows/oss_pr_opened_notification.yml@main + permissions: + contents: read + id-token: write + uses: ROKT/rokt-workflows/.github/workflows/oss_pr_opened_notification.yml@da0c5fd5d38e9cf113a24ec9aaea079cc7d0bc40 # main secrets: gchat_webhook: ${{ secrets.GCHAT_PRS_WEBHOOK }} - - automerge-dependabot: - name: 'Save PR Number for Dependabot Automerge' - needs: [js-tests, android-unit-tests, android-lint, android-kotlin-lint] - uses: mParticle/mparticle-workflows/.github/workflows/dependabot-save-pr-number.yml@main diff --git a/.github/workflows/release-draft.yml b/.github/workflows/release-draft.yml index 94a462da..cbf3c99f 100644 --- a/.github/workflows/release-draft.yml +++ b/.github/workflows/release-draft.yml @@ -13,8 +13,7 @@ on: - major permissions: - contents: write - pull-requests: write + contents: read jobs: create-release-pr: @@ -57,7 +56,7 @@ jobs: - name: Generate changelog from git history id: changelog - uses: ROKT/rokt-workflows/actions/generate-changelog@main + uses: ROKT/rokt-workflows/actions/generate-changelog@da0c5fd5d38e9cf113a24ec9aaea079cc7d0bc40 # main with: version: ${{ steps.bump-version.outputs.new_version }} @@ -74,7 +73,7 @@ jobs: permission-pull-requests: write - name: Create release PR - uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: token: ${{ steps.generate-token.outputs.token }} branch: release/${{ steps.bump-version.outputs.new_version }} diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml deleted file mode 100644 index 43b126c1..00000000 --- a/.github/workflows/sonarcloud.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: "SonarCloud" - -on: - workflow_dispatch: - workflow_run: - workflows: ["Build and Test"] - types: - - completed - -jobs: - sonarcloud-check: - name: "SonarCloud Check" - uses: mParticle/mparticle-workflows/.github/workflows/sonarcloud.yml@main - secrets: inherit - with: - app_relative_path: "android" diff --git a/.github/workflows/trunk-upgrade.yml b/.github/workflows/trunk-upgrade.yml index d30e47e9..6a50209c 100644 --- a/.github/workflows/trunk-upgrade.yml +++ b/.github/workflows/trunk-upgrade.yml @@ -2,13 +2,17 @@ name: Run trunk upgrade on: workflow_call: + secrets: + SDK_RELEASE_GITHUB_CLIENT_ID: + required: true + SDK_RELEASE_GITHUB_APP_PRIVATE_KEY: + required: true schedule: - cron: 0 0 1 * * workflow_dispatch: permissions: - contents: write - pull-requests: write + contents: read jobs: generate-and-call-upgrade: @@ -20,15 +24,20 @@ jobs: id: generate-token uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3.3.0 with: - client-id: ${{ secrets.SDK_RELEASE_GITHUB_CLIENT_ID }} # trunk-ignore(actionlint/expression) - private-key: ${{ secrets.SDK_RELEASE_GITHUB_APP_PRIVATE_KEY }} # trunk-ignore(actionlint/expression) + client-id: ${{ secrets.SDK_RELEASE_GITHUB_CLIENT_ID }} + private-key: ${{ secrets.SDK_RELEASE_GITHUB_APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} repositories: | react-native-mparticle + permission-contents: write + permission-pull-requests: write trunk-upgrade: needs: generate-and-call-upgrade name: Run trunk upgrade - uses: ROKT/rokt-workflows/.github/workflows/trunk-upgrade.yml@main # trunk-ignore(actionlint/workflow-call) + permissions: + contents: write + pull-requests: write + uses: ROKT/rokt-workflows/.github/workflows/trunk-upgrade.yml@da0c5fd5d38e9cf113a24ec9aaea079cc7d0bc40 # main with: token: ${{ needs.generate-and-call-upgrade.outputs.generated-token }} diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 9ec2d64c..566a7f12 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -10,6 +10,7 @@ on: paths: - .github/workflows/** - .github/actions/** + - .github/dependabot.yml push: branches: - main @@ -18,6 +19,7 @@ on: paths: - .github/workflows/** - .github/actions/** + - .github/dependabot.yml concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} @@ -41,10 +43,6 @@ jobs: fetch-depth: 1 # zizmor only needs the tree at HEAD - name: Run zizmor uses: zizmorcore/zizmor-action@85b2b9fb8e3325e7a23d7d0a9d7ba5ae0f999e3e # v0.7.1 - # Permanent advisory mode — zizmor is rolled out across Rokt repos as a - # reporter, not a gate. Findings surface as PR annotations so owners - # can triage incrementally without blocking unrelated changes. - continue-on-error: true with: advanced-security: false annotations: true