Resource not accessible by integration - GITHUB_TOKEN scopes
Error: Resource not accessible by integration
Focused incident mode — strips away everything but this runbook.
Symptoms
- Error: Resource not accessible by integration
- Error: HttpError: Not Found - token lacks actions or issues scope
- OIDC token request fails: id-token permission missing
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Workflow permissions block
cat .github/workflows/<file>.yml | grep -A15 'permissions'Failed API call in the logs
gh run view <RUN_ID> --log-failed | grep -E 'Not Found|accessible|403|404'
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- Step uses actions/github-script to request an OIDC token
- Error: 'id-token permission is missing'
Confirm before fixing
cat .github/workflows/<file>.yml | grep 'id-token'Check if id-token: write is present
Fix
sed -i '/permissions:/a\ id-token: write' .github/workflows/<file>.ymlAdd id-token: write for OIDC federation
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
gh run view <RUN_ID> --log-failed | grep -E 'accessible|403|404'Identify the exact API call that was denied
cat .github/workflows/<file>.yml | grep -A20 'permissions'Read the permissions block
sed -i '/permissions:/a\ contents: read\n pull-requests: write' .github/workflows/<file>.ymlAdd the needed scopes
Prevention
- Always declare an explicit permissions block in workflows rather than relying on defaults.
- Use the principle of least privilege: only grant what each job needs.
- Review permissions after adding new steps that call the GitHub API.
- Set organization-level default token permissions to 'restricted' to enforce explicit grants.
Related runbooks
Same stack, same failure family — worth a skim.
Docker push to ghcr.io fails with 'denied: permission_denied' or '403 Forbidden'
actions/checkout fails with 'Could not read Username for https://github.com'
Step logs show empty string where a secret should be
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.