Git Push 403 - Token Lacks Scope or Permission in CI
The token is valid - authentication passed - but it does not carry the permission the operation needs. A push or a write to a protected resource returns 403 because the token’s scope or the workflow’s permissions block is too narrow.
What this error means
Authentication succeeds but the operation fails with a 403 and remote: Permission to org/repo.git denied. Read may work while write fails, or one repo works while another is forbidden.
remote: Permission to org/repo.git denied to github-actions[bot].
fatal: unable to access 'https://github.com/org/repo.git/': The requested URL
returned error: 403Common causes
GITHUB_TOKEN has read-only permissions
By default the workflow token may be read-only (or restricted per the repo setting). A push then fails 403 even though the token is valid, because it lacks contents: write.
A PAT is missing the required scope
A classic PAT without repo scope, or a fine-grained PAT without the repository’s Contents: read/write permission, authenticates but cannot perform the action.
The token has no access to that repository
A fine-grained token or App installation scoped to a different set of repos can read nothing in this one, so even a fetch is forbidden.
How to fix it
Grant the workflow the write permission it needs
Raise the permissions block so GITHUB_TOKEN can push.
permissions:
contents: write # allow the job to push commits/tagsUse a PAT with the right scope/permissions
- For a classic PAT, include the
reposcope (andworkflowif editing workflows). - For a fine-grained PAT, grant the target repos Contents: read and write.
- Confirm the token’s repository access list includes this repo.
How to prevent it
- Declare an explicit least-privilege
permissionsblock in every workflow. - Prefer fine-grained tokens scoped to specific repos and permissions.
- Document which scope each automation step requires.