The goal of modern applications and services is to provide the best possible experience for our users, in a secure and reliable way. Cloud applications that utilise more recent architectural patterns, or are migrating to newer topologies, need to revise their current security requirements to compensate for those new risks. To maintain the CIA triad of security (Confidentiality, Integrity and Availability), we need to discover new ways to incorporate security controls and tools into our infrastructure.
One way to achieve that is to determine the best place to perform checks and preventive actions. This is where the cloud design patterns come in place.
Let us explain what cloud design patterns are and how they relate to security and best practices.
Cloud computing design patterns
Every business entity that deploys applications in a Cloud environment should perform constant security reviews of the risks associated with that transfer of responsibility. There is a controversial article about why the Cloud is just someone else’s computer. When a business offshores the internal operations and infrastructure to a third party (aka Amazon or Google), something is expected in return. In addition, when operating Cloud infrastructure, it tends to get completely architected (or over-architected) in advance, often by utilizing vendor services (Amazon SNS or Managed Kubernetes for example). Also, the business tries separating services, creating availability zones, externalizing configuration and so on. Those changes eventually end up as patterns, occasionally duplicating functionality for each service.
Cloud design patterns are architectural and can indicate potential solutions to particular problems that arise when engineering applications in the Cloud. Every case is different, so it’s recommended to have a “common sense” approach and protocol when introducing something new to the scene. Here are some of the most useful patterns in practice:
Bulkhead: A Bulkhead is another name for offering service levels for each application. There are standard services, but there are also critical services that you may need to be constantly available; they may, however, also consume more resources. We as solution engineers, want to isolate levels of service so that if one of them fails, then the others are unaffected. This is especially significant if we want to maintain the availability of the system.
SideCar: Reasonably often, when we develop services, we include other services, which are then available as support services next to the deployed application. For example, logging, monitoring, cross-cutting logic and configuration-handling are all functionalities that work alongside each application. The sidecar pattern is just another process that sits next to the application, often in the same host that offers those common services, which relieves the developers from implementing those inside the applications.
API Gateways: An API Gateway is the modern front door of the backend API. They work by consolidating the backend services to a unique entity by offering a unified API. The backend part may contain thousands of entities, so it’s not viable or practical to expose that in the client side. Plus, the management of things like SSL certificates and connection handling should not be duplicated or mishandled, as they could have catastrophic effects on availability and confidentiality. The API Gateway helps by decoupling all of those operations, and creating separate services. It then combines the results into one service that acts as a facade of other operations.
Microservices: When we develop a server-side enterprise application, we need to provide solutions that are easy to maintain and test. If we were to place all our business logic in a monolith application in the cloud, suddenly it would be remarkably difficult to change something without affecting something else totally unrelated. Plus, if we have lots of different cross-functional teams, we also want independent releases with low communication noise between them.
The most suitable solution is to use the Microservices approach when developing new services. Each service is independent and developed by a team with its own release cycle. This enables more rapid and continuous delivery, better scalability and testability; and most important, isolation. However, by doing that, we increase the complexity and communication costs between the services, so we need additional controls that handle failures in a consistent and secure manner.
How design patterns impact Software Security
Now that we have an understanding of modern design patterns, let’s resolve the initial question: How do they impact software Security?
Well, as we did mention before, tools that work alongside our applications are primary candidates for adding or handling new security controls.
We include modern patterns because we want to prevent failures from propagating to other services or affect their status.
The Bulkhead Pattern, for example, is suitable for enhancing the Availability of the system. Without it we risk having cascading failures, or loss of quality when we serve some request.
The SideCar pattern can be used in an Application Firewall or a Request filter for each application, handling cross-cutting rules and triggers that respond to invalid on dangerous requests. This prevents issues with the Integrity of our applications.
The API Gateway handles SSL termination and renewals, delegating requests to the appropriate services. This handles confidentiality issues, for example.
Some other patterns handle more specific issues or problems in a different angle. For example Federated Identity is a secure and reliable way to handle Authentication, as it simplifies a lot of the annoyances and the risks involved when dealing with user identification across multiple environments.
Take extra care to apply the right design patterns in the right context, as not all of them offer good benefits. They can affect security negatively, as well. For example, make sure you handle caches appropriately, and clear them when necessary to prevent leaks of cached data or allowing out of expiry date sessions. Make sure you have tried and tested bulkhead configurations in low resource scenarios before applying them, as they may tend to make services unavailable even when resources are available.
Nevertheless, we can note several examples of tools that utilize the SideCar pattern to aid the overall security posture of our infrastructure. For example, how we handle secrets for human and non-human actors is a very important design decision. We wouldn’t want to have insecure controls in place that allow cunning attackers to steal credentials, login and exfiltrate sensitive data, for example.
Tools, such as CyberArk Conjur, that work alongside vendors and utilize modern design patterns, remain a sound choice when it comes to handling secrets in a Corporate environment. CyberArk’s newest tool, called Secretless Broker, utilizes the Sidecar Pattern to properly handle secrets fetching and handling between applications, and secret stores all in an opaque manner, so it’s worth checking it out.
Cloud computing design patterns are important techniques available in the arsenal of the modern Cloud Architect. While each one of them has their pros and cons, when it comes to security, we need to be particularly sensitive if we aim to maintain the CIA triad. However, if the available security tooling such as Conjur leverages the best parts and works alongside our patterns, it can be a significant benefit to utilize them for our purpose. Let me know what you think about these design patterns or other topics related to open source in the CyberArk Commons.
Theo Despoudis is a Senior Software Engineer and an experienced mentor. He has a keen interest in Open Source Architectures, Cloud Computing, best practices and functional programming. He occasionally blogs on several publishing platforms and enjoys creating projects from inspiration.