“Version control” sounds a bit like something used by people scattered around the country trying to collaborate on a story. But it’s a crucial part of software development, especially in the DevSecOps era, where you need to ensure that the speed of the CI/CD pipeline doesn’t outrun quality and security.
That’s because software development isn’t like an assembly line where a product moves from one group of workers to the next in a perfectly coordinated sequence. In software, multiple developers are working at the same time to build a product, each on different elements, features, and components.
How can they coordinate what they do so the final product isn’t plagued by chaos, conflicts, and security defects?
Version control “oversees” the software development workflow, which is a system of versions, or branches. The main branch contains what will eventually be put into production, but alongside it are a number of side branches—feature branches, development branches, etc. When developers working on a side branch complete their task, the goal is to merge it with the main branch—after making sure it doesn’t conflict with what another developer just did, or something in the main branch. They also need to make sure it’s not riddled with security vulnerabilities that hackers could exploit.
That’s what a good version control system does. It tracks what all the developers are doing in the side branches and helps them resolve conflicts and fix high-risk vulnerabilities before permitting a merge with the main branch.
One of the most popular is Git, a free, open source, distributed version control system designed to handle everything from small to very large projects. The Git Workflow is one of the most common in software development.
It helps developers resolve conflicts. If Jim tries to merge his feature branch but it would break something Mary has already done in a different feature branch she merged yesterday, Git will stop Jim’s merge until they resolve it.
But eliminating critical security vulnerabilities requires security analysis tools.
Meera Rao, senior director for product management (DevOps solutions) at Synopsys, said that until a couple of years ago most organizations didn’t run testing tools—static, dynamic, and interactive security testing, along with software composition analysis (SCA)—until all the code was in the main branch.
But more recently, the need to deploy much more frequently into production has prompted teams to adopt branching workflows that involve security testing before the merge with the main branch.
“Git is such an amazing version control,” she said. “When you decide to merge and you run the scans, if you see critical vulnerabilities you can actually stop the merge. That is something very nice in all of these branching workflows.”
There are three strategies for structuring a branching workflow.
This is a basic workflow, according to Rao, which makes it most useful for teams transitioning from a version control system like SVN (subversion). It provides a single point of entry for all code changes, which is good in that it’s less complicated than others. But its disadvantages are that the main branch can become unstable and it’s difficult to maintain releases.
“If the developers are checking in 10 times a day and each time they do you run a scan, it’s very hard even for the developers to understand which version of all the files the scanning tool will get,” Rao said.
Also known as GitHub flow, this strategy divides all the functionalities a team wants into different feature branches, and multiple developers can work simultaneously on a branch.
“The developers branch out and call it whatever name they want, like August branch or September branch,” Rao said. “Once they do that, multiple developers start working on it. Maybe there are some features that they want in the UI, some that they want in the back end, some that they want in the database. So they create three or four different feature branches with different developers assigned to them.”
“Once they decide their sprint is complete, all of them will commit to the main branch. And this merging happens through a pull request, which can be done in GitHub, GitLab, or in Bitbucket,” she said.
At which point, teams can configure their version control to decide what needs to be done—code review, static analysis, SCA, threat modeling, or other tests.
“Someone can actually manually review that, and only when they approve it and say it is a good feature with no glaring vulnerabilities or risk in the code, then it can merge to the main branch,” Rao said.
The disadvantage of the feature branch workflow, according to Rao, is that since there are so many features in a merge, “you need to have solid automated tests to make sure that when you merge, feature one won’t break the changes that feature two is adding.”
This is the strategy used by teams with the most maturity in DevSecOps. It includes feature, development, and main branches, with the development branch serving as the integration branch for features, and the main branch storing the release history.
Rao notes that release history is important for organizations that need to comply with auditing requirements. “It will answer questions like, ‘What went into this feature that went into production? What changes did you make? Did you run static analysis?’” she said. It also means teams working on feature branches will do a pull request to merge with the development branch, not the main branch.
The GitFlow workflow also includes a dedicated release branch. Once the development teams have enough features for a release, the release branch is forked, which allows one team to finalize the current release and another team to continue working on more features. And once the release branch is tested, it is then merged to the main branch.
It can get complicated, Rao said, with so many branches. “But one of the key things is to see how easy it is for us to help clients run our testing tools when they are either merging from the develop branch to the main branch, or from the feature branch to the develop branch or the main branch.”
It’s easy, she said, because Synopsys has a new tool to help decide on the significance of code changes and the risk level of potential vulnerabilities.
The Intelligent Security Scan GitHub Action leverages the orchestration capabilities of the Synopsys Polaris platform with static (SAST) and software composition analysis (SCA) technologies to ensure that the right security tests are run at the right time.
It also helps to “unclog the pipeline,” so to speak.
Development teams often find it very easy to halt their pipelines if they insert a security scan into the middle of it. So rather than simply initiating a full SAST or SCA scan whenever a GitHub Action is invoked, Polaris first reviews code changes in order to calculate a risk score using rules defined by the team as well as the scope of the changes that have been made to the code.
This score is used to determine which security scans to perform, and at what depth. This combination of selective testing and out-of-band execution ensures that security analysis doesn’t hinder the progress of other build and integration activities.
“That is one of the reasons you need to finely configure your tools. You don’t want a tool that gives you thousands of issues. You want to configure it so that only critical or high-confidence issues stop the merge. Otherwise yes, the developers will go crazy,” Rao said. That’s because perfect code is impossible, and any organization that tries to make it perfect will have a tough time bringing anything to market.
“You need to run the tool, but if you don’t configure it properly, you’re going to lose the confidence of your developers,” Rao said. “You’re going to create friction. Developers won’t look at medium, informational, and low findings. They don’t have the time.”