Adopting and implementing cloud-native patterns and methodologies is one thing. Another important aspect is securing and hardening cloud-native applications. Securing cloud-native applications is an ongoing, time-consuming, and maybe a tedious challenge. Especially smaller teams may struggle with securing all aspects of their cloud-native application.
- Part 1: Code, Container, Cluster, Cloud: The 4C’s of Cloud-Native Security ⬅
- Part 2: Container Security: The 4C’s of Cloud-Native Security
- Part 3 Cluster Security: The 4C’s of Cloud-Native Security
- Part 4: Code Security: The 4C’s of Cloud-Native Security
- Part 5 (coming soon)
In this article, we will look at the 4C’s of cloud-native security. Those “C’s” represent the different layers where developers and DevOps teams have to ensure security best practices to meet overall security goals and pass corresponding gates before exposing cloud-native applications to their customers.
From a developer’s perspective, we should first talk about code security. All tools available to increase code security fall into one of the following categories:
- Static Application Security Testing (SAST)
- Dynamic Application Security Testing (DAST)
- Interactive Application Security Testing (IAST)
Producing secure code should be top of every developer’s mind. This means we’ve should not just use proper libraries and frameworks to reduce or eliminate the risk of attacks like SQL injections, cross-site scripting (XSS), or others. Additionally, we should design public API surfaces and interfaces with care and ensure proper handling of edge cases or invalid arguments being passed to those entry points. However, even if we as developers follow these rules, we can’t be 100% sure that all aspects of our application are safe.
Fortunately, there are tools available that can assist here. SAST tools scan our source code for known types of vulnerabilities and anti-patterns. As developers, we can use SAST tools – like, for example, CodeQL or SonarQube – locally (i.e. in the developer’s inner loop). Being able to check your code almost instantly is beneficial because you can fix potential vulnerabilities immediately.
Most popular SAST tools allow seamless integration with existing continuous integration (CI) systems such as GitHub Actions or Azure DevOps pipelines. Invoking SAST during CI runs is important because merging code may introduce unexpected vulnerabilities.
When it comes to DAST, you can think of black-box testing because the DAST tools do not have access to your application’s source code. In contrast, a running instance of your application is examined. DAST allows you to detect misconfiguration and misbehavior, not just by mistakes accidentally made in source code but also introduced by inappropriate runtime environment configuration.
DAST will help you harden your application against well-known vulnerabilities listed by the Open Web Application Security Project (OWASP).
The third category of tools for securing the code of your cloud-native application is IAST. You can think of IAST as a combination of SAST and DAST, where your application is actively observed at runtime. However, DAST incident or vulnerability information is enriched with important contextual information (traces, source references). This means IAST tools typically consist of three parts.
- First, there is a library (or a package) that you’ve to integrate with your application on the source code level.
- Second, an IAST server component is often used to analyze, categorize, and report incidents.
- Third, a scanner that observes your application from the outside. This typically takes environmental aspects into consideration.
The next layer that should be secured is the container layer. For containers, you have to care about two different security aspects. First, you should build your custom container images with care. Not relying on a privileged user (root) is perhaps the most popular and prominent rule when it comes to authoring a good
On top of that, your Dockerfiles should be checked for numerous rules. Fortunately, we do not have to memorize all those rules. Instead, we can use tools like dockle to scan a container image and get recommendations to optimize its
Additionally, you should always check all of your container images for known vulnerabilities. By scanning your container images, you cannot just find vulnerabilities of your application or the framework and programming language you have used. You can even spot vulnerabilities in all components being part of the container image and even the underlying operating system used in the container. Again there are many tools available to do vulnerability scanning for container images. Quite popular tools are provided from AquaSec, Qualys, and Snyk (which is also seamlessly integrated with Docker Desktop and accessible via the docker scan command).
Last but not least, you should consider signing your container images. You can ensure your container images integrity and establish higher trust with signed container images because you can prevent the execution of unsigned container images.
Docker Inc provides some good documentation on setting up and working with signed container images. Just browse the official documentation and look for Docker Content Trust (DCT) to dive deeper.
The third layer in cloud-native security is the cluster layer (or, to be more precise: Kubernetes). Kubernetes and its vibrant open source community offer a wide variety of concepts and tools that we can use to harden both the Kubernetes cluster itself and our application workloads running in the cluster.
From a Kubernetes cluster point of view, we must ensure proper authentication and authorization. In conjunction, AuthN and AuthZ are used to limit access to the cluster only to desired people and services. If you’re using Azure Kubernetes Service (AKS), you can configure seamless integration with Azure Active Directory (AAD). With this integration in place, you can use plain old role-based access control (RBAC) to enforce control cluster access.
On top of that, you should consider implementing NetworkPolicies. By adding NetworkPolicies to your Kubernetes cluster, you can lock down your containerized applications and stop unwanted network communication between your application components or between different applications running in the same shared cluster.
Another great example when it comes to cluster security is the use of custom admission controllers. In Kubernetes, we can use validating admission controllers to reject inappropriate requests sent to the Kubernetes API server. For example, you can use a validation admission controller to reject all privileged Pods.
These were just a few samples focusing on securing your Kubernetes cluster. Please consult the official Kubernetes documentation to dive deeper into securing and hardening your cluster and applications deployed to a certain Kubernetes cluster.
Last but not least, we must take care of the surrounding cloud. Moving containerized applications to the cloud is easy. Cloud vendors simplify the onboarding experience to get more and more customers on their platform. However, securing those cloud infrastructures and continuously monitoring and responding to threats is time intensive and may become complex depending on the overall cloud footprint.
To harden and secure cloud infrastructures, teams typically use services from four different categories:
- Security Information and Event Management (SIEM) hosting
- Security Operations, Automation, and Response (SOAR)
- Cloud Workload Protection (CWP)
- Cloud Security Posture Management (CSPM)
SIEM analyzes activities and signals in an environment and distinguishes between regular and anomalous incidents. For anomalous incidents, SIEM alerts were generated. SOAR tools are used to react, automate and finally respond to anomalous incidents reported through SIEM alerts. Speaking about Microsoft Azure, Azure Sentinel addresses both SIEM and SOAR.
On the other hand, we have Azure Defender for Cloud (previously known as Azure Security Center), addressing both CWP and CSPM. It automatically monitors all security- and health-sensitive configuration of your Azure environment. Azure Defender for Cloud flags misconfigured services and provides its users with detailed recommendations on remediating them.
Additionally, users can integrate Azure Sentinel with Azure Defender for Cloud to respond quickly to insecure service configurations.
Separating responsibilities for securing your cloud-native applications according to the 4 C’s of cloud-native security helps define responsibilities and actionable work items. Often, each category comes with its own tools and tool vendors, which reflects in terms of licensing and legal discussions with those vendors. However, securing all aspects of your cloud-native application (and we did not even reference application layer security topics like OAuth 2.0 or OIDC in this post) is unfortunately often underrated or even ignored.
I think teams leveraging cloud-native technologies should care more about securing their workloads. Pushing some of the responsibilities to the left (towards developers) is generally good. Organizations must provide their teams with the necessary tools and licenses to ensure their products are secure and operated according to security best practices.