GITHUB_TOKEN returns HTTP 403 when reading PR comments despite Issues: read #210157
Replies: 4 comments
|
1. The request isn't hitting the repo the token is scoped to. 2. A different token is actually being sent. env:
TOKEN: ${{ github.token }}headers = {"Authorization": f"Bearer {os.environ['TOKEN']}",
"Accept": "application/vnd.github+json"}3. Job-level Quick isolation test (same job, before your script): - run: gh api "repos/${{ github.repository }}/issues/${{ github.event.issue.number }}/comments" --jq 'length'
env:
GH_TOKEN: ${{ github.token }}If this works, the problem is in how the script builds the request (URL or token). If it also fails with 403, add permissions:
contents: read
issues: read
pull-requests: readNo PAT needed. |
|
I think, your token’s probably fine. It’s what the token can actually reach that’s the issue. That “Issues: read” in the setup log? It just shows what your workflow asked for. Doesn’t mean you got it. If your org or repo has a default cap (Settings -> Actions -> General -> Workflow permissions), that cap wins over your YAML. Also, if there’s a job-level permissions: block anywhere, it wipes out the workflow-level one. Anything you didn’t list there goes to none. Sneaky. The 4997 rate limit thing is a hint too. The request went through as authenticated, so it’s a straight-up “you’re not allowed” and not a rate limit or bad token. also, comments stay readable after merge. But issue_comment workflows always run from the default branch’s workflow file, and if the PR came from a fork or Dependabot, GitHub gives you a nerfed token no matter what you wrote. Check if that’s your case. Easiest fix, just add pull-requests: read. That header literally listed it as an accepted option: Still read-only, still GITHUB_TOKEN, no PAT needed. If it still 403s, check these: hope this helpsss |
|
I'd start by isolating whether the 403 comes from the API request itself or from how the workflow token and repository are being resolved. A few checks that may help:
I wouldn't assume the merged state is the cause. The key is to identify why this particular request is denied despite the reported permissions. If the CLI test also returns 403, inspect repository policy and the event's token context before changing authentication methods. This should help narrow it down without introducing a PAT or granting write permissions. |
|
Your permissions look fine to me. What caught my attention was the rate limit shown in the 403 response. The Your response showed 4,997 requests remaining, which suggests the request might be using a different token instead of the workflow's Also, the I'd check these three things first:
You can verify this without exposing the token by adding the following step: - name: Check token rate limit
env:
GH_TOKEN: ${{ github.token }}
run: |
gh api -i "repos/${GITHUB_REPOSITORY}/issues/${{ github.event.issue.number }}/comments?per_page=1" \
| grep -iE '^(HTTP|x-ratelimit-limit|x-ratelimit-resource)'If everything is configured correctly, you should get a Then, in your Python script, log only As for your three questions:
In your workflow: env:
COMMENTS_TOKEN: ${{ github.token }}And in Python: token = os.environ["COMMENTS_TOKEN"]I'd start there, since the most likely explanation is that your script is picking up a different token than the one you intended to use. |
Uh oh!
There was an error while loading. Please reload this page.
🏷️ Discussion Type
Question
💬 Feature/Topic Area
Workflow Configuration
Discussion Details
Hello,
I'm investigating a GitHub Actions authorization problem in a private repository.
An "issue_comment" (created) event successfully triggers my workflow.
The workflow declares:
"permissions: contents: read, issues: read"
The job setup log confirms "Issues: read".
A Python script uses the workflow-issued "${{ github.token }}" to call:
"GET /repos/{owner}/{repo}/issues/{pr_number}/comments?per_page=100&page=1"
However, GitHub responds with:
The "X-Accepted-GitHub-Permissions" header lists "issues=read" or "pull_requests=read" as accepted alternatives.
The PR is already merged and contains comments. Another authorized GitHub integration can retrieve the comments, but it uses a different authentication identity.
My questions:
The workflow intentionally fails closed when comment history cannot be verified.
Thank you for your help.
All reactions