Your version control system, like Git, is a primary vector for secret sprawl, unintentional source poisoning, and intentional source poisoning. In a shift left model, there are degrees of leftness. The most left you can get is to test all the code before the developer tries to commit anything and train them thoroughly in the best practices. But when we rely on people to remember to do things consistently and correctly, we're cutting holes in the safety net. We need mechanisms.
At Amazon they have a saying: "Good intentions don't work. Mechanisms do." Humans can feel fatigued, rushed, distracted, or otherwise encumbered, and despite all intentions to follow best practices, they don't. When you automate enforcement of best practices, you can ensure those practices are followed in a much more consistent and correct fashion.
Git exists independently of GitHub, GitLab, and BitBucket. All of these businesses are providing Git as a service. Rather than categorizing them as "GaaS" (Git as a Service), let's call them GSPs (Git Service Providers). Pretty much all GSPs add functions and features you won't get from setting up your own basic Git server. But while they each add some unique value propositions, they often provide some of the same added value features as well. One of these is called "Code Owners."
Just like you would use .gitignore
to specify which files should be ignored and never committed, you can add a file called CODEOWNERS
to the root of a branch to specify who owns files, directories, naming patterns, etc. Those owners must review pull requests that impact the files they own before they can be merged.
This is supported by default in GitHub, GitLab, and BitBucket Data Center. For BitBucket Cloud, there's a free plugin. Generally they're pretty similar. Owners must have write permission so they can merge the pull requests. Depending on how the Git service identifies the owners, you might use their handle in the system, their email address, or a team identifier. In general, all three services use a similar syntax for their files, but consult the documentation for each.
For example, to fully protect a GitHub repository end to end, using CODEOWNERS
, they recommend adding a CODEOWNERS
file to the .github
directory of the main branch, using it to set ownership of all the other CODEOWNERS
files in the main repo or branches. No one will be able to modify a CODEOWNERS
file in a subdirectory or branch without a review except the owner of the CODEOWNERS
files.
CAVEAT:
This can get a little fiddly as you deal with various combinations of permissions, settings, and rules. A couple of the fiddly bits from GitHub…
This goes by different names at the different services. We've got GitHub branch protection, Gitlab protected branches, and Bitbucket branch permissions.
These give you a bit more expansive and varied permissions than a CODEOWNERS
file does and can even impact how CODEOWNERS
is enforced, but require a bit more of a learning curve, and in some cases, navigating configuration menus in the website instead of just adding files.
For example, GitHub branch protection rules are set up by going to Settings – Code & automation – Branches – Branch protection rules, then adding a rule.
The first step is to define the branches to which the rule will apply using a pattern or a name. Then, in the docs, 21 sentences following that begin with "optionally" before you get to finalizing and applying the rule.
If I've counted correctly, the fourth "optionally" covers setting "Require review by Code Owners" as mentioned in the previous section.
Three other options to keep in mind:
It's probably obvious to you by now that we like mechanisms.
Gitlab's "rulesets" are used to control a number of scans, such as SAST, SCA, and secrets scanning.
In GitHub, branch and tag behaviors can be governed with rulesets. Rulesets, however, are not limited to a single repository. They can be set at an organizational level. And all rules in effect for a branch or tag, at whatever 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 recipes repository.
One caveat on rulesets can be found in GitHub's Enterprise Migration Guide. If you're importing commits from another GSP and some or all of those commits don't meet the requirements of rules in your organization, the commit imports will be blocked.
Now that you've learned about these three mechanisms, start using them. Start with Code Owners and then move on to enabling it with a branch protection rule. If you're feeling adventurous, enable a GitGuardian scan on pull requests to block secrets from getting merged (and let you remediate them). And once you're a bonafide branch protecting talent, level up into rulesets.
Remember, messing up and not following best practices isn't evil. It's human. Use your skills to build mechanisms that aren't your overlords, but a backup to help you and everyone writing code for your repository catch mistakes before they become problems.
*** This is a Security Bloggers Network syndicated blog from GitGuardian Blog - Automated Secrets Detection authored by Greg Bulmash. Read the original post at: https://blog.gitguardian.com/three-mechanisms-to-protect-your-git-repositories/