In this post, I will be going through some of the essential Branch Protection Rules you should have on all* of your GitHub repositories. GitHub is constantly releasing new updates all the time but my recommendations stand as of January 2022.
I’ve also added some gotchas I’ve
tripped over discovered whilst deploying such rules across nearly a thousand repositories.
*Assuming we’re talking about corporate GitHub organisations… and by all, I mean ALL. Branch protection Rules should be the rule, not the exception. Have exceptions if you need them (you will!) but otherwise apply it everywhere.
Which branches to protect?
At the very least I’d suggest protecting your main branch; it’s probably called master or main.
You almost certainly don’t want anyone merging directly to your master branch. It’s worth mentioning that this isn’t strictly only a security control; pull requests (PR’s) encourage healthy, secure and reliable codebases by pulling in appropriate team members to review changes to potentially critical services. Talking of reviews…
You should check this box to enforce reviews for proposed code changes to the repository. The number of approvals required is largely dependent on SDLC maturity and criticality of the code in the repository.
Note: If your GitHub Actions Workflow permissions are set to read and write and you only require one approval, an adversary can trivially bypass this rule no matter how strict your other protection rules might be.
GitHub approvals are designed such that an author cannot approve their own PR’s, however, a compromised GitHub account can trigger a GitHub Action to create a PR (the PR will be created under a bot user) then approve it with the compromised account.
Closely linked to the above; we want at least one reviewer but we don’t want just anyone reviewing and approving the code. We may want a specific team within the GitHub organisation to review and approve the code changes.
Even if you don’t mind anyone viewing and approving code changes, I would still recommend having a
CODEOWNERS file with a team that everyone is a member of, bar service and machine accounts.
CODEOWNERS failures are silent so I’m going to shamelessly plug one of my GitHub repositories to help discover such silent failures
It’s usually a good idea to dismiss an approval if additional commits are made after the fact. This helps protect against seemingly harmless but reliability affecting code changes to more malicious ones caused by compromised accounts.
This is a new option that only got released a few months ago but is a big win for security. Previously, the only way to get any form of automation to work on a repository was to uncheck the “Include Administrators” option which meant that any repository admin or organisation owner could bypass branch protection rules for that repository.
With this new option, we can apply all branch protection rules to everyone (including admins and owners!) and explicitly an automation user which is permitted to bypass the branch protection rules.
Now that the option of allowing specified actors to bypass PR requirements exists, this option must be checked. I can’t think of any valid reasons not to at this point. Leave a comment if there’s an edge case I haven’t considered!
It’s a good idea to enable status checks that help enable your engineering team. Status checks can help maintain and improve the security and reliability of your services.
Requiring branches to be up to date is more of a hygiene thing and is more likely to cause reliability issues than anything else if not checked.
This one might be a little controversial (feel free to leave a comment with your thoughts!) but I actually don’t recommend enabling this unless your organisation is already heavily invested and embedded in the GPG world (my condolences).
This control adds very little (it can help mitigate impersonation attacks within the GitHub organisation) but comes at the heavy cost of creating, storing, distributing and managing GPG keys.
When SSH signing becomes a thing then commit signing starts to sound a lot more attractive. Given SSH signing was released to Git late last year, I am hopeful that we will see it supported at some point in 2022!
If you’re interested in reading more about commit signing and what attacks it can (and can’t!) defend again, check out Dan Lorenc’s blog where he explains it a lot more eloquently.