Skip to content

ci(swift-sdk): add workflow permissions for PR comment posting#3158

Closed
thepastaclaw wants to merge 1 commit intodashpay:v3.1-devfrom
thepastaclaw:ci/swift-sdk-comment-permissions
Closed

ci(swift-sdk): add workflow permissions for PR comment posting#3158
thepastaclaw wants to merge 1 commit intodashpay:v3.1-devfrom
thepastaclaw:ci/swift-sdk-comment-permissions

Conversation

@thepastaclaw
Copy link
Contributor

@thepastaclaw thepastaclaw commented Feb 25, 2026

Summary

The Swift SDK build workflow's post-build step uses actions/github-script@v7 to post PR comments with artifact/xcframework info. It calls github.rest.issues.createComment and github.rest.issues.updateComment, which require issues: write permission.

Without an explicit permissions block, the workflow inherits the repo default (read-only for GITHUB_TOKEN on fork PRs), causing a 403 error that fails the entire CI check — even though the xcframework build itself succeeded.

Changes

Added a workflow-level permissions block to .github/workflows/swift-sdk-build.yml:

  • contents: read — required for actions/checkout
  • pull-requests: write — required for PR interaction
  • issues: write — required for issues.createComment/updateComment API calls

Context

Observed on PR #3137 where the Swift SDK build succeeded but the comment posting step 403'd, failing CI.

Summary by CodeRabbit

Release Notes

Chores

  • Updated CI/CD workflow permissions to follow security best practices.

Note: This release contains only internal infrastructure updates with no user-facing changes.

The Swift SDK build workflow's post-build step posts a PR comment with
artifact/xcframework info using actions/github-script, which calls
github.rest.issues.createComment. This requires issues: write and
pull-requests: write permissions.

Without explicit permissions, the workflow inherits the repository
default (read-only), causing the comment step to fail with 403:
'Resource not accessible by integration'. This marks the entire CI
check as failed even though the actual build succeeded.

Add workflow-level permissions block with:
- contents: read (required for checkout)
- pull-requests: write (required for PR interaction)
- issues: write (required for issues.createComment/updateComment API)

Fixes the failing check on PR dashpay#3137.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

📝 Walkthrough

Walkthrough

Added explicit GitHub Actions workflow permissions (contents: read, pull-requests: write, issues: write) to the top-level permissions block in the swift-sdk-build.yml workflow file, enhancing security by declaring required access levels.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow Permissions
.github/workflows/swift-sdk-build.yml
Added explicit permissions block declaring required access levels: read for contents, write for pull-requests and issues.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Poem

🐰 A rabbit skips through workflows with cheer,
With permissions explicit and clear—
Read, write, and more to see,
GitHub Actions wild and free! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding workflow permissions to enable PR comment posting in the Swift SDK build workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/swift-sdk-build.yml (1)

16-19: pull-requests: write is not required by any step in this workflow.

The comment step only calls github.rest.issues.listComments, github.rest.issues.createComment, and github.rest.issues.updateComment — all of which require issues: write, not pull-requests: write. The extra scope is harmless but violates least-privilege.

♻️ Proposed fix
 permissions:
   contents: read
-  pull-requests: write
   issues: write
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/swift-sdk-build.yml around lines 16 - 19, Remove the
unnecessary "pull-requests: write" permission under the workflow's permissions
block; keep "contents: read" and "issues: write" since the job only calls
github.rest.issues.* methods, and ensure the permissions object only grants
least-privilege (i.e., delete the pull-requests: write entry referencing the
permissions block and value "pull-requests: write").
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/swift-sdk-build.yml:
- Around line 16-19: The added permissions block (permissions: / contents: read
/ pull-requests: write / issues: write) won't grant write access for PRs from
external forks because GitHub downgrades GITHUB_TOKEN for forked PRs; fix by
implementing one of the recommended approaches: (1) split the workflow: keep the
current pull_request job for building/uploading artifacts (no write needed) and
add a separate workflow triggered by workflow_run in the base-repo context to
download the artifact and post comments, (2) enable the repo-level "Send write
tokens to workflows from pull requests" setting if acceptable, or (3) change the
trigger to pull_request_target only if you ensure the workflow does not check
out or execute untrusted PR code; reference the permissions block, issues:
write, pull_request trigger, workflow_run, and pull_request_target when making
the change.

---

Nitpick comments:
In @.github/workflows/swift-sdk-build.yml:
- Around line 16-19: Remove the unnecessary "pull-requests: write" permission
under the workflow's permissions block; keep "contents: read" and "issues:
write" since the job only calls github.rest.issues.* methods, and ensure the
permissions object only grants least-privilege (i.e., delete the pull-requests:
write entry referencing the permissions block and value "pull-requests: write").

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b5a9c4 and e5da9f3.

📒 Files selected for processing (1)
  • .github/workflows/swift-sdk-build.yml

Comment on lines +16 to +19
permissions:
contents: read
pull-requests: write
issues: write
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if the dashpay/platform repo has PR `#3137` and its origin
cd /tmp && git clone --depth=1 https://github.com/dashpay/platform.git 2>&1 | head -20

Repository: dashpay/platform

Length of output: 1475


🌐 Web query:

GitHub Actions permissions block fork pull request write access token restrictions official documentation

💡 Result:

  • Default restriction for fork PRs: Workflows triggered by a pull request from a fork run with a read-only GITHUB_TOKEN and do not receive secrets (except GITHUB_TOKEN). [1]
  • Why “write” is blocked: Even if your workflow sets permissions: write-all (or specific write scopes), fork PR workflows typically still can’t get write access—the repo/admin setting overrides this. [2]
  • The admin/owner override (the main switch): A repo/org/enterprise admin can explicitly allow write-capable tokens by enabling “Send write tokens to workflows from pull requests” (and separately can allow secrets). [3]
  • Important exception (pull_request_target): If you use pull_request_target, GitHub grants read/write repo permission to GITHUB_TOKEN even when triggered from a public fork, because the workflow runs in the base repository context (this is powerful and risky if you execute untrusted PR code). [2]

Official docs to cite for this behavior:

  • Fork PR read-only token + no secrets: GitHub “Events that trigger workflows” → Workflows in forked repositories [1]
  • permissions behavior + fork limitation + pull_request_target read/write note: GitHub “Workflow syntax” [2]
  • Admin policy/setting “Send write tokens to workflows from pull requests”: GitHub “Enforcing policies for GitHub Actions…” [3]

Sources: [1] (docs.github.com) [2] (docs.github.com) [3] (docs.github.com)

Citations:


🌐 Web query:

GitHub pull_request_target event workflow write permissions fork security

💡 Result:

pull_request_target is the “privileged” PR trigger in GitHub Actions, and it’s risky with forks because it runs in the base repo context (trusted workflow from the base branch) but is triggered by activity coming from an untrusted fork PR.

What changes vs pull_request (fork security model)

  • pull_request from forks: GITHUB_TOKEN is read-only and no secrets are provided (safe-by-default for untrusted contributions). (docs.github.com)
  • pull_request_target: GITHUB_TOKEN is read/write by default (unless you restrict via permissions:) and the workflow can access secrets, even when triggered from a fork. (docs.github.com)

The core vulnerability (“pwn request”)

If a pull_request_target workflow checks out the PR’s head commit/branch and then builds/tests/executes anything from it, an attacker can run code with base-repo privileges (exfiltrate secrets, push commits, create releases, poison caches, etc.). (docs.github.com)

When pull_request_target is appropriate

Use it only for actions that treat PR content as data, not executable code—e.g., labeling, commenting, triage, metadata updates. (docs.github.com)

Safer patterns

  • Prefer split workflows: run untrusted CI on pull_request, then do privileged actions in a separate workflow triggered by workflow_run. (codeql.github.com)
  • Least-privilege tokens: explicitly set permissions: (don’t rely on defaults), granting only what the job needs. (docs.github.com)
  • If you must gate privileged runs: require a maintainer action (for example, a “safe to test” label) before running anything sensitive—GitHub Security Lab notes this helps but can still have race-condition pitfalls. (securitylab.github.com)

If you share your workflow YAML (especially any actions/checkout usage and permissions: blocks), I can point out the exact fork-to-write escalation paths and how to restructure it safely.

Citations:


🏁 Script executed:

# Check the swift-sdk-build.yml workflow file
cat -n /tmp/platform/.github/workflows/swift-sdk-build.yml | head -30

Repository: dashpay/platform

Length of output: 996


🏁 Script executed:

# Look for PR `#3137` in git history/refs or check recent PRs
cd /tmp/platform && git log --all --oneline --grep="3137" | head -10

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Check if we can get PR details using git 
cd /tmp/platform && git show-ref | grep -i pull | head -20

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Read lines 16-30 to see the permissions block area
cd /tmp/platform && sed -n '16,30p' .github/workflows/swift-sdk-build.yml

Repository: dashpay/platform

Length of output: 441


🏁 Script executed:

# Read lines 170-250 to see the comment step
cd /tmp/platform && sed -n '170,250p' .github/workflows/swift-sdk-build.yml

Repository: dashpay/platform

Length of output: 3677


🏁 Script executed:

# Check git log for recent changes to this workflow
cd /tmp/platform && git log --oneline -10 -- .github/workflows/swift-sdk-build.yml

Repository: dashpay/platform

Length of output: 140


🏁 Script executed:

# Try to find if there are any branches or tags related to PR `#3137`
cd /tmp/platform && git show-ref | grep -E "(3137|swift-sdk-build)" | head -20

Repository: dashpay/platform

Length of output: 42


🏁 Script executed:

# Check if there's a PR branch or recent tag
cd /tmp/platform && git for-each-ref --sort=-creatordate --format='%(refname:short) %(creatordate:short)' refs/ | head -20

Repository: dashpay/platform

Length of output: 129


The permissions block cannot grant write access for external fork PRs—this fix is incomplete.

GitHub's security model mandates that pull requests from public forks always receive a read-only GITHUB_TOKEN, regardless of the permissions block settings in the workflow. This means the added permissions block will only fix the 403 for PRs opened from same-repo branches (i.e., from collaborators with push access).

If PR #3137 originated from an external fork, the issues: write permission will be silently downgraded to read-only by GitHub, and the comment step will continue to fail with a 403.

To reliably post comments for fork PRs, use one of these approaches:

  1. Split workflow (recommended): Create a separate workflow_run-triggered job that runs in the base-repo context:

    • The pull_request job builds artifacts and uploads them (no write needed).
    • A workflow_run job then runs after completion, retrieves the artifact, and posts the comment with write access.
  2. Repository setting: Enable "Send write tokens to workflows from pull requests" in the repo settings. This grants write permissions to fork PR workflows—note that this carries security implications, especially with self-hosted runners.

  3. pull_request_target event: Use pull_request_target instead of pull_request to run in the base-repo context with write access. Only use this if the workflow does not check out and execute untrusted PR code, as it creates a "pwn request" vulnerability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/swift-sdk-build.yml around lines 16 - 19, The added
permissions block (permissions: / contents: read / pull-requests: write /
issues: write) won't grant write access for PRs from external forks because
GitHub downgrades GITHUB_TOKEN for forked PRs; fix by implementing one of the
recommended approaches: (1) split the workflow: keep the current pull_request
job for building/uploading artifacts (no write needed) and add a separate
workflow triggered by workflow_run in the base-repo context to download the
artifact and post comments, (2) enable the repo-level "Send write tokens to
workflows from pull requests" setting if acceptable, or (3) change the trigger
to pull_request_target only if you ensure the workflow does not check out or
execute untrusted PR code; reference the permissions block, issues: write,
pull_request trigger, workflow_run, and pull_request_target when making the
change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants