By Marco Fioretti
The microservices software architecture implements each main function of large web platforms exactly as a separate, smaller service running in the cloud. Security-wise, the nature of both microservices and of their Application Programming Interfaces (APIs) present the unique opportunities and challenges summarized in this article. Before digging into this topic, you may want to first read the earlier pieces in this series, Microservices: Definition and Main Applications and APIs in Microservices.
Since they are distributed over different servers, microservices often expose a bigger and more diverse attack surface than a monolithic implementation of the same platform. This makes it harder to find and fix vulnerabilities soon enough to avoid problems. At a minimum, this requires real time analysis of lots of heterogeneous data. Even ignoring security, designing many interconnected microservices in such a way that if one of them fails or is compromised, none of the others will break or lose their own internal data can be quite complex.
On the positive side, those same characteristics make it possible to configure and run each single microservice with whatever security measures are the best possible for it, regardless of the needs of its peers. In that way, if an attacker did succeed in compromising one microservice, she may be unable to reuse the same techniques or knowledge to compromise the others.
The starting point for designing secure microservices is easy: actively involve security specialists from the very beginning of development, rather than asking them if everything is ok when design and implementation are over.
Standard security techniques developed over the years for traditional Web-based applications become even more necessary with microservices. We refer to measures like:
- sanitize input data to prevent command injection
- encrypt every communication because among microservices that run in the cloud no communication is “internal”
- for the same reason, encrypt data as early as possible and decrypt as late as possible; a microservice that, for example, must relay messages between other microservices has no business decrypting their payloads
- whenever possible limit the connection rate of a microservice to prevent Denial of Service attacks
- set up automated testing, deployment, and logging procedures at all levels, from application to infrastructure, with automatic alerts for administrators as soon as an anomaly is detected
Besides these basic best practices, some of the most widely applicable security measures for microservice-based platforms are those mentioned in the following sections.
Keep your software always clean. ALL of it
Regardless of origin or license, every release of all your microservices must have adequate release notes that list the security fixes they received. Which may be obvious, but what may be less obvious, and quite harder to achieve, is that the same guarantees are equally needed for all the third party components your microservices use, all the way down your software supply chain. In the real world, getting that information with enough details and in a standard format that is easy to analyze can be quite a challenge, unless every component comes with a proper Software Bills of Materials (SBoM).
Containers are microservices’ friends. When they are really secure, that is
One of the biggest advantages of microservices is the ease with which administrators can upgrade or roll back every single component of a platform, in any moment and with the smallest possible impact on the rest of that same platform.
The easiest and most common way to achieve this isolation and enforce custom security measures is to deploy each microservice into its own container. In practice, this works as expected only if the containers are created and managed properly, from images that contain as little software and data as possible, and are as protected as possible. The container images for your microservices, for example, should not contain passwords or other credentials (more on this below). Additionally, they should be digitally signed, have suffixed tags to guarantee that administrators always get the exact versions they need, and kept in a private repository with secure versioning like Harbor. The actual deployment and management of the containers may happen with tools like Docker, cri-o or containerd. In all cases, however, those tools should run with as little privileges as possible, like Docker’s rootless mode, in order to minimize any vulnerability that they may have.
Control all accesses, without reinventing wheels
A microservice should not only restrict access to only allow authenticated users, but should also let those users access only the smallest set of its functions and data that they really need. In many cases, the first protection of this kind could and should be a Microservices API Gateway, that leaves attackers only one, highly protected entry point to the whole platform.
Alternatively, or in some circumstances in addition to an API Gateway that may even be used only to maximize performances, rather than security, you may give each microservice its own authorization server, with its own set of certificates and keys for authentication and encryption purposes. While making the platform as a whole more complex to manage – and potentially slower – this strategy greatly increases its security and robustness. Whatever authorization strategy you choose, stick to well proven, open industry standards for authentication and access control like OpenID Connect and OAuth 2.0.
Keep access credentials and keys safe
As mentioned above, the container images of your microservices should not include user passwords, API authorization keys or equally sensitive information. The less such data is in the cloud, or scattered around several repositories, even if they are private ones, the better it is. A safer, and usually easier to manage solution is to keep all the data in one central vault, passing them to the microservice containers only when they are actually launched, for example through environment variables.
Last but not least, multiple layers of defense
Since a platform’s microservices are distributed around the cloud, they have no single, well-defined “perimeter” that could be adequately protected by a traditional firewall. In practice, however, this makes little difference, because the right approach to protect microservice platforms is to always adopt a zero trust approach and multiple layers of protection. Always combine, that is, tools like distributed firewalls or service meshes with the other techniques mentioned here, starting from the microservices that manage the most sensitive data.
Be sure to read the next article in this series, How Microservices Work Together.
If you want to improve your or your team’s cybersecurity skills, consider some of the training courses and certifications on this topic offered by Linux Foundation Training & Certification.