ci: GHA workflow security cleanup#2208
Conversation
Without an explicit permissions block, jobs fall back to the repository-default GITHUB_TOKEN scope, which is broader than any of these workflows need. Set contents: read at the workflow level (with the additional deployments/id-token write scopes the features.yml reusable workflow requires on its job).
actions/checkout writes a token to .git/config and leaves it there for the rest of the job by default. With persist-credentials: false the token is only used to fetch and is then removed, so later steps in the same job cannot reuse it.
The reusable workflow ably/features/.github/workflows/sdk-features.yml declares one named secret (ABLY_AWS_ACCOUNT_ID_SDK). Passing it explicitly instead of using secrets: inherit means new repository or organisation secrets are not silently forwarded to the called workflow.
GitHub tag references like @v4 are mutable - the maintainer (or anyone who compromises their account) can move the tag to a different commit. Pinning to a full commit SHA freezes the exact code that runs in CI; the trailing comment records which tagged release each SHA corresponds to so updates are still easy to review. ably/features and editorconfig-checker were previously tracking @main and are now pinned to a specific commit.
WalkthroughSix GitHub Actions workflows are updated to improve supply-chain security by adding explicit read-only permissions, pinning all external actions and reusable workflows to specific commit SHAs instead of version tags, disabling credential persistence in checkout steps, and tightening secret handling in the features workflow. ChangesGitHub Actions Supply-Chain Security Hardening
🎯 2 (Simple) | ⏱️ ~12 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/docs.yml (1)
15-23:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd
contents: readto this job’s permissions.
actions/checkoutruns with the job’sGITHUB_TOKEN, and when a job-levelpermissionsblock is present, any omitted scopes are set tonone, which can block checkout (especially for private repos).Suggested fix
permissions: + contents: read deployments: write id-token: write🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/docs.yml around lines 15 - 23, The job-level permissions block currently lists only deployments and id-token, which causes omitted scopes like contents to be set to none and can break actions/checkout; update the permissions block to include contents: read so actions/checkout can access the repository (i.e., add contents: read alongside deployments: write and id-token: write in the permissions section referenced around the actions/checkout@... step).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/integration-test.yaml:
- Around line 65-68: The workflow step get-xcparse-commit-sha currently uses the
deprecated ::set-output command; replace the echo "::set-output name=sha::$(git
rev-parse HEAD)" approach by writing the output key/value into $GITHUB_OUTPUT so
the output remains available as steps.get-xcparse-commit-sha.outputs.sha (i.e.,
append a line of the form sha=<git rev-parse HEAD> to the $GITHUB_OUTPUT file in
that step).
---
Outside diff comments:
In @.github/workflows/docs.yml:
- Around line 15-23: The job-level permissions block currently lists only
deployments and id-token, which causes omitted scopes like contents to be set to
none and can break actions/checkout; update the permissions block to include
contents: read so actions/checkout can access the repository (i.e., add
contents: read alongside deployments: write and id-token: write in the
permissions section referenced around the actions/checkout@... step).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3e6c7a3c-8776-4dad-846a-d7bb925217c1
📒 Files selected for processing (7)
.github/workflows/check-pod.yaml.github/workflows/check-spm.yaml.github/workflows/docs.yml.github/workflows/examples.yaml.github/workflows/features.yml.github/workflows/integration-test.yaml.github/workflows/lint.yml
| run: | | ||
| cd xcparse | ||
| echo "::set-output name=sha::$(git rev-parse HEAD)" | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify there are no deprecated set-output commands left in workflows.
rg -n --iglob '*.yml' --iglob '*.yaml' '::set-output\s+name=' .github/workflowsRepository: ably/ably-cocoa
Length of output: 164
🏁 Script executed:
#!/bin/bash
set -euo pipefail
nl -ba .github/workflows/integration-test.yaml | sed -n '55,80p'Repository: ably/ably-cocoa
Length of output: 102
🏁 Script executed:
#!/bin/bash
set -euo pipefail
awk 'NR>=55 && NR<=80 {printf "%d:%s\n", NR, $0}' .github/workflows/integration-test.yamlRepository: ably/ably-cocoa
Length of output: 1003
Replace deprecated set-output in workflow
.github/workflows/integration-test.yaml uses the deprecated workflow command on the get-xcparse-commit-sha step; migrate it to write to $GITHUB_OUTPUT (so steps.get-xcparse-commit-sha.outputs.sha keeps working).
Suggested fix
cd xcparse
- echo "::set-output name=sha::$(git rev-parse HEAD)"
+ echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| run: | | |
| cd xcparse | |
| echo "::set-output name=sha::$(git rev-parse HEAD)" | |
| run: | | |
| cd xcparse | |
| echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 65-65: workflow command "set-output" was deprecated. use echo "{name}={value}" >> $GITHUB_OUTPUT instead: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
(deprecated-commands)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/integration-test.yaml around lines 65 - 68, The workflow
step get-xcparse-commit-sha currently uses the deprecated ::set-output command;
replace the echo "::set-output name=sha::$(git rev-parse HEAD)" approach by
writing the output key/value into $GITHUB_OUTPUT so the output remains available
as steps.get-xcparse-commit-sha.outputs.sha (i.e., append a line of the form
sha=<git rev-parse HEAD> to the $GITHUB_OUTPUT file in that step).
Routine hygiene pass over the seven GitHub Actions workflows in this repo, prompted by a workflow security audit. No behavioural changes are intended.
The changes are split into four commits, one per finding type:
Declare minimal permissions on workflows — every workflow now sets an explicit
permissions:block (most arecontents: read). Without one, the job'sGITHUB_TOKENfalls backto the repository-default scope, which is broader than these workflows need.
Disable credential persistence on checkout steps —
actions/checkoutwrites a token to.git/configand leaves it there for the rest of the job by default. Settingpersist-credentials: falsemeans the token is only used to fetch and is then removed.Pass only the required secret to the features workflow —
features.ymlpreviously usedsecrets: inherit, forwarding every secret to the reusable workflow. It now passes onlyABLY_AWS_ACCOUNT_ID_SDK, which is the single named secret the called workflow declares.Pin third-party actions to commit SHAs — tag references like
@v4are mutable; pinning to a full commit SHA freezes the exact code that runs in CI. The tagged release isrecorded in a trailing comment so updates are still easy to review.
ably/featuresandeditorconfig-checker/action-editorconfig-checkerwere previously tracking@mainand are nowpinned to a specific commit.
Summary by CodeRabbit