Streamlining Developer Activities: How to Control GitHub App Code Contributions
In the fast-paced world of software development, leveraging GitHub Apps can significantly enhance automation and streamline developer activities. However, a common concern arises when granting permissions: how do you ensure an app can contribute via pull requests without having the ability to push code directly to your main branches? This question, recently debated in the GitHub Community, highlights a crucial aspect of repository security and workflow integrity.
The Dilemma: Write Pull Requests vs. Write Code
A developer, lancedolan, raised a pertinent question: is it possible to configure a GitHub App to have READ/WRITE permissions for Pull Requests but only READ access for Code? The underlying worry was that an app with "Pull Requests (write)" permission might implicitly gain "Contents (write)" access, allowing it to bypass the standard pull request workflow and directly modify repository code.
Why Direct Separation Isn't Natively Possible
As community experts yegost and anshk1234 clarified, GitHub's permission model currently bundles these capabilities. Creating or updating a Pull Request inherently requires the app to reference commits and branches, which fall under the Contents permission scope. While Pull Requests: Write minimally depends on Contents: Read, the current system often grants Contents: Write alongside it. This means, technically, the app can push commits directly.
Practical Solutions for Constraining App Contributions
While you can't remove the app's technical capability to write code at the permission level, you can implement robust repository settings to make it practically impossible for the app to bypass your established review processes. This ensures that all code contributions, including those from apps, adhere to your team's quality and security standards, thereby improving overall developer activities.
1. Enforce Branch Protection Rules
This is a foundational step for any critical branch (e.g., main, develop). Branch protection rules prevent direct pushes and enforce a review process. To set this up:
- Navigate to
Settings → Branches → Add rulefor your protected branch (e.g.,main). - Enable:
- ✅ Require a pull request before merging
- ✅ Require approvals (at least 1 human reviewer is recommended)
- ✅ Restrict who can push to matching branches (explicitly exclude the app's actor)
Even if an app has Contents: Write, these rules will physically block it from pushing directly to a protected branch, forcing it to go through the PR workflow.
2. Utilize Rulesets for Granular Control
Rulesets offer a newer, more powerful way to manage branch protection, allowing for highly specific controls, including targeting specific actors like apps or bots.
- Go to
Settings → Rules → Rulesets. - Create a ruleset that targets your desired branches.
- Configure it to:
- Block direct pushes from the app's actor specifically.
- Still allow the app to create pull requests.
Rulesets provide a more precise mechanism than classic branch protection for managing who can do what, making them ideal for complex team structures and automated workflows.
3. Limit App Access to Specific Repositories
As lancedolan already implemented, restricting an app's access to only the repositories where it's absolutely needed is a critical security best practice. This minimizes the blast radius should an app be compromised or misconfigured.
4. Audit App Activity
Regularly monitoring an app's actions provides transparency and helps identify any unexpected behavior. You can do this via:
Settings → Audit log.- Filter by the app's name to review its activities on your repository.
The Bottom Line for Developer Activities
While GitHub's current permission model doesn't allow for an exact "write PRs but not code" setting, the combination of Branch Protection Rules and Rulesets provides a robust framework. These features effectively prevent any app, regardless of its technical permissions, from bypassing your pull request review process. By implementing these controls, you maintain strong governance over your codebase and ensure all contributions align with your team's standards, significantly enhancing the security and efficiency of your developer activities.
