Three mechanisms to protect your Git repositories

Your version control system, like Git, is a primary vector for stealth propagation, unintentional source poisoning, and intentional source poisoning. In the left shift model, there are degrees of left. The most you can do is test all the code before a developer tries to input anything and thoroughly train them on best practices. But when we rely on people to remember to do things consistently and correctly, we create holes in the safety net. We need mechanisms.

At Amazon, they have a saying: “Good intentions don’t work. Mechanisms do.” People can feel tired, rushed, distracted, or otherwise burdened, and despite all intentions to follow best practices, they don’t. When you automate the implementation of best practices, you can ensure that those practices are followed in a much more consistent and correct manner.

Force code reviews by “code owners”

Git exists independently of GitHub, GitLab, and BitBucket. All of these companies provide Git as a service. Instead of categorizing them as “GaaS” (Git as a Service), let’s call them GSP (Git Service Providers). Almost all GSPs add functions and features that you won’t get if you set up your own basic Git server. But while they each add some unique value propositions, they often provide some of the same value-added features. One of them is called “Code Owners”.

Just like you would use .gitignore to specify which files to ignore and never commit, you can add a file named CODEOWNERS to the root of the branch to determine who owns the files, directories, naming patterns, etc. Those owners must review pull requests affecting the files they own before they can be merged.

This is supported by default in GitHub, GitLab, and the BitBucket datacenter. There is a free plugin for BitBucket Cloud. In general, they are quite similar. Owners must have written permission to merge pull requests. Depending on how the Git service identifies owners, you can use their system name, their email address, or their team identifier. In general, all three services use similar syntax for their files, but see the documentation for each.

For example, to fully protect a GitHub repository end-to-end, using CODEOWNERSrecommend adding a CODEOWNERS file in .github master branch directory, using it to set ownership of everything else CODEOWNERS files in the master repository or branches. No one will be able to modify a CODEOWNERS file in a subdirectory or branch with no view other than the owner CODEOWNERS files.

warning

This can get a little tricky because you’re dealing with various combinations of permissions, settings, and policies. A few tricky bits from GitHub…

  • Someone on the team who is set as the code owner, but who does not have write permissions, will be able to approve the pull request, but not merge it.
  • You will need to set “Require review by code owner” in the branch protection rules (see next section) to restrict merges to designated code owners. Without it, specific code owners will be notified, but anyone with write permission will be able to connect.

Set rules/permissions to protect branches

This has different names in different services. We have GitHub branch protection, GitLab protected branches, and Bitbucket branch permissions.

They give you slightly more extensive and varied permissions than a CODEOWNERS file does and can even affect how CODEOWNERS is implemented, but requires a little more time to learn and in some cases navigate the configuration menus on the website instead of just adding files.

For example, GitHub branch protection rules are set by going to Settings — Code and Automation — Branches — Branch Protection Rulesthen by adding rules.

The first step is to define the branches to which the rule will apply using a pattern or name. Then, in the documents, the 21 sentences that follow begin with “by choice” before you get to the finalization and application of the rules.

If I counted correctly, the fourth “optional” covers the “Require code owner review” setting as mentioned in the previous section.

Keep in mind three other options:

  • Require status checks to pass before merging: I don’t like this one only because that way you enable GitGuardian scanning on the pull request and block the merge if it fails. You can test coding style compliance, Software Content Analysis (SCA) on any dependency changes, etc. And if any of those fail… the merge is blocked.
  • Allow these actors to bypass necessary pull requests: You may be pressured by the CTO to use this to allow them to bypass code owner review on their commits because they are the CTO and won’t push bad code. don’t Ask your manager for support, but resist it with all your might. Even the CTO’s good intentions fail. Mechanisms work.
  • Do not allow the above settings to be bypassed: Even with some protections you can put in place, another person with administrative privileges (or even you in a moment of weakness) can bypass them. This means that EVERYONE, no matter how good their intentions, are subject to mechanisms.

It’s probably clear to you by now that I love mechanisms.

Get granular control with rule sets

Gitlab’s “rule sets” are used to control a number of scans, such as SAST, SCA, and secret scans.

In GitHub, the behavior of branches and tags can be managed by rule sets. Rule sets, however, are not limited to a single repository. They can be set at the organizational level. All rules in effect for a branch or tag, at any level, are evaluated in a process called rule layering.

This is a very powerful feature, and to help you out, GitHub has its own ruleset recipe repository.

One caveat about policy sets can be found in the GitHub Enterprise Migration Guide. If you are importing obligations from another GSP and some or all of those obligations do not meet the policy requirements in your organization, the obligation imports will be blocked.

Next steps

Now that you’ve learned about these three mechanisms, start using them. Start with the code owners, then move on to enabling with the branch protection rule. If you’re feeling adventurous, enable GitGuardian to scan pull requests to prevent secrets from being merged (and allow you to fix them). And when you become a credible branch protecting talent, level up in the rulesets.

Remember, messing up and not following best practices is not evil. It’s human. Use your skills to build mechanisms that are not your masters, but another set of eyes to help you and anyone writing code for your repository catch errors before they become problems.

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *