From ce135e18b7c2b173173e46e2d7d2ba668b3c883f Mon Sep 17 00:00:00 2001 From: Matt Hammond Date: Tue, 26 May 2026 12:37:21 +0100 Subject: [PATCH 1/5] ci: disable credential persistence on checkout actions/checkout leaves the workflow's GITHUB_TOKEN in the local git config after fetching by default. Set persist-credentials: false so later steps don't inherit token access they don't need. --- .github/workflows/check.yml | 1 + .github/workflows/docs.yml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 127e9d311..4f64a9a34 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -18,6 +18,7 @@ jobs: - uses: actions/checkout@v2 with: submodules: 'recursive' + persist-credentials: false - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 890e0eab1..65b19622a 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -11,6 +11,8 @@ jobs: id-token: write steps: - uses: actions/checkout@v2 + with: + persist-credentials: false - uses: ruby/setup-ruby@v1 with: From 7306b9280d31d011f2d90de7c314fc6aac30013f Mon Sep 17 00:00:00 2001 From: Matt Hammond Date: Tue, 26 May 2026 12:38:24 +0100 Subject: [PATCH 2/5] ci: scope job permissions explicitly Set a top-level permissions: {} default and grant each job only the GITHUB_TOKEN scopes it needs: - check.yml/check and check.yml/finish: contents: read for checkout and coverallsapp PR identification. - features.yml/build: contents, deployments, id-token to match the permissions the called reusable workflow requires. --- .github/workflows/check.yml | 6 ++++++ .github/workflows/features.yml | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4f64a9a34..4f4eb1914 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -5,9 +5,13 @@ on: branches: - main +permissions: {} + jobs: check: runs-on: ubuntu-latest + permissions: + contents: read strategy: fail-fast: false matrix: @@ -55,6 +59,8 @@ jobs: finish: needs: check runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Coveralls Finished uses: coverallsapp/github-action@v2 diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index 17cf9d77d..ba3ef2ef1 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -6,8 +6,14 @@ on: branches: - main +permissions: {} + jobs: build: + permissions: + contents: read + deployments: write + id-token: write uses: ably/features/.github/workflows/sdk-features.yml@main with: repository-name: ably-ruby From bf33770b870151a5514a0e3dfc8be7d5f95eb19b Mon Sep 17 00:00:00 2001 From: Matt Hammond Date: Tue, 26 May 2026 12:38:49 +0100 Subject: [PATCH 3/5] ci: read matrix value from env in test run step The run: block expanded ${{ matrix.type }} into the shell directly. Reference TEST_TYPE (already bound in the step's env:) instead so workflow-context values stay out of the shell source. --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4f4eb1914..c7890e1df 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -36,7 +36,7 @@ jobs: RUBY_VERSION: ${{ matrix.ruby }} run: | mkdir junit - bundle exec parallel_rspec --prefix-output-with-test-env-number --first-is-1 -- spec/${{ matrix.type }} + bundle exec parallel_rspec --prefix-output-with-test-env-number --first-is-1 -- "spec/$TEST_TYPE" - uses: actions/upload-artifact@v4 with: name: test-results-ruby-${{ matrix.ruby }}-${{ matrix.protocol }}-${{ matrix.type }} From ee124acbf8c7802b17cc68469d1712605f374582 Mon Sep 17 00:00:00 2001 From: Matt Hammond Date: Tue, 26 May 2026 12:42:14 +0100 Subject: [PATCH 4/5] ci: pin third-party actions to commit SHAs Tags can be moved to point at different commits after publication. Pinning the SHA (with the previous tag retained as a comment for readability) ensures CI runs the exact code we audited. --- .github/workflows/check.yml | 12 ++++++------ .github/workflows/docs.yml | 8 ++++---- .github/workflows/features.yml | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index c7890e1df..c10d05282 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -19,11 +19,11 @@ jobs: protocol: [ 'json', 'msgpack' ] type: [ 'unit', 'acceptance' ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2 with: submodules: 'recursive' persist-credentials: false - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true @@ -37,7 +37,7 @@ jobs: run: | mkdir junit bundle exec parallel_rspec --prefix-output-with-test-env-number --first-is-1 -- "spec/$TEST_TYPE" - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: test-results-ruby-${{ matrix.ruby }}-${{ matrix.protocol }}-${{ matrix.type }} path: | @@ -46,12 +46,12 @@ jobs: retention-days: 7 - name: Upload test results if: always() - uses: ably/test-observability-action@v1 + uses: ably/test-observability-action@5b61d9c59f356b83426cab1b8243dd8bf03c1bea # v1 with: server-url: 'https://test-observability.herokuapp.com' server-auth: ${{ secrets.TEST_OBSERVABILITY_SERVER_AUTH_KEY }} path: 'junit/' - - uses: coverallsapp/github-action@v2 + - uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} flag-name: ruby-${{ matrix.ruby }}-${{ matrix.protocol }}-${{ matrix.type }} @@ -63,7 +63,7 @@ jobs: contents: read steps: - name: Coveralls Finished - uses: coverallsapp/github-action@v2 + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 with: github-token: ${{ secrets.github_token }} parallel-finished: true diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 65b19622a..1a2620fdc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,11 +10,11 @@ jobs: deployments: write id-token: write steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2 with: persist-credentials: false - - uses: ruby/setup-ruby@v1 + - uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0 with: ruby-version: '2.7' bundler-cache: true @@ -24,14 +24,14 @@ jobs: bundle exec yard --readme INTRO.md --tag "spec:Specification" ls -al doc/ - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1 + uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # v1 with: aws-region: eu-west-2 role-to-assume: arn:aws:iam::${{ secrets.ABLY_AWS_ACCOUNT_ID_SDK }}:role/ably-sdk-builds-ably-ruby role-session-name: "${{ github.run_id }}-${{ github.run_number }}" - name: Upload Documentation - uses: ably/sdk-upload-action@v1 + uses: ably/sdk-upload-action@8c6179796fc7ee8fc9bb28d5223ffef005b985cc # v1 with: sourcePath: doc/ githubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index ba3ef2ef1..5d75296d9 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -14,7 +14,7 @@ jobs: contents: read deployments: write id-token: write - uses: ably/features/.github/workflows/sdk-features.yml@main + uses: ably/features/.github/workflows/sdk-features.yml@6b3fc7a8ede2ebdd7a6325314f3a96c6466f1453 # main with: repository-name: ably-ruby secrets: inherit From 4673b91caf5c6b5cb414d398d5a60b5d3ffcc7d9 Mon Sep 17 00:00:00 2001 From: Matt Hammond Date: Tue, 26 May 2026 12:42:53 +0100 Subject: [PATCH 5/5] ci: pass only required secret to reusable workflow The called workflow only declares ABLY_AWS_ACCOUNT_ID_SDK in its workflow_call.secrets contract. Replace secrets: inherit with an explicit passthrough so other repo secrets aren't forwarded into a workflow that has no need for them. --- .github/workflows/features.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/features.yml b/.github/workflows/features.yml index 5d75296d9..dac82afa2 100644 --- a/.github/workflows/features.yml +++ b/.github/workflows/features.yml @@ -17,4 +17,5 @@ jobs: uses: ably/features/.github/workflows/sdk-features.yml@6b3fc7a8ede2ebdd7a6325314f3a96c6466f1453 # main with: repository-name: ably-ruby - secrets: inherit + secrets: + ABLY_AWS_ACCOUNT_ID_SDK: ${{ secrets.ABLY_AWS_ACCOUNT_ID_SDK }}