Skip to content

ci: migrate workflow auth from PAT to GitHub App tokens - #3004

Merged
wwwillchen merged 1 commit into
dyad-sh:mainfrom
wwwillchen-bot:agent--1773431833069-1773431422
Mar 30, 2026
Merged

wwwillchen merged 1 commit into
dyad-sh:mainfrom
wwwillchen-bot:agent--1773431833069-1773431422

Conversation

@wwwillchen-bot

@wwwillchen-bot wwwillchen-bot commented Mar 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Migrated draft-stale-prs and label-rebase-prs GitHub Actions workflows from using a personal access token (PR_RW_GITHUB_TOKEN) to generating tokens via the Dyad GitHub App (actions/create-github-app-token@v2)
  • Improves security and auditability by using scoped, short-lived GitHub App tokens with explicit permissions instead of long-lived PATs

Test plan

  • Verify draft-stale-prs workflow runs successfully on its cron schedule (or trigger manually)
  • Verify label-rebase-prs workflow runs successfully when triggered by push to main
  • Confirm the GitHub App has the required permissions: contents: read, pull-requests: write, and issues: write (for draft-stale-prs)

πŸ€– Generated with Claude Code


Open with Devin

Switch draft-stale-prs and label-rebase-prs workflows from using
PR_RW_GITHUB_TOKEN (personal access token) to generating tokens via
the Dyad GitHub App, improving security and auditability.

Co-Authored-By: Claude <[email protected]>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Note

Gemini is unable to generate a summary for this pull request due to the file types involved not being currently supported.

@wwwillchen

Copy link
Copy Markdown
Collaborator

@BugBot run

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

Comment on lines +22 to +23
permission-contents: read
permission-pull-requests: write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

πŸ”΄ Missing permission-issues: write on app token causes issues.addLabels to fail

The label-rebase-prs.yml workflow creates a GitHub App token with only permission-contents: read and permission-pull-requests: write, but the script calls github.rest.issues.addLabels at line 74, which uses the POST /repos/{owner}/{repo}/issues/{issue_number}/labels endpoint. This endpoint requires the issues: write permission for GitHub Apps. Without it, the addLabels call will fail with a 403 permission error whenever the workflow tries to label a conflicting PR. The sibling workflow draft-stale-prs.yml correctly includes permission-issues: write (line 26), so this appears to be an oversight.

Suggested change
permission-contents: read
permission-pull-requests: write
permission-contents: read
permission-pull-requests: write
permission-issues: write
Open in Devin Review

Was this helpful? React with πŸ‘ or πŸ‘Ž to provide feedback.

@dyad-assistant

Copy link
Copy Markdown
Contributor

πŸ” Dyadbot Code Review Summary

Verdict: βœ… YES - Ready to merge

Reviewed by 3 independent agents: Correctness Expert, Code Health Expert, UX Wizard.

Clean, straightforward migration from PAT-based auth to GitHub App tokens. The changes are consistent across both workflow files, permissions are appropriately scoped, and the pattern follows best practices for GitHub Actions auth.

Issues Summary

No HIGH or MEDIUM issues found.

🟒 Low Priority Notes (1 item)
  • Redundant top-level permissions block - .github/workflows/draft-stale-prs.yml / .github/workflows/label-rebase-prs.yml - The top-level permissions: block now only governs the unused GITHUB_TOKEN since auth is handled by the App token. Consider setting it to permissions: {} or removing it to avoid confusion.
🚫 Dropped False Positives (3 items)
  • GraphQL convertPullRequestToDraft may fail with App token - Dropped: pull-requests: write is sufficient for this mutation per GitHub API docs. The claim about needing contents: write is speculative and unsupported.
  • Review comments sort order not guaranteed - Dropped: Pre-existing logic not introduced or affected by this PR. The PR only changes the auth mechanism.
  • Permission inputs may not be supported in v2 - Dropped: The permission-* inputs are documented and supported in actions/create-github-app-token@v2.

Generated by Dyadbot multi-agent code review

@greptile-apps

greptile-apps Bot commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR improves the CI security posture by replacing long-lived personal access tokens (PR_RW_GITHUB_TOKEN) with short-lived, scoped GitHub App tokens in two workflows (draft-stale-prs and label-rebase-prs). The change uses actions/create-github-app-token@v2 to generate tokens with explicit permission scopes, which is the recommended approach.

  • The draft-stale-prs.yml migration looks correct: it requests permission-contents: read, permission-pull-requests: write, and permission-issues: write, matching the REST and GraphQL operations performed. The only cosmetic issue is a now-redundant workflow-level permissions block for the unused GITHUB_TOKEN.
  • label-rebase-prs.yml has a likely runtime bug: it requests only permission-pull-requests: write but calls github.rest.issues.addLabels, which requires issues: write in GitHub's App permission model. This will likely result in a 403 Forbidden error when the workflow tries to apply the cc:rebase label.
  • Both workflows use actions/create-github-app-token@v2 with a mutable major-version tag rather than a pinned commit SHA β€” a supply-chain security consideration given that this action handles the App private key.

Confidence Score: 2/5

  • Not safe to merge as-is β€” label-rebase-prs.yml is missing issues: write permission, which will cause the label step to fail at runtime.
  • The overall migration direction is correct and a security improvement. However, label-rebase-prs.yml omits the issues: write permission required by the issues.addLabels API call, making the workflow functionally broken after this change. The draft-stale-prs.yml migration is correct but has a minor stale permissions block. The missing permission is a concrete runtime failure, not a theoretical concern.
  • .github/workflows/label-rebase-prs.yml β€” missing permission-issues: write for the issues.addLabels call.

Important Files Changed

Filename Overview
.github/workflows/draft-stale-prs.yml Migrates from PAT to GitHub App token using actions/create-github-app-token@v2; permissions for the App token are correct (contents: read, pull-requests: write, issues: write), but the now-unused workflow-level permissions block still grants elevated rights to GITHUB_TOKEN.
.github/workflows/label-rebase-prs.yml Migrates from PAT to GitHub App token, but the requested App token permissions omit issues: write, which is required by the issues.addLabels REST endpoint used to apply the cc:rebase label β€” likely causing a runtime 403 error.

Sequence Diagram

sequenceDiagram
    participant Runner as GitHub Actions Runner
    participant TokenAction as create-github-app-token
    participant GitHubApp as Dyad GitHub App
    participant ScriptAction as github-script
    participant API as GitHub REST/GraphQL API

    Runner->>TokenAction: app-id + private-key (scoped permissions)
    TokenAction->>GitHubApp: JWT exchange for installation token
    GitHubApp-->>TokenAction: Short-lived scoped token
    TokenAction-->>Runner: outputs.token

    Runner->>ScriptAction: Pass App token as github-token
    ScriptAction->>API: Authenticated REST and GraphQL calls
    API-->>ScriptAction: Responses (PR updates, labels, comments)
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: .github/workflows/label-rebase-prs.yml
Line: 22-23

Comment:
**Missing `issues: write` permission for label operations**

The `github.rest.issues.addLabels` call (line 74) uses the GitHub Issues REST API (`POST /repos/{owner}/{repo}/issues/{issue_number}/labels`). GitHub Apps require the `issues: write` permission to manage labels on issues and pull requests β€” `pull_requests: write` alone is not sufficient for this endpoint.

The `draft-stale-prs.yml` workflow correctly requests `permission-issues: write` for its comment creation (`issues.createComment`). By analogy, this workflow also needs `issues: write` for label management.

Without this permission, the App token will likely receive a `403 Forbidden` response when attempting to add the `cc:rebase` label.

```suggestion
          permission-contents: read
          permission-pull-requests: write
          permission-issues: write
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/draft-stale-prs.yml
Line: 8-11

Comment:
**Stale workflow-level `permissions` block**

Now that all privileged operations use the GitHub App token (from `steps.app-token.outputs.token`) rather than the built-in `GITHUB_TOKEN`, the top-level `permissions` block only applies to `GITHUB_TOKEN`, which is no longer used for any write operations. `pull-requests: write` and `issues: write` are therefore granted to an unused token. Consider reducing these to `contents: read` only (or removing the block entirely and relying on the org/repo default), to follow the principle of least privilege.

```suggestion
permissions:
  contents: read
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: .github/workflows/draft-stale-prs.yml
Line: 20

Comment:
**Action not pinned to a commit SHA**

`actions/create-github-app-token@v2` uses a mutable major-version tag. This action handles the GitHub App's private key (`DYAD_GITHUB_APP_PRIVATE_KEY`), making it a high-value supply-chain target. A compromised or accidentally updated tag could exfiltrate secrets. Best practice is to pin to a full commit SHA, e.g.:

```suggestion
        uses: actions/create-github-app-token@v2  # pin to a commit SHA, e.g. @<sha>
```

The same concern applies in `label-rebase-prs.yml` line 18.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 6ad8d49

Comment on lines +22 to +23
permission-contents: read
permission-pull-requests: write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing issues: write permission for label operations

The github.rest.issues.addLabels call (line 74) uses the GitHub Issues REST API (POST /repos/{owner}/{repo}/issues/{issue_number}/labels). GitHub Apps require the issues: write permission to manage labels on issues and pull requests β€” pull_requests: write alone is not sufficient for this endpoint.

The draft-stale-prs.yml workflow correctly requests permission-issues: write for its comment creation (issues.createComment). By analogy, this workflow also needs issues: write for label management.

Without this permission, the App token will likely receive a 403 Forbidden response when attempting to add the cc:rebase label.

Suggested change
permission-contents: read
permission-pull-requests: write
permission-contents: read
permission-pull-requests: write
permission-issues: write
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/label-rebase-prs.yml
Line: 22-23

Comment:
**Missing `issues: write` permission for label operations**

The `github.rest.issues.addLabels` call (line 74) uses the GitHub Issues REST API (`POST /repos/{owner}/{repo}/issues/{issue_number}/labels`). GitHub Apps require the `issues: write` permission to manage labels on issues and pull requests β€” `pull_requests: write` alone is not sufficient for this endpoint.

The `draft-stale-prs.yml` workflow correctly requests `permission-issues: write` for its comment creation (`issues.createComment`). By analogy, this workflow also needs `issues: write` for label management.

Without this permission, the App token will likely receive a `403 Forbidden` response when attempting to add the `cc:rebase` label.

```suggestion
          permission-contents: read
          permission-pull-requests: write
          permission-issues: write
```

How can I resolve this? If you propose a fix, please make it concise.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

2 issues found across 2 files

Confidence score: 2/5

  • High-confidence workflow breakage is likely: .github/workflows/label-rebase-prs.yml lacks issues: write, so github.rest.issues.addLabels should fail when trying to label PRs.
  • .github/workflows/draft-stale-prs.yml has the same permission gap (permission-issues: write missing), which can consistently block stale/draft labeling automation via the Issues API endpoint.
  • Given both findings are severity 8/10 with strong confidence and affect core PR automation behavior, this carries high merge risk until permissions are corrected.
  • Pay close attention to .github/workflows/label-rebase-prs.yml, .github/workflows/draft-stale-prs.yml - missing Issues write permissions will prevent label-adding steps from working.
Prompt for AI agents (unresolved issues)

Check if these issues are valid β€” if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".github/workflows/label-rebase-prs.yml">

<violation number="1" location=".github/workflows/label-rebase-prs.yml:23">
P1: Add `issues: write` to the app token permissions; labeling a PR uses the Issues API, so `addLabels` will fail with the current token.</violation>
</file>

<file name=".github/workflows/draft-stale-prs.yml">

<violation number="1" location=".github/workflows/draft-stale-prs.yml:25">
P1: Missing `permission-issues: write` β€” the script calls `github.rest.issues.addLabels` which uses `POST /repos/{owner}/{repo}/issues/{issue_number}/labels`. This endpoint requires `issues: write` permission for GitHub Apps, so the `addLabels` call will fail with a 403 error. The sibling `draft-stale-prs.yml` workflow correctly includes this permission.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

app-id: ${{ vars.DYAD_GITHUB_APP_ID }}
private-key: ${{ secrets.DYAD_GITHUB_APP_PRIVATE_KEY }}
permission-contents: read
permission-pull-requests: write

@cubic-dev-ai cubic-dev-ai Bot Mar 13, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1: Add issues: write to the app token permissions; labeling a PR uses the Issues API, so addLabels will fail with the current token.

Prompt for AI agents
Check if this issue is valid β€” if so, understand the root cause and fix it. At .github/workflows/label-rebase-prs.yml, line 23:

<comment>Add `issues: write` to the app token permissions; labeling a PR uses the Issues API, so `addLabels` will fail with the current token.</comment>

<file context>
@@ -13,9 +13,18 @@ jobs:
+          app-id: ${{ vars.DYAD_GITHUB_APP_ID }}
+          private-key: ${{ secrets.DYAD_GITHUB_APP_PRIVATE_KEY }}
+          permission-contents: read
+          permission-pull-requests: write
+
       - uses: actions/github-script@v7
</file context>
Suggested change
permission-pull-requests: write
permission-pull-requests: write
permission-issues: write
Fix with Cubic

app-id: ${{ vars.DYAD_GITHUB_APP_ID }}
private-key: ${{ secrets.DYAD_GITHUB_APP_PRIVATE_KEY }}
permission-contents: read
permission-pull-requests: write

@cubic-dev-ai cubic-dev-ai Bot Mar 13, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1: Missing permission-issues: write β€” the script calls github.rest.issues.addLabels which uses POST /repos/{owner}/{repo}/issues/{issue_number}/labels. This endpoint requires issues: write permission for GitHub Apps, so the addLabels call will fail with a 403 error. The sibling draft-stale-prs.yml workflow correctly includes this permission.

Prompt for AI agents
Check if this issue is valid β€” if so, understand the root cause and fix it. At .github/workflows/draft-stale-prs.yml, line 25:

<comment>Missing `permission-issues: write` β€” the script calls `github.rest.issues.addLabels` which uses `POST /repos/{owner}/{repo}/issues/{issue_number}/labels`. This endpoint requires `issues: write` permission for GitHub Apps, so the `addLabels` call will fail with a 403 error. The sibling `draft-stale-prs.yml` workflow correctly includes this permission.</comment>

<file context>
@@ -15,9 +15,19 @@ jobs:
+          app-id: ${{ vars.DYAD_GITHUB_APP_ID }}
+          private-key: ${{ secrets.DYAD_GITHUB_APP_PRIVATE_KEY }}
+          permission-contents: read
+          permission-pull-requests: write
+          permission-issues: write
+
</file context>
Fix with Cubic

@github-actions github-actions Bot added the needs-human:review-issue ai agent flagged an issue that requires human review label Mar 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🎭 Playwright Test Results

❌ Some tests failed

OS Passed Failed Flaky Skipped
🍎 macOS 256 2 7 6

Summary: 256 passed, 2 failed, 7 flaky, 6 skipped

Failed Tests

🍎 macOS

  • select_component.spec.ts > select component next.js
    • Error: expect(locator).toBeVisible() failed
  • template-create-nextjs.spec.ts > create next.js app
    • Error: expect(locator).toBeVisible() failed

πŸ“‹ Re-run Failing Tests (macOS)

Copy and paste to re-run all failing spec files locally:

npm run e2e \
  e2e-tests/select_component.spec.ts \
  e2e-tests/template-create-nextjs.spec.ts

⚠️ Flaky Tests

🍎 macOS

  • approve.spec.ts > write to index, approve, check preview (passed after 1 retry)
  • chat_tabs.spec.ts > right-click context menu: Close tabs to the right (passed after 1 retry)
  • fix_error.spec.ts > fix error with AI (passed after 1 retry)
  • new_chat.spec.ts > new chat (second button) (passed after 1 retry)
  • refresh.spec.ts > preview navigation - forward and back buttons work (passed after 1 retry)
  • setup_flow.spec.ts > Setup Flow > setup banner shows correct state when node.js is installed (passed after 1 retry)
  • setup.spec.ts > setup ai provider (passed after 1 retry)

πŸ“Š View full report

@wwwillchen
wwwillchen merged commit 871e3b4 into dyad-sh:main Mar 30, 2026
10 of 12 checks passed

This branch was previously deployed

1 inactive deployment
ai-bots β€” 6ad8d490 Deployed Mar 13, 2026 by wwwillchen-bot via claude-review #1825
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-human:review-issue ai agent flagged an issue that requires human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants