Introduction
Dependabot is GitHub's automated dependency update service that scans repositories for outdated dependencies and creates pull requests to update them. Many teams implement auto-merge workflows to automatically merge Dependabot PRs after tests pass, reducing the manual burden of keeping dependencies updated. However, these workflows often fail with permission errors even when the pull request is valid and all tests are green.
The root cause lies in how GitHub treats Dependabot-triggered automation differently from regular maintainer workflows. The default GITHUB_TOKEN permissions are narrower when triggered by Dependabot, branch protection rules still apply to automated merges, and the workflow event type determines what permissions the job receives. Understanding these differences is essential for configuring successful auto-merge automation.
Dependabot PRs are created from a fork (even within the same organization), which introduces additional security considerations. GitHub restricts what workflows can do when triggered by fork PRs to prevent malicious actors from gaining repository access. The pull_request_target event provides elevated permissions for these scenarios but requires careful security review to prevent privilege escalation.
Symptoms
When Dependabot auto-merge fails due to permission issues, you will observe these symptoms:
- Dependabot PRs fail with
Resource not accessible by integrationerror in workflow logs - The auto-merge step can read the PR but cannot approve it or merge it
- The workflow succeeds for maintainer-created PRs but fails only for Dependabot PRs
- Branch protection keeps the PR blocked even after the automation workflow runs
- Workflow logs show 403 Forbidden errors when attempting to approve or merge
- PRs remain in "Waiting for review" or "Waiting for status checks" state indefinitely
Common error messages in GitHub Actions logs:
Error: Resource not accessible by integration (403 Forbidden)
Error: You do not have permission to approve this pull request
Error: Branch protection rules prevented the merge
Error: pull request is in mergeable state CONFLICTING
HttpError: You are not authorized to access this resourceWorkflow failure showing permission issue:
Run actions/github-script@v6
with:
script: |
github.rest.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
event: 'APPROVE'
})
Error: HttpError: Resource not accessible by integrationCommon Causes
Several factors cause Dependabot auto-merge permission failures:
- 1.Missing token permissions: The workflow token lacks
pull-requests: writeorcontents: writepermissions needed to approve and merge PRs. Default permissions are often read-only for Dependabot-triggered workflows. - 2.Wrong workflow event: Using
pull_requestinstead ofpull_request_targetlimits permissions for fork PRs. Dependabot PRs requirepull_request_targetto get elevated permissions. - 3.Branch protection requirements: Branch protection rules require approvals, status checks, or linear history that the workflow cannot satisfy. Even with correct permissions, protection rules block the merge.
- 4.Missing required approvals: Branch protection requires code review approvals, but the workflow's automated approval doesn't count or the approver isn't authorized.
- 5.Status check requirements: Branch protection requires specific status checks to pass, but the workflow environment doesn't match or required checks haven't run.
- 6.Repository settings: Repository may have "Restrict merging to users with write access" enabled, blocking the automated token from merging.
- 7.Personal access token instead of GITHUB_TOKEN: Using a PAT that doesn't have sufficient scope or that belongs to a user lacking repository permissions.
Step-by-Step Fix
Follow these steps to resolve Dependabot auto-merge permission issues:
Step 1: Grant explicit token permissions in workflow
Declare the permissions the workflow needs explicitly:
```yaml name: Dependabot Auto-Merge
on: pull_request_target
permissions: contents: write pull-requests: write
jobs: auto-merge: runs-on: ubuntu-latest if: github.actor == 'dependabot[bot]' steps: - name: Enable auto-merge for Dependabot PRs uses: actions/github-script@v6 with: script: | github.rest.pulls.createReview({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.issue.number, event: 'APPROVE', body: 'Auto-approved for Dependabot update' }) ```
Step 2: Use the correct workflow event
For Dependabot PRs, use pull_request_target:
```yaml # WRONG - Won't work for Dependabot (fork PRs) on: pull_request
# CORRECT - Works for Dependabot PRs with elevated permissions on: pull_request_target
# Alternative: Use both events if needed on: pull_request: types: [opened, synchronize] pull_request_target: types: [opened, synchronize] ```
Note: pull_request_target provides repository write permissions even for fork PRs. This is necessary for Dependabot automation but requires security considerations. Never checkout and run code from the PR head ref without validation.
Step 3: Configure branch protection to allow automation
Adjust branch protection rules to accommodate automation:
```yaml # Navigate to: Settings > Branches > Branch protection rules # Edit the rule for your default branch (main/master)
Required settings: - Require status checks to pass before merging: Check required CI checks - Require branches to be up to date before merging: Enable if tests need latest base
Optional settings to enable automation: - Required number of approvals: Set to 0 if auto-approving - OR use "Dismiss stale reviews" to allow automated approval - Allow specific actors to bypass branch protection: Add Dependabot or the automation workflow
# Via GitHub API curl -X PUT \ -H "Authorization: token $TOKEN" \ https://api.github.com/repos/$OWNER/$REPO/branches/main/protection \ -d '{ "required_status_checks": { "strict": true, "contexts": ["ci-tests"] }, "required_pull_request_reviews": { "dismiss_stale_reviews": true, "require_code_owner_reviews": false }, "enforce_admins": false }' ```
Step 4: Enable GitHub's built-in auto-merge
As an alternative to custom workflows, use GitHub's native auto-merge:
```yaml # In workflow, enable auto-merge instead of direct merge jobs: dependabot-auto-merge: runs-on: ubuntu-latest if: github.actor == 'dependabot[bot]' permissions: contents: write pull-requests: write steps: - name: Enable auto-merge uses: actions/github-script@v6 with: script: | github.rest.pulls.enableAutoMerge({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.issue.number, merge_method: 'SQUASH' })
- name: Approve PR
- uses: actions/github-script@v6
- with:
- script: |
- github.rest.pulls.createReview({
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: context.issue.number,
- event: 'APPROVE'
- })
`
Step 5: Limit auto-merge to safe update types
Only auto-merge low-risk dependency updates:
```yaml jobs: auto-merge: runs-on: ubuntu-latest if: github.actor == 'dependabot[bot]' steps: - name: Check update type id: check uses: actions/github-script@v6 with: script: | const pr = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.issue.number });
const labels = pr.data.labels.map(l => l.name); const isSafe = labels.includes('dependencies') && (labels.includes('patch') || labels.includes('minor'));
return { safe: isSafe, labels: labels };
- name: Auto-merge safe updates only
- if: fromJSON(steps.check.outputs.result).safe
- uses: actions/github-script@v6
- with:
- script: |
- github.rest.pulls.createReview({
- owner: context.repo.owner,
- repo: context.repo.repo,
- pull_number: context.issue.number,
- event: 'APPROVE'
- });
`
Step 6: Handle CODEOWNERS requirements
If branch protection requires CODEOWNERS approval, ensure Dependabot path is excluded or the automation account is a code owner:
```yaml # .github/CODEOWNERS file # Exclude Dependabot changes from requiring approval /.github/dependabot.yml @maintainers /package-lock.json /yarn.lock /go.sum
# Or include automation as code owner /* @automation-bot @maintainers ```
Verification
After fixing permissions, verify auto-merge works:
```bash # Trigger a Dependabot update manually gh api repos/:owner/:repo/dependabot/secrets --paginate
# Or create a test PR and watch workflow execution gh run watch
# Check workflow permissions in run logs gh run view --log | grep -i permission
# Verify branch protection configuration gh api repos/:owner/:repo/branches/main/protection ```
Check the workflow successfully approved and merged:
# Look for these in workflow logs:
- "Successfully approved pull request #123"
- "Successfully enabled auto-merge for pull request #123"
- PR merged (check PR status)Prevention
To prevent Dependabot auto-merge permission issues:
- 1.Always declare explicit permissions: Every workflow that approves or merges should explicitly declare
contents: writeandpull-requests: writepermissions. - 2.**Use
pull_request_targetcarefully**: This event grants elevated permissions for fork PRs. Never checkout and run untrusted PR code without safeguards.
# Safe pattern: checkout base branch, not PR head
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.ref }}- 1.Align branch protection with automation: Document which branch protection rules apply to automation and ensure workflows satisfy all requirements.
- 2.Auto-merge selectively: Only auto-merge patch and minor updates. Require manual approval for major version changes that may break compatibility.
- 3.Test with a real Dependabot PR: After configuration changes, wait for or trigger a Dependabot update and verify the complete workflow executes successfully.
- 4.Monitor workflow failures: Set up notifications for Dependabot workflow failures to catch permission issues quickly.
- 5.Keep Dependabot configuration updated: Maintain
.github/dependabot.ymlwith appropriate update schedules and limits to control the volume of PRs needing auto-merge.
Related Articles
- [WordPress troubleshooting: Fix IAM Access Denied 403 - Complete Tro](fix-iam-access-denied-403)
- [GitHub Actions Artifact Expired or 403 Download Failed](github-actions-artifact-expired-403-download-failed)
- [Fix Github Actions Artifact Upload Failed File Too Large 5gb Limit Issue in GitHub Actions](github-actions-artifact-upload-failed-file-too-large-5gb-limit)
- [Fix Github Actions Aws S3 Deploy Credentials Expired Rotate Issue in GitHub Actions](github-actions-aws-s3-deploy-credentials-expired-rotate)
- [Fix Github Actions Cache Evicted Manually Workflow Fails Download Issue in GitHub Actions](github-actions-cache-evicted-manually-workflow-fails-download)
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "GitHub Actions Dependabot Auto-Merge Permission Denied",
"description": "Resolve Dependabot auto-merge permission denied errors by checking GITHUB_TOKEN permissions, branch protection requirements, and the workflow event used for approval and merge automation.",
"url": "https://www.fixwikihub.com/github-actions-dependabot-auto-merge-permission-denied",
"publisher": {
"@type": "Organization",
"name": "FixWikiHub",
"url": "https://www.fixwikihub.com"
},
"author": {
"@type": "Person",
"name": "FixWikiHub Editorial Team"
},
"datePublished": "2026-01-23T15:03:52.860Z",
"dateModified": "2026-01-23T15:03:52.860Z"
}
</script>