It’s often true that threats evolve faster than development practices and technologies can keep up with, which can be seen in the current microservices approach to application development. While microservices bring clear benefits to developers by enabling application deployment via modular, independently deployable services, they also open the door to new security vulnerabilities.
Consequently, these changes in the approach to software development require a change in the mindset of developers regarding how they think about and implement security. Security now must be a core component of each service—security that can withstand the constantly changing nature of these interactive services. Each service must be a resilient and secure unit that is capable of interacting with other apps and services without compromising security. In addition, each service must be careful how it handles data at the edges to ensure every possible interaction can be secured, even when interacting with services that do not meet the required security standards.
To fully address these security challenges, developers also need to change their mindset on how they approach privacy and security in their code. That means thinking of security from the genesis of the program and from within the code itself rather than relying on the infrastructure to secure the application. This approach enables developers to start their architectural decision-making by thinking of security as the foundation of their code, instead of as an accessory.
Security from the Start
In the bigger picture, DevOps teams must have full awareness and appreciation that there is no single approach to security, and that security and privacy considerations must be addressed case by case. Although there can be more, there are essentially five things that developers can do to make microservices security foundational to the development process.
First, developers must begin compartmentalizing the software development mission by attempting to make their microservices as essential as possible. Still, developers have to be careful not to go to extremes that result in the creation of a swarm of nanoservices performing a single task. The overall goal is to reduce responsibilities to the point where each single process lacks enough information to be a liability if it were to be breached.
The role of encryption plays prominently in the new mindset for developers, so it’s imperative to utilize it on all of the data that each microservice needs and sending it on a perishable channel. This allows the cancellation of a compromised communication channel, rotation of the encryption keys used and retrying the message on a different channel or to a different node without worrying about a breach.
A good example of this is a node where control has been lost in a high availability (HA) layout. By cancelling all message queues and resending the messages with a rotated key, it’s possible to continue functioning without worrying that the unresponsive node could be compromised and avoid a full stop.
Disposable Channel Signing
Developers will greatly improve their security posture in the software development life cycle (SDLC) by sending disposable channel signing and encrypting data to the services under their control. This will allow them to cancel credentials, and avoid data leakage, even when the control on the node is lost.
Developers are beginning to understand the efficacy in using as many different keys as may be needed since storage is a weak point in terms of encryption. The alternative is to use keys that are rotated regularly. This, however, requires going around the persistence solution and re-encrypting a lot of the data, which is not ideal. Besides, having layers of encryption will ensure that a single leakage from the storage keys will not grant access to plain data. Also, it’s important to use different keys for storage and transport, as re-encrypting on read is easy. This process avoids the need to spread keys and keep it tight.
Finally, developers will benefit from making sure that all keys allow the minimum possible access while keeping in mind that they will need to tailor the time to live (TTL) as much as possible to the targeted use of each key. Although this approach may result in a complex permission schema, it delivers a massive reduction of the attack surfaces while adhering to security best practices.
Some of this may be common sense, and what is useful for one developer might not be sufficient for another. Generally, it’s good for developers to regularly challenge these suppositions on every service that they write, but the above formulated guidelines will serve almost every developer well by providing a stable foundation on which to begin their thinking. The universal viewpoint that they should all be taking is that security must be part of the DNA of their software.