In the first article in this series we covered the basics. In the second article about the planning process, we covered how developers incorporate security at the beginning of their project. This article explores DevSecOps during the Continuous Integration (CI) phase of the coding process and how to protect the code from supply chain attacks, license issues, and theft. Developers are advised during planning to use secure coding best-practices during the coding process.
The focus of DevSecOps in the coding process switches to securing the source code developers write. Code is stored in a centralized repository where it is now the single source of truth. From the repository, code can be retrieved and modified by other developers and automation tools.
What is a source code repository?
A source code repository “repo” is a centralized file storage location that uses a revision control system to retain the history of file changes and comments from the developers on why changes were made. Repos also allow collaboration within a team of developers who are working on the same project while being protected from overlapping or conflicting changes. Developers have a choice of which repo to use based on requirements and purpose of the software they’re building. For example, a public repo would be appropriate for open source (FOSS) while a private repo may be needed to protect the proprietary software code “crown jewels” of the business.
Public versus private repo
Software as a Service “SaaS” repo websites like Github, Gitlab, and Bitbucket are examples of public repos where people can store a project, collaborate, and share with others around the world. Because public repos are accessible from the Internet, they are designed primarily to be available to everyone.
Private repos in services like Azure DevOps (can be public or private) or an on-premises setup of Gitlab offer additional layers of security but also come with more administrative overhead. Network security controls like virtual private network (VPN) access, firewalls, data loss protection (DLP) systems, and intrusion detection / protection systems protect the private repo from malicious activity. The overhead of managing and administering the private repo platform falls on the company.
In addition to administering system level security, the company must also maintain patches, version upgrades, and availability to protect the repo. The benefit is increased security and privacy because the repo should be accessible only to those within the company. The following sections are additional layers of security to consider when implementing for all repos.
Authentication and authorization
Authentication verifies who the requester is and authorization defines what the requester has access to. Access to the repo for a project should operate with the principal of least privilege. In other words, only the developers and tools that need access to the repo are authorized. In most cases, the project owner will approve or deny all user access requests to the repo. The owner can also grant the necessary permissions based on the type of user.
For example, an auditor may only need read-only access while a developer would need to add or modify items in the repository. For private repos, DevSecOps recommends authentication be integrated into the company’s single sign-on (SSO) platform and multifactor authentication (MFA) will provide a stronger measure of protection against password attacks.
Source code branching
A project in the repo most likely has several user stories that multiple developers are working on to deliver the application. The “main” branch of source code in the repo represents the “single source of truth”.
When a developer creates a feature branch, they are taking a snapshot of the code in the main branch and creating a copy to work on with their user story. When the developer completes the coding for the user story, they can merge their feature branch into the main branch.
Main branches aren’t always the best version of the software to send into production. Release branches are a snapshot of the main branch and dedicated to delivering a specific version of the application to production. Release branches offer additional control and can help with applying hot fixes for bugs or adding temporary features that may not need to be in the main branch.
Hot fixes are used to quickly solve a problem identified in production. They can also use a branching strategy to give developers time and flexibility while still quickly solving the problem. Hot fix branches make it easy to deliver a targeted resolution to a specific issue or vulnerability. For a temporary hot fix, the hot fix branch does not have to be merged into the next release. This often happens when a more long-term solution is being developed.
Merging from a feature branch into the main branch should be restricted from happening without a pull request. A pull request is a tool in repos that announces a desire by the developer for others on the team to review the changes they made. Other developers review the changes made and can send feedback for additional changes or approve the request to merge the code into the main branch. Once the peer review is complete, the pull request is approved, and the feature branch code is merged into the main branch to create a new “single source of truth”. After the merge is complete, the feature branch can be deleted.
There may be times when a developer wants to take the source code of an application and use it for an entirely different project than its original intention. In this case, the developer can create a new repo by forking (making a copy) the main branch from the current repo for the new project.
This is acceptable in the FOSS community because it fosters innovation and allows faster delivery of projects by reusing snippets of code. It also carries risks that malicious actors can create supply chain attacks through forking. Also, forking does not free the developer from the original license. For private repos, DevSecOps recommends that forking is disabled to prevent software code theft.
Source code separation
Not all applications have the same security requirements, which is based on the risk associated with the application source code. An application that is critical to revenue generation in the business may need more security than an informational website. The critical application may need to be hosted in a separate project or an entire source code repo platform can be created with separate authentication and authorization. The DevOps and DevSecOps models can support multiple repos and projects for however the business needs to adjust.
The decision for which software repository platform to use depends on several criteria including public or private, automated workflows, and seamless transitions that help the developer with their user story. Automation and easy to use security tools also promote DevSecOps and improve the security quality of code. Combined with continuous security training for developers, using the repo security features will protect companies from supply chain attacks, licensing issues, and code theft. The next step is to compile the code into a package or artifact using the build process.