Repository navigation
Add write permissions for workflow contents - #261
Conversation
WalkthroughThe PR grants the Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 |
| types: [opened, synchronize, reopened] | ||
|
|
||
| permissions: | ||
| contents: write |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
GitHub Actions GITHUB_TOKEN permissions needed for issues.createLabel and pulls.listFiles API
💡 Result:
To call these GitHub REST APIs from a GitHub Actions workflow using the built-in GITHUB_TOKEN, set the workflow/job permissions to the minimum scopes below. 1) issues.createLabel (create a label) Required GITHUB_TOKEN permission scope: issues: write (because creating/modifying issue labels is an “issues” write operation). In workflows, you control token access with the permissions key, and you can grant least-privilege per job/workflow. [1][2] Example: permissions: issues: write contents: read 2) pulls.listFiles (List files for a pull request) Required GITHUB_TOKEN permission scope: contents: read (listing PR files is repo-content read). Use the permissions key to grant least-privilege for the GITHUB_TOKEN. [1][2] Example: permissions: contents: read Notes / gotchas - Ensure you actually include the needed scopes in the workflow/job; any unspecified permissions are set to none when you use the permissions key. [2] - If you need capabilities not available via GITHUB_TOKEN, GitHub recommends using a GitHub App installation token or a PAT instead. [1]
Citations:
- 1: https://docs.github.com/actions/reference/authentication-in-a-workflow
- 2: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/large-pr-labeler.yml"
echo "== file: $FILE =="
wc -l "$FILE"
nl -ba "$FILE" | sed -n '1,120p'
echo
echo "== grep permissions key =="
rg -n "permissions:|contents:|issues:|pull-requests:" "$FILE" || true
echo
echo "== grep for GitHub REST API usage =="
rg -n "github\\.rest\\.|actions/github-script|listFiles|getLabel|createLabel|addLabels|removeLabel" "$FILE" || trueRepository: yarsa/nepal-compliance
Length of output: 220
🌐 Web query:
GitHub REST pulls.listFiles GITHUB_TOKEN required permissions contents: read
💡 Result:
For the GitHub REST endpoint GET /repos/{owner}/{repo}/pulls/{pull_number}/files (GitHub API “List pull requests files”, i.e., github.rest.pulls.listFiles), the documentation excerpt we found does not specify any particular OAuth/PAT “required permission scopes” (like contents: read or pull-requests: read). It is, however, the Pull Requests Files endpoint itself. [1][2] What you should do with GITHUB_TOKEN / fine-grained PAT permissions: 1) If you’re calling it from GitHub Actions using the default GITHUB_TOKEN, ensure the workflow/job has “read” access to pull request data by setting explicit minimal job permissions. Example pattern (adjust as needed): permissions: pull-requests: read contents: read This matches how GitHub Actions permissions are configured for PR-related APIs in practice. [3][4] 2) If you’re using a fine-grained PAT, GitHub returns an “X-Accepted-GitHub-Permissions” header that tells you what permission(s) are required; GitHub’s fine-grained token guidance explicitly says to use that header to determine required permissions for an endpoint. [5] Key takeaway: “contents: read” is not shown in the authoritative endpoint documentation we found for pulls.listFiles; instead, the most reliable way to determine the exact permission(s) required for your specific repository visibility (public/private), token type (GITHUB_TOKEN vs fine-grained PAT), and resource access is to (a) set minimal PR read permissions in workflows, and (b) rely on X-Accepted-GitHub-Permissions for fine-grained PATs. [3][4][5]
Citations:
- 1: https://github.apifox.cn/api-5363660
- 2: https://github.apidog.io/api-3489533
- 3: https://github.com/tj-actions/changed-files/blob/main/README.md
- 4: https://github.com/tj-actions/changed-files/tree/ff2f6e6b91913a7be42be1b5917330fe442f2ede
- 5: https://docs.github.com/en/enterprise-cloud@latest/rest/authentication/permissions-required-for-fine-grained-personal-access-tokens?apiVersion=2022-11-28
🌐 Web query:
GitHub REST issues.createLabel required permissions issues: write
💡 Result:
To create a label using the GitHub REST API (POST /repos/{owner}/{repo}/labels) or to apply labels to an issue that do not already exist, the authenticated user or application must have push access to the repository [1][2][3]. In the context of GitHub Actions workflows using the GITHUB_TOKEN, this requirement translates to needing the issues: write permission [3]. If this permission is not explicitly set in your workflow file, the GITHUB_TOKEN may lack the necessary authority, causing attempts to create labels (or apply non-existent labels) to fail [3]. For example, to ensure your workflow has the correct permissions, you should include the following block in your configuration: permissions: issues: write While pull-requests: write may be sufficient for applying existing labels to pull requests, creating new labels or applying labels that are not yet defined in the repository requires the broader issues: write access [3]. Users without sufficient push access may find that labels are silently dropped during issue creation [4][5].
Citations:
- 1: https://docs.github.com/rest/issues/labels
- 2: [BUG]: New label is not created on creating a new github issue octokit/rest.js#479
- 3: HttpError: You do not have permission to create labels on this repository actions/labeler#870
- 4: https://docs.github.com/rest/issues/issues
- 5: https://stackoverflow.com/questions/22779873/create-an-issue-with-labels-via-github-api
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/large-pr-labeler.yml"
echo "== file: $FILE =="
wc -l "$FILE"
nl -ba "$FILE" | sed -n '1,200p'
echo
echo "== permissions block =="
rg -n "permissions:|contents:|issues:|pull-requests:" "$FILE" || true
echo
echo "== GitHub API / github-script usage =="
rg -n "github\\.rest\\.|actions/github-script|listFiles|getLabel|createLabel|addLabels|removeLabel" "$FILE" || trueRepository: yarsa/nepal-compliance
Length of output: 220
🌐 Web query:
GitHub REST pulls.listFiles GITHUB_TOKEN required permissions contents: read
💡 Result:
To use the GitHub REST API endpoint GET /repos/{owner}/{repo}/pulls/{pull_number}/files (often referred to as pulls.listFiles in SDKs like actions/github-script), you must have the appropriate permissions. When using the GITHUB_TOKEN in a GitHub Actions workflow, the required permission scope is: permissions: pull-requests: read This permission allows the GITHUB_TOKEN to read metadata about pull requests, including the list of files changed in a pull request [1][2][3]. Note that contents: read is typically required to check out repository code or read file contents [4][1][5], but pull-requests: read is the specific permission required to access pull request metadata via the REST API [2][3]. If your workflow does not explicitly set permissions, the GITHUB_TOKEN may default to broader permissions depending on your repository or organization settings, which is generally discouraged in favor of the principle of least privilege [6][1].
Citations:
- 1: https://dev.to/freerave/teampcp-broke-github-and-nobody-saw-it-coming-but-they-should-have-3opg
- 2: https://github.com/tj-actions/changed-files/blob/main/README.md
- 3: https://github.com/tj-actions/changed-files/tree/ff2f6e6b91913a7be42be1b5917330fe442f2ede
- 4: https://dev.to/vasiliy0/run-a-no-token-cicd-preflight-before-your-next-release-2l7l
- 5: https://dev.to/josh_blair/zero-secret-cicd-github-actions-oidc-on-aws-part-6-22e7
- 6: https://docs.github.com/en/rest/actions/permissions
🌐 Web query:
GitHub REST issues.createLabel required permissions issues: write
💡 Result:
To create a label using the GitHub REST API (POST /repos/{owner}/{repo}/labels), you must have write access to the repository [1][2]. When using fine-grained personal access tokens (PATs) or GitHub Apps, this requires the following repository permissions: - Issues: Write [2] - Pull requests: Write [2] Having at least one of these "write" permission sets is sufficient to authorize the creation of labels [2]. If you are using traditional OAuth scopes, you generally need scope levels that grant push access to the repository (such as the repo scope) [3]. Note that for other actions, such as setting labels on a new issue during its creation (POST /repos/{owner}/{repo}/issues), the labels must already exist in the repository [4]. If a label does not exist, it may be silently dropped, and attempting to apply it requires appropriate write permissions as well [5][4][3].
Citations:
- 1: https://docs.github.com/rest/issues/labels
- 2: https://docs.github.com/enterprise-server@3.13/rest/issues/labels
- 3: https://stackoverflow.com/questions/22779873/create-an-issue-with-labels-via-github-api
- 4: [BUG]: New label is not created on creating a new github issue octokit/rest.js#479
- 5: https://docs.github.com/rest/issues/issues
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/large-pr-labeler.yml"
echo "== file header =="
sed -n '1,120p' "$FILE"
echo
echo "== permissions block lines (if any) =="
rg -n "^(permissions:|[[:space:]]+(contents|issues|pull-requests):)" "$FILE" || true
echo
echo "== github-script / rest API usage =="
rg -n "github\.rest\.|actions/github-script|pulls\.listFiles|getLabel|createLabel|addLabels|removeLabel|issues\.addLabels|issues\.removeLabel" "$FILE" || trueRepository: yarsa/nepal-compliance
Length of output: 3146
🌐 Web query:
permissions pull-requests: read pulls.listFiles GITHUB_TOKEN
💡 Result:
For GitHub Actions, to read pull requests (including file listings for a PR), you typically need the workflow permission pull-requests: read when calling the REST API with the built-in GITHUB_TOKEN; GitHub lets you control these permissions via the workflow/job permissions key, and any permission not specified is set to none.[1]
Citations:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/large-pr-labeler.yml"
echo "== file header =="
sed -n '1,160p' "$FILE"
echo
echo "== permissions-related lines =="
rg -n "^(permissions:|[[:space:]]+(contents|issues|pull-requests):)" "$FILE" || true
echo
echo "== github REST / github-script usage =="
rg -n "github\.rest\.|actions/github-script|pulls\.listFiles|getLabel|createLabel|addLabels|removeLabel|issues\.addLabels|issues\.removeLabel" "$FILE" || trueRepository: yarsa/nepal-compliance
Length of output: 3142
🌐 Web query:
permissions pull-requests: read pulls.listFiles GITHUB_TOKEN
💡 Result:
To grant a GitHub Actions workflow the ability to read pull request data (such as listing files in a pull request), you must configure the permissions key in your workflow file [1][2]. The correct permission scope is pull-requests: read [1][3]. Configuration Example: You can define this at the job level (recommended for least privilege) or the workflow level [4][1]. jobs: my-job: runs-on: ubuntu-latest permissions: pull-requests: read steps: - name: List files run: gh pr diff --name-only ${{ github.event.pull_request.number }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} Key Details: 1. Scope Name: The correct permission scope is pull-requests, not pulls [2][5]. Using pulls: read is not a valid configuration in the workflow syntax [2]. 2. Least Privilege: When you use the permissions key, all unspecified permissions are set to none (except for metadata, which always has read access) [1][2]. Therefore, if you need other access (like contents: read to checkout your code), you must explicitly include those as well [2][6]. 3. Security Warning: If a workflow is triggered by a pull request from a forked repository, the GITHUB_TOKEN is automatically downgraded to read-only permissions for security reasons, regardless of your explicit settings [2][7]. 4. Accessing Pull Request Data: Using pull-requests: read allows your workflow to use the GitHub API (via gh CLI or actions/github-script) to read information about pull requests, including listing files [8][3].
Citations:
- 1: https://dev.to/github/the-githubtoken-in-github-actions-how-it-works-change-permissions-customizations-3cgp
- 2: https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/
- 3: Add missing GitHub permissions to workflows using GitHub API toolsets github/gh-aw#10020
- 4: https://github.com/github/docs/blob/main/content/actions/tutorials/authenticate-with-github_token.md
- 5: https://dev.to/pwd9000/fgjgghjgh-19ka
- 6: https://dev.to/grigorkh/ai-agents-in-cicd-give-them-context-not-production-authority-3fh2
- 7: Clarify
How the permissions are calculated for a workflow jobgithub/docs#32398 - 8: https://stackoverflow.com/questions/59077079/how-to-get-pull-request-number-within-github-actions-workflow
Over-scoped GITHUB_TOKEN perms in .github/workflows/large-pr-labeler.yml — drop contents: write (and downgrade pull-requests: write)
This workflow only:
- Manages labels via
issues.*→ needsissues: write - Reads PR file list via
pulls.listFiles→ needspull-requests: read(notpull-requests: write)
There’s no repo-content write usage (no checkout, no commits/releases), socontents: writeis pure principle-of-least-privilege pain—and extra blast radius if the token is ever abused.
Use the minimal perms, e.g.:
issues: writepull-requests: read- remove
contents: write(usecontents: readonly if GitHub requires it for your exact API response).
This pull request makes a minor update to the workflow configuration by adjusting permissions in the
.github/workflows/large-pr-labeler.ymlfile.contentspermission from its previous value (default or none) towritein the workflow configuration.