Conversation
🧩 Plugin PR Summaryℹ️ No plugins were modified in this PR. |
There was a problem hiding this comment.
LGTM — the cleanup logic is correct and mirrors the deploy workflow pattern.
Extended reasoning...
Overview
Adds a single new GitHub Actions workflow () that triggers on PR close. It installs the SquaredUp CLI, lists all deployed plugins, filters for those whose display name ends with (matching the suffix applied by the deploy workflow), and deletes them.
Security risks
The only flag is the missing block, already surfaced as an inline nit. The workflow never calls any GitHub API and has no need for any GITHUB_TOKEN scope. Adding is a straightforward least-privilege improvement but does not represent an active vulnerability.
Level of scrutiny
Low — this is a self-contained CI automation file with no plugin code changes and no plugin version bumps required. The logic is simple and directly mirrors the companion pattern. No production plugin data is at risk; the worst outcome of a bug here is a failed cleanup (leaving orphaned test deployments), not data corruption.
Other factors
No prior reviews exist on this PR. The companion workflow explicitly sets , confirming the team is already familiar with least-privilege declarations — so the fix is trivial once the author sees the inline comment.
| jobs: | ||
| cleanup: | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🟡 The cleanup workflow has no explicit permissions block, so it inherits the repository's default GITHUB_TOKEN permissions (which may include broad write access). Since this workflow only uses SQUAREDUP_API_KEY and never needs the GITHUB_TOKEN, adding permissions: {} would enforce least privilege and reduce blast radius.
Extended reasoning...
What the bug is: The pr-cleanup.yaml workflow omits an explicit permissions block entirely. When no permissions block is specified, a GitHub Actions workflow inherits the repository's default GITHUB_TOKEN permissions. Depending on organization and repository settings, those defaults can include write access to contents, issues, pull-requests, and other scopes.
The specific code path: Lines 7–9 define the cleanup job with only runs-on: ubuntu-latest and no permissions: key. The companion workflow pr-run.yaml explicitly declares permissions: pull-requests: write because it needs to post PR comments — demonstrating the team is already aware of the principle of least privilege. The cleanup workflow simply lacks the analogous declaration.
Why existing code doesn't prevent it: There is no permissions key at either the workflow level or the job level in pr-cleanup.yaml. GitHub's default behavior is to grant whatever the repository's default token permissions are, which is an implicit grant rather than an explicit, auditable one.
Impact: The GITHUB_TOKEN is minted and injected into every workflow run automatically. Even though no step currently uses it, a token with broad write permissions exists in the runner environment. If the workflow is ever compromised (e.g., via a malicious dependency in the @squaredup/cli package), the token could be exfiltrated and used to push code, create releases, modify issues, or take other privileged actions against the repository. Setting permissions: {} would make the minted token essentially useless, minimizing blast radius.
How to fix it: Add an explicit empty permissions block to the job (or at the workflow level):
jobs:
cleanup:
runs-on: ubuntu-latest
permissions: {}Step-by-step proof:
- GitHub mints a GITHUB_TOKEN for every workflow run and injects it as
secrets.GITHUB_TOKENand theGITHUB_TOKENenvironment variable. - Without a
permissions:block, the token's scopes are set by the repository's "Default permissions" setting (Settings → Actions → General). Many repos default to "Read and write permissions" for all scopes. - The
pr-cleanup.yamlworkflow never calls any GitHub API and has noactions/checkoutstep — confirming it has zero need for any GITHUB_TOKEN scope. - A supply-chain attack on
@squaredup/clicould readGITHUB_TOKENfrom the environment and use it to e.g. push a commit or create a release, since the token would carry write permissions. - Adding
permissions: {}would cause GitHub to mint a token with no scopes, making it inert even if exfiltrated.
📋 Summary
🔍 Scope of change
- [ ] Documentation only- [ ] Repository metadata or configuration- [ ] Other (please describe):📚 Checklist