Without going down to the level of which architecture is more comfortable or suitable for deployment into the organisation’s application stack, I’d like in this blog post to try and extract the differences in security across monoliths, SOA (service-oriented architecture) and microservices architectures and then lay out few security best practices and points to think about in a microservices architecture.
To date, the trend is a one way direction, with more and more organisations moving away from the monolithic and SOA models which seems to be as outdated (but still works good in some use-cases), towards a decoupled, distributed, microservices-based architecture.
If a migration is our use-case, then the first question we should ask ourselves is how do we balance the migration with (usually) a large amount of time investment vs. the outcome benefit and effectively completing the migration, while keeping security along the way? If a blank sheet is our use-case for a newly developed application stack, then the focus should be set on embedding the right security controls from day-one, while maintaining/updating those throughout the life-cycle of the stack.
In both cases, the main consideration will be not to compromise on quality. Sometimes we put too much emphasis on moving as fast as possible. Business needs to understand that an unchecked quickness of release is not realistic. It can hobble reasonable security efforts, which don’t have to work against reasonably quick releases.
When looking at transformation in the move to microservices, we ought to estimate the tremendous amount of change across the organisation –some flexibility will be required from everyone related.
I’ve gathered few insights, from my own experience and knowledge in this space, which could benefit your journey, while thinking on your next app deployment, a tactical migration between architectures, or long-term strategical solution.
Understand how mature is your DevOps culture and your SDLC & CI/CD pipelines, will determine how “easy” it will be to overcome some of the challenges aroused while adopting microservices architecture. microservices architecture can be highly complex, they create a lot of potential attack surface and if we’re not looking into things such as infrastructure configuration, configuration of the Cloud services in used, etc. then we need to think on how we can practically secure a highly distributed application?
Remember that it takes time to move from existing monolithic/SOA based apps into microservices. You should asses not only the operational aspect, but also the security of it (e.g. does the code base needs to be matured enough to fit into the new architecture? Can you maintain and/or improve existing security controls within the new architecture?)
Testing for microservices can become complex, because it can be harder to setup the ‘state’ necessary to interact and find some logic bugs or other types of flaws with a particular workflow.
In microservices, the attack surface is probably become larger, especially if we’re not maintaining homogeneous environments, which creates incredible diversity between data sets as well as multiple languages/frameworks.
One of the issues with monoliths, is that it can have a dependency on the updating and curation process for (updates, vulnerabilities fix, etc.), as we tend to have then a diffusion of responsibility, with multiple teams relaying on a single dependency, unless there's a very explicit process with the correct assignments on responsibility. Also, the change itself can potentially be a bit slower, as one change can have a lot of cascading breaks, so hopefully you will have a good testing in place.
In applications where the model is based on growth, expansion and up-scaling, this sort of tight coupling between the components, characterised within monolithic architectures, results in slower and more challenging deployment, hence the trend.
When choosing microservices, (runtime) containers are dramatically better for security than virtual machines, as it encapsulate a lightweight runtime environment for the application, reducing the attack surface associated with an OS layer.
Microservices are distributed across multiple Datacentres, CSPs, and Host machines. Deploying infrastructure across many platforms and environments, increases the risk of losing control and visibility of the application components.
Microservices expose new entry points to both internal and external actors, as opposed to the traditional monolithic/SOA architectures, with fewer ingress/egress points of access.
Data generated in a microservices architecture moves, changes and is continuously interacted with. Data is also stored in different locations and for different purposes. Hence it becomes a challenge if we don’t have a continuous visibility and protection controls over this data.
When you look on SOA as a “good enough” alternative to microservice (loosely-coupled vs. decoupled), know these pros and cons associated with it: The components can be reused in multiple applications without influencing other services, relatively easy to update and maintain it without impacting other services, services are easier to debug and test than are large pieces of code as in the monolithic approach –hence increasing the application reliability, and support a parallel development approach. On the other hand, SOA introduce a potential complexity with each service has to ensure that messages are delivered in time, it costly and as inputs are validated before one service interacts with another one and it increase latency by an increased response time-which decreases overall performance.
As monolithic and SOA architectures have been with us for a while now, I don’t think we need to repeat what is already being known, but instead I’ll try to map out few security best practices for microservices architecture:
The critical mechanism to secure applications has always been authentication and authorisation. Ensure those are kept with its best practice, while and once migration is completed, or embedded into the solution from day-1 for new deployments.
Make your containers immutable, with any defects or vulnerabilities fixed by rebuilding/redeploying these containers, along with the data stored outside the container, to maintain availability.
Owners of data assets need insight into the life cycle and the dynamics of data to avoid breaches.
Create trusted image repositories as a source for deployments, once you have confirmed all images are clean from any known vulnerabilities and malicious code. In addition, validate application signatures in scripts before deploying containers into Production.
Use container-native monitoring tools to collect events and ideally benchmark them against the security policies of your organisation.
Secure and protect the APIs (both private & public). Microservices by its design, communicates between the different services over APIs, spreading the attack surface. *See this blog post on how to best protect and secure your APIs.
Create Defensive Depth. Protecting your microservices will never come down to a singular solution or practice. We have to create defensive depth, including as applied to microservices, not just top-down. The defense in depth approach creates a multi-layer security to prevent attacks. *See this blog post on defense in-depth best practices.
Consider using OpenID or OAuth 2.0 to simplify the process of securing microservices by allowing (a developer) to process user tokens. There are four different roles that OAuth 2.0 can play in microservices security patterns: resource server, resource owner, authorisation server, and client. These tokens are responsible for access to the resource prior to its expiry time, and ‘Refresh Tokens’ that are responsible for requesting new access after the original token has expired.
For sensitive data (PII, secrets, transnational data, etc.) traffic, consider adding extra encryption on top of TLS/HTTPS, which could help at the point where TLS terminates (e.g. accidental dumping into a request log). Also, consider to encrypt the user data before persisting it.
Tight and centralised Access Control polices for users, applications, groups, devices and APIs, is a key aspect when looking into securing decoupled infrastructure, as by its design microservices architecture exposes new entry points to both internal and external actors.
Comments