In November, the Cloud Native Computing Foundation released a whitepaper that focused on the security of cloud native applications. It was large in scope, covering everything from cloud native layers, to the full lifecycle of development, to compliance (and everything in between). This white paper should not only serve as a guiding light for any and all cloud native developers and admins (and the companies that hire them) but as a warning about the complex nature of security surrounding cloud native.
Because developing and administering in and for the cloud brings with it several layers of complexity not found when working with standard applications. And everyone involved in the relationship between the cloud and the company is affected.
Let’s dig into this whitepaper and highlight some of the more important bits, from the perspective of an administrator. So put on your admin hat and let’s go.
What Makes Cloud Native So Complex?
Right out of the gate, the CNCF paper discusses the complexity of cloud native operations. And anyone who has developed within this arena will not disagree with their assessment. The first point the paper makes is the focus on rapid deployment and development in conjunction with the impracticality of traditional “perimeter-based security.”
This is a big problem for many developers coming from a traditional background, if they assume the methods of securing a traditional application apply.
They do not.
In fact, as CNCF clearly indicates:
“This complexity requires a paradigm shift to protect applications by migrating from a perimeter based approach to one where security moves closer to dynamic workloads that are identified based on attributes and metadata.”
With cloud native applications, workload is key. Considering one of the primary benefits of cloud native is the ability to scale at will, the workload of an application takes center stage. Developers know this, so they give this functionality an almost singular focus. When the need to scale takes precedence over security, those deployed applications run the risk of compromise. In order to meet the needs of scale, while addressing the crucial security requirements of an application in constant flux, a paradigm shift is necessary.
For that, the CNCF states that cloud native development must be modeled into four distinct lifecycle phases: Develop, Distribute, Deploy, and Runtime. Let’s take a look at those phases.
With cloud native development, security should be introduced early in the application lifecycle, and security testing should immediately identify compliance violations and misconfigurations. By doing this, it is possible to create short and actionable feedback cycles, which opens the door for continuous improvement such that security failures are addressed in the same way as all other workflows are resolved before moving software from one phase to the next.
The CNCF also makes it clear the security lifecycle of modern cloud native development must revolve around code that adheres to recommended design patterns, such as the 12 Factor App, which breaks down development into these points:
- Codebase: one codebase tracked in revision code with many deployments.
- Dependencies: explicitly declared and isolated.
- Config: configurations are stored within the environment.
- Backing services: are treated as attached resources.
- Build, release, run: these three stages are strictly separated.
- Processes: apps are executed as one or more stateless processes.
- Port binding: services are exported via port binding.
- Concurrency: applications are scaled out via the processes model.
- Disposability: fast startups and graceful shutdowns.
- Dev/prod parity: development, staging, and production should be kept as similar as possible.
- Logs: should be treated as event streams.
- Admin processes: admin/management tasks should be run as one-off processes.
By using a recommended design pattern, you can ensure the integrity of a workload is delivered. And with cloud native development tied to Infrastructure as Code, such practices are meant to ensure all controls operate as intended and include early security check integrations to identify misconfigurations and implement best practices.
The software supply chain is one of the most crucial aspects of the lifecycle. Why? Because within the world of cloud native development, iteration is much faster than it is within standard development. This is especially true when dealing with CI/CD. And with cloud native, you need to include methods for verifying the integrity of the workload, the process for workload creation, and the means of operation. This is made even more complex by the use of open source software and third-party runtime images.
Remember, you are deploying containers, which depend on images. Those images can be the weakest link in the chain, as your developers might have pulled down an image containing malware. Those images need constant scanning for vulnerabilities, malware, and insecure coding practices, otherwise the cloud native applications built from those images would risk opening your network (and the data contained within) to attack.
The deployment of your cloud native applications needs to be accompanied by real-time validation of candidate workload attributes. You must make sure:
- Signed artifacts are verified.
- Container images adhere to security policies.
- Host suitability can be validated.
Another key aspect of cloud native apps is the ability to deploy with secure workload observability capabilities that allow for logs and metrics to be monitored with a very high level of trust. Such a high level of transparent observability, will serve to complement the already integrated security of your cloud native applications.
Think of observability as a new type of monitoring, geared specifically for cloud native deployments, and is built upon three pillars:
- Metrics: show you when you have a problem
- Tracing: points you to the problem
- Logs: help you find the root of the problem.
Finally, we have runtime. Your cloud native environments are required to provide strict policy enforcement and resource-restrictive capabilities. With cloud native applications, you have runtime resource constraints like Linux kernel cgroup isolation, which limits, isolates, and measures resource usage of a group of processes. Cgroup isolation is an example of restrictive/observability primitives which must be integrated into the higher levels of your cloud native application lifecycle.
One key high level component, within cloud native applications, is the runtime. Do not mistake this runtime with the runtime environment. This is runtime with regard to software and instructions that are executed while an application is running. Many times, the runtime will include instructions you did not explicitly write, but were programmed by a third party. Because of that fact, it is key that you work with best practices to secure all of these interconnected components, such that:
- Only sanctioned processes are allowed to operate within a container namespace.
- You prevent unauthorized resource access.
- Network monitoring is used to detect hostile tooling activity.
The security of cloud native applications must, at all times, be applied to each of these components to ensure the same conditions, diligence, integrity, trust, and threat prevention is applied throughout the entire lifecycle. Because cloud native development is exponentially more complex than traditional development, every layer must be approached with an eye for protection from unauthorized access. Your organization, your administrators, and your developers must adopt specific methodologies that shift security and give a renewed importance to DevOps, so you can ensure the security of your cloud native apps through the lifecycle of development, distribution, deployment, and runtime.