Building a security-conscious CI/CD pipeline
Tags: codesecurity, devsecops, cicd
Published: 2023-06-30 02:00:27

[Continuous integration (CI) and continuous delivery (CD)](https://snyk.io/learn/what-is-ci-cd-pipeline-and-tools-explained/) has become a ubiquitous practice for DevOps teams. The CI/CD process focuses on building and deploying new applications or releasing updates to already-deployed workloads. As a result, most CI/CD efforts focus on enhancing development speeds. 


However, CI/CD practices can accomplish much more than enabling workload deployments. For instance, we can also use CI/CD as a security-conscious pipeline that subjects code to security-oriented testing, performs source code vulnerability scanning, and runs other essential checks before the application components are deployed.


![](https://res.cloudinary.com/snyk/image/upload/v1688058588/blog-secure-cicd-infinity-graphic.jpg)
What a security-conscious CI/CD pipeline looks like
---------------------------------------------------


Let’s start by visualizing the CI/CD pipeline as a linear pathway, moving from development to operation.


![](https://res.cloudinary.com/snyk/image/upload/v1688058590/blog-secure-cicd-automate-graphic.jpg)
Developers start with the build process, after which they check their code into a source control system like Git. The code is validated and packaged, and then the package file — like a Webdeploy.zip for .NET or a Docker container image — is published to the target runtime environment (for example, a Docker host or a Kubernetes environment). Next, the operations teams assume control and manage the environment.


With this in mind, let’s consider how the CI/CD security optimization concept of shifting security left might change this process by incorporating security practices throughout the timeline. In the context of security, shifting left refers to the process of integrating security awareness and consciousness as early in the DevOps cycle as possible — then maintaining this awareness throughout every part of the process. 


However, it’s important to note that most of the guidance around shifting left  is a general concept that extends to incorporating *any* DevOps concerns (testing, operational automation, *and* security) closer to the implementer. The purpose of the shift is to close the feedback loop and provide faster awareness to the results of changes in those areas. 


Most organizations are already shifting other DevOps process cycles in this way, but falter or fail at shifting security. As a result, the term DevSecOps arose to draw attention to the importance of including security in DevOps practices.


Let’s look at some common security capabilities that we can integrate as part of each CI/CD pipeline structure.


![](https://res.cloudinary.com/snyk/image/upload/v1688058589/blog-secure-cicd-integrate-early-graphic.jpg)
As this diagram demonstrates, it’s possible to establish a security-conscious CI/CD flow without changing anything in the CI/CD process itself. Shifting to this kind of security-focused flow empowers DevOps teams to integrate security capabilities into every CI/CD cycle. 


Let’s take a closer look at some of the key security aspects mentioned in the diagram, which components we can incorporate into a CI/CD pipeline, and what security benefits they provide. 


### Automated threat modeling


Threat modeling tools analyze applications for known security flaws, vulnerabilities, and other security risks. They help organizations identify, recognize, and predict threats while aiding in proactive decision-making for avoiding or mitigating security threats. 


Threat modeling appears as the first step in our CI/CD pipeline diagram, but it often occurs before the development process starts. Ideally, we should repeat it throughout different stages of CI/CD — which is where an automated threat modeling approach becomes beneficial. 


### Software bill of materials


An increasing number of source code developers use code that originates from elsewhere. As a result, it can be tricky to track resources — like open source code snippets, software packages, or Docker containers — during an application’s development lifecycle. A software bill of materials (SBOM) becomes handy in situations like this.


The SBOM allows development teams to catalog aspects of software components, such as package location and dependencies, and provides visibility into an application’s components. This information also enables the SBOM to cross-check packages in the application against known security vulnerabilities, which in turn helps identify where and how malicious users might exploit the code. For these reasons, [SBOMs have become a critical part of security-conscious CI/CD pipelines](https://snyk.io/blog/building-sbom-open-source-supply-chain-security/). 


### Artifact signing


Often, developers will reuse artifacts across applications to expedite the process. In software development terms, an artifact refers to any software or the artifacts about the software — such as the previously described SBOMs — that provide the features and capabilities of a larger software application lifecycle. 


We can view the outcome of building or compiling development code (the result of CI) as an artifact. Other common artifacts include NuGet packages for .NET, npm for Node.js development, and Maven for Java. We can even consider PowerShell or Bash scripts as artifacts. 


To protect assets and ensure their authenticity, DevOps engineers might consider digitally signing the source code they produce. This digital signature is a requirement for app developers who use distribution platforms like Apple’s App Store and the Google Play Store. A digital signature linked to a certificate enables the consumer of the source code to determine the artifact’s source organization. This signature also guarantees that no unauthorized party has tampered with the code. 


However, the digital signing process is complex and requires navigating private key infrastructure certificates. Fortunately, we can integrate an automation tool into our CI/CD pipeline to implement digital signatures. 


### Unit tests for security validation


Unit tests allow developers to validate the quality and outcome of a small unit of functional software. This testing guarantees that each piece of the code runs as expected. While mainly used for testing the integrity and functionality of the code, we can also use unit tests specifically for security validation. 


Unit tests can check each code snippet for any known vulnerabilities that the threat modeling analysis detects, which makes them useful to the threat modeling process. 


### Analyze infrastructure as code (IaC)


Infrastructure as code (IaC) allows DevOps teams to define the end state of the required infrastructure and deploy it using a template-based approach. Public cloud platforms each provide proprietary IaC tools, such as Azure ([ARM Templates and Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/overview)), AWS ([CloudFormation](https://aws.amazon.com/cloudformation/)), and GCP ([Deployment Manager](https://cloud.google.com/deployment-manager/docs)). 


For multi-cloud environments, organizations can consider a cross-platform solution like HashiCorp [Terraform](https://www.terraform.io/), which removes the complexity of learning multiple template language syntaxes. If the majority of your DevOps team has a developer background, a solution like  [Pulumi](https://www.pulumi.com) might represent an exceptional alternative. Instead of providing templates, Pulumi uses code libraries and actual coding, supporting various popular languages like JavaScript, Python, and DotNet. It also supports multiple cloud platforms.  


IaC template files are similar to application source code, containing definition components, variables, and links to other artifacts. As a result, we should also apply all security-oriented optimizations to IaC. Automating these security processes is also effective here. For instance, [Snyk automates the analysis of security vulnerabilities in IaC](https://snyk.io/product/infrastructure-as-code-security/) to help DevOps teams analyze security vulnerabilities quickly and efficiently. 


### Automated vulnerability scanning


Vulnerability scanning allows DevOps engineers to integrate security vulnerability scanning as part of the CI/CD pipeline process. In this context, vulnerability scanning generally takes the form of static analysis security testing (SAST) or dynamic application security testing (DAST). 


First, SAST scans source code at rest and performs a detailed code validation directly as part of source control. Then, another vulnerability scanning process can run once the code compiles and integrates with software packages. This scans the developer’s source code for security threats and thoroughly scans any additional packages, such as Docker containers or software libraries. Finally, DAST integrates once an application is published and tests the security of the running application, without scanning the source code to mimic the actions of a hacker or malicious user and test the code’s defenses. 


A variety of tools can help scan code or automate scanning. For instance, [Snyk](https://snyk.io/product/open-source-security-management/) provides powerful code security and code scanning capabilities for [common DevOps tools and platforms](https://docs.snyk.io/integrations/ci-cd-integrations) available today. 


Continuous security
-------------------


These are some key aspects of integrating security controls within each cycle of DevOps. They align well with the industry concept of “shifting left” that encourages integrating security controls as early in the DevOps process as possible. 


The result is a practice of continuous security, which protects every part of the development cycle. Strategies like these help DevOps teams take security practices a step further and transform development and operations (DevOps) into development, security, and operations (DevSecOps). 


DevSecOps emphasizes that we should integrate security validation mechanisms early in development and at every stage of DevOps. For instance, we might start with threat modeling in the architecture phase, include security scanning in source control and when building the code, and validate security during release and the workload runtime once it is operational.


[Continuous security](https://snyk.io/learn/what-is-ci-cd-pipeline-and-tools-explained/continuous-security/) can — and should — be an integral part of software development lifecycle management. 


Optimizing CI/CD practices — and security
-----------------------------------------


CI/CD processes have historically been used to optimize the speed of software releases. However, they can also be immensely useful when integrated into security practices and extended into a fully security-conscious CI/CD pipeline. Given the evolving nature of cyberthreats and cybersecurity attacks, protecting the software lifecycle requires a more active security methodology than ever before. 


Some beneficial security guidelines for DevSecOps engineering teams include automated threat modeling, SBOMs, artifact signing, and automated vulnerability scanning. Adopting strategies like these is a way to move towards continuous security monitoring. In the same way, your organization benefits from faster software releases, as well as releases incorporating security best practices.