google-gemini / google-gemini/gemini-cli
CI: six workflows have no explicit permissions block
- Dominant language
- TypeScript
- Stars
- 107k
- Forks
- 14.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 45
Description
### What happened?
Six workflows don't declare a `permissions:` block, so the `GITHUB_TOKEN` they receive falls back to the repository/org default instead of being scoped to what they need:
- `.github/workflows/deflake.yml`
- `.github/workflows/docs-rebuild.yml`
- `.github/workflows/issue-opened-labeler.yml`
- `.github/workflows/links.yml`
- `.github/workflows/tools-python-ci.yml`
- `.github/workflows/trigger_e2e.yml`
The other 41 workflows in the repo do declare one, and the repo is clearly deliberate about supply-chain hygiene elsewhere — actions are pinned to full SHAs with `# ratchet:` comments, and checkouts use `persist-credentials: false`. These six look like they were missed rather than intentionally left open.
Reviewing what each actually needs:
| Workflow | Needs | Why |
| --- | --- | --- |
| `deflake.yml` | `contents: read` | checkout, `npm ci`, build, docker |
| `links.yml` | `contents: read` | checkout + lychee link check |
| `tools-python-ci.yml` | `contents: read` | checkout + setup-python + tests |
| `trigger_e2e.yml` | `contents: read` | shell steps + upload-artifact |
| `issue-opened-labeler.yml` | `issues: write` | falls back to `secrets.GITHUB_TOKEN` and calls `issues.addLabels` |
| `docs-rebuild.yml` | none (`{}`) | only `curl`s `secrets.DOCS_REBUILD_URL`; never touches the GitHub API |
`issue-opened-labeler.yml` is worth calling out: it uses a GitHub App token when `APP_ID` is set but falls back to `secrets.GITHUB_TOKEN` otherwise (`github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'`), and then calls `issues.get` and `issues.addLabels`. So it genuinely needs `issues: write` — pinning it to `read` would break labeling on the fallback path.
To be clear about severity: this is hardening, not a live vulnerability. If the repo default is already read-only, behavior doesn't change. The value is that these six stop depending on that default.
### What did you expect to happen?
Every workflow declares the minimum `permissions:` it needs, as the other 41 already do.
### Client information
Not a runtime issue — it's a configuration gap in `.github/workflows/` on current `main` (package version `0.56.0-nightly.20260806.g761f604c1`).
Reproducible with: `for f in .github/workflows/*.yml; do grep -q "permissions:" "$f" || echo "$f"; done`
Contributor guide
Research direction
Review the six named files under .github/workflows/ and compare their requirements with the 41 workflows that already declare permissions. Add the minimum permissions listed for each workflow, then rerun the provided grep command and verify the workflows still support their described actions, including fallback labeling in issue-opened-labeler.yml.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, yaml
- Domain
- ci-cd, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100