Prevent AI Coding Agents Pushing to Main on GitHub
Prepared and checked using AI. Sources are linked in the article.
To prevent an AI coding agent pushing to main on GitHub, create an active branch ruleset targeting main. Require a pull request, require your CI checks, and require an approval if you want someone to review the diff before merging. Keep the agent’s GitHub identity off the ruleset’s bypass list. The agent can then push a working branch and open a pull request, while GitHub enforces the rules on changes reaching main.
Create a ruleset for main
Branch rulesets are available for public repositories on GitHub Free and for public and private repositories on GitHub Pro, Team, and Enterprise Cloud. You need repository admin access, or a role with permission to edit repository rules, to create one.
In the repository, open Settings → Rulesets → Rulesets → New ruleset → New branch ruleset. Give it a descriptive name, such as Protect main from direct agent changes, and set enforcement to Active. Under Target branches, add main as the target. Targeting the default branch is also an option when main is your default branch, but an explicit main target makes the intended scope clear. Check the target before creating the ruleset: protecting a similarly named working branch will leave main exposed.
Under Branch protections, select:
- Require a pull request before merging. This requires changes to the target branch to be associated with a pull request; it does not, by itself, require approval. Set a required approval count if review is part of your policy.
- Require status checks to pass before merging. Add the specific CI job names that must pass. A workflow running somewhere in the repository is not enough: its check must be selected as a requirement for
main. - Block force pushes. This keeps a force push from replacing the protected branch’s history, subject to any bypass permissions you grant.
For agent-written changes, requiring an approval gives a reviewer a chance to inspect the actual diff. Consider Dismiss stale pull request approvals when new commits are pushed so an approval of one diff does not cover later code changes. If your concern is the final update to an approved branch, Require approval of the most recent reviewable push requires approval from someone other than its last pusher. These review settings have different effects when the branch changes, so choose the behavior your team can sustain.
Leave the agent, its GitHub App, and any role it uses off Bypass list. A bypass entry can exempt an actor from the rules you just selected. If a trusted maintainer needs exceptional access, the ruleset offers For pull requests only bypass: that actor must still open a pull request but can bypass protections when merging it. Do not grant that exception to an agent expected to wait for checks and review.
Click Create, then confirm that the ruleset is Active and targets main. A branch ruleset is the relevant control here. GitHub’s separately named push rulesets address restrictions such as file paths, extensions, and sizes; selecting one instead will not configure the pull request gate described above.
Make a CI check available to require
For example, suppose this repository has a working make test target. A workflow at .github/workflows/pr-checks.yml could define a test job for pull requests targeting main:
name: pr-checks
on:
pull_request:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: make test
The pull_request branch filter applies to the pull request’s target branch, and jobs.<job_id>.runs-on selects the runner. The checkout action places repository files in the job workspace; the make test command is only an example, so replace it with your project’s real test command. Limiting GITHUB_TOKEN to contents: read follows GitHub’s least-privilege guidance for workflows. A test workflow does not need repository write access merely to report its result.
Open a pull request so the check runs, then add the resulting test check to the ruleset’s required status checks. Beside that required check, select the GitHub App that reported it as the expected source, rather than any source. An identity with repository write permission can set a status result, but a result from another source will not satisfy a check restricted to the selected app. If the app is not offered yet, save the check requirement and edit it after the app has reported a check run.
Use a distinct job name: duplicate job names across workflows can make a required check ambiguous and block merging. Select checks that cover every proposed change to main. If a required workflow is skipped by a path filter, branch filter, or commit message, its check can stay pending and prevent a merge. A job skipped by a condition can instead report a successful result, so a green badge does not prove that a particular test command ran.
Required checks are a gate on reported results, not a judgment of what the tests cover. Decide which builds, tests, or security checks are necessary for this repository, and make their jobs run reliably on pull requests to main. If you later enable a merge queue, add a merge_group trigger to workflows that produce required checks; otherwise the queue may wait for a check that never runs.
Send agent work through a branch and pull request
Give the agent a working branch rather than a task that asks it to commit on main. For example, agent/fix-parser can be the branch for one change. In an ordinary checkout, creating and switching to it uses git switch -c:
git switch -c agent/fix-parser
After the change is committed, pushing with -u sets the remote branch as its upstream:
git push -u origin agent/fix-parser
Then GitHub CLI can open a draft pull request with an explicit base and head branch:
gh pr create --base main --head agent/fix-parser --draft --fill
--fill uses commit information for the pull request title and body. Edit that text if it omits the change’s purpose, test plan, or known limits. A draft is useful while an agent is still revising the branch. When the changes are ready, click Ready for review in the pull request’s merge box. A draft pull request cannot be merged, even when checks and approvals are satisfied. Reviewers can then assess the finished diff and its checks before merging. For the handoff after several agents finish, see merging parallel agent branches and reviewing AI-generated code.
If agents work in separate git worktrees, each worktree should still use its own branch. Worktrees keep local working files apart; the GitHub ruleset governs what can reach the remote main branch. The local arrangement and the remote merge policy solve different parts of the workflow.
Check the bypass and direct-push limits
A ruleset only protects the branches and actors it actually covers. Inspect its target, Active status, required checks, approval count, and bypass list after saving. Active rulesets can be viewed from the repository’s rules page and from a pull request’s merge box when a rule blocks merging. Ruleset insights can show failed evaluations and bypasses, which helps investigate an unexpected update.
Pay particular attention to the credential available to the agent. If it operates through a personal account, app, or automation that has bypass permission, the policy may not apply as intended. Repository rules cannot distinguish a person typing a command from an agent using that same credential. Keep bypass rights with trusted maintainers and review the permissions of any automation that can update the repository.
There is a narrower meaning to “no direct pushes” than “changes must have a pull request.” GitHub permits some locally merged, up-to-date pull requests to be pushed to a protected branch after their required checks pass. The pull request rule is therefore a gate on the change, not a promise that every accepted branch update came from clicking GitHub’s Merge button. Requiring review, avoiding agent bypass, and keeping merge authority with maintainers matter if the agent must never finalize a change itself.
If you already use a classic branch protection rule, check it alongside the new ruleset. Both can apply to the same branch, and GitHub enforces their combined requirements. Classic protection also has a separate Do not allow bypassing the above settings option because administrators and designated bypass roles are exempt by default. Review the effective requirements before assuming that adding a new rule replaced an old one.
When a required check blocks a pull request
Start with the pull request’s checks and merge box. A required check must report for the latest relevant commit; a successful run on an earlier commit does not clear a newer push. If the check says Waiting for status to be reported, compare the exact required check name with the job that ran, then inspect the workflow trigger and any path or branch filters. Do not remove a required check merely to clear a pending state without deciding what will replace its coverage.
If you enable Require branches to be up to date before merging, changes to main can require a pull request branch to be updated and checked again. That costs additional CI runs but tests the branch against a newer base. Without that option, fewer reruns are needed, while an incompatible change on main may be discovered later. This trade-off matters when several agent branches are ready at once.
Where Parallel Code fits
Parallel Code is our free, open-source desktop app for macOS and Linux. It runs several AI coding agents in parallel, each in its own git worktree, and provides a diff-first review surface. Its local worktree isolation helps keep agent changes separate while your GitHub ruleset controls their path into main.
Frequently asked questions
Does requiring a pull request also require a human approval?
No. Configure an approval requirement in the branch ruleset if review is mandatory. Keep the agent off the bypass list and choose a reviewer who can assess the diff.
Why is a green workflow not satisfying the required check?
The selected check name may differ from the job that reported, its source may differ from the expected GitHub App, or the successful run may belong to an older commit. Check the pull request’s latest checks and ensure the workflow runs on an eligible pull request event without filters that skip the required job.
Should I protect each agent branch too?
The essential gate is on the destination branch, main. You can add rules for working branches if your team needs them, but first make sure agents can still push revisions to their own branches and that the ruleset targets main exactly.
Can an agent use my admin account and still be blocked?
A branch ruleset with no applicable bypass entry can enforce its requirements on that account. Sharing an admin credential with an agent still gives it broad repository control, including settings access, so use an identity with only the permissions the agent needs.