Microservices
Engineering
Security

Securing your microservices architecture

In 2021, companies reported a 31% increase in the average number of cyberattacks compared to the previous year. Gone are the days when cybersecurity fell solely under the purview of a specialized team.

Today, with the growing shift to microservice architectures, complex security vulnerabilities are commonplace. The risks are especially high if you are in the middle of your transition to microservices, as you may be unfamiliar with the weaknesses that they are prone to. Like its predecessor, a microservice architecture is susceptible to specific weaknesses. For example, the connections between various services increase the attack surface of the software.

It is important to no longer treat application security as an afterthought but to invest in comprehensive security solutions like OWASP to tackle these challenges. Not only should security be factored into the beginning of the software lifecycle, but it should also be acknowledged as an ongoing process. In this article, we discuss best practices for developing a microservices security strategy.

Design and Development

In traditional workflows, developers and security teams work on a piece of software one after another inside a platform with containerized workloads like Kubernetes or Amazon Web Services (AWS). The developers design and build it based on certain specifications. The security team will then review the code and point out bugs that are potential security risks. This information is relayed to the developers who find the bugs and fix them. However, this process can be made more efficient by avoiding back-and-forth communication and retrofitting on the part of the engineers.

The popularization of DevSecOps and the treatment of security as a first-class concern is not without cause. When you make security a core part of the active software development lifecycle, it is ingrained into the minds of the developers. It encourages sharing of responsibility and increases cooperation among teams. Where possible, DevOps teams must automate security tests and processes and build them into the application development pipeline.

Instead of treating them as afterthoughts, we recommend incorporating security considerations into the application’s life cycle from the design stage itself. This might mean that both security and development teams are involved in a collective process of writing the specifications. A few considerations that can be raised in this process include:

  • The failure modes that can be anticipated from a security standpoint
  • Guidelines for accessing personally identifiable information (PII) if it is being stored
  • The intent and possible consequences of logging information like secrets, as well as related protection mechanisms
  • The kind of data being collected by a service and possible risks of this data getting exposed

Security by design forces developers to consider potential security risks at the time of writing their code. Only by anticipating cyberattacks and thinking as a hacker would can the devs minimize the frequency and impact of such failures. As a result, they can brainstorm alternate security mechanisms that should be incorporated into the program.

An in-built advantage of using a microservices architecture over a monolithic application is that the principle of least privilege is included by default. This means that each microservice is independent in its functionality, so a security issue in one may only affect the subsection to which it is connected. It may be possible to turn off communication paths to other microservices. On the contrary, a monolithic architecture may be easier to take down in its entirety once it has been broken into.

In your ongoing development process, it is necessary to have a baseline as well as regular sanity checks. These can be a part of your automated CI (continuous integration) process. They should also include regression testing to ensure that bugs that have been fixed do not resurface in future versions of the software. It is also good practice to regularly scan for secrets and to block the application’s deployment if any vulnerabilities are noticed. Today, multiple open-source tools for scanning code are available, including an API from GitHub. The developers can also use protocols like OAuth 2.0 to develop and manage security services. Similarly, they can use OpenID Connect, which is an identity layer built on top of OAuth 2.0 to authenticate users.

Finally, running regular tests not solely focused on security is crucial. Unit, contract, and API testing, for example, ensure that the services work like they are supposed to. When security considerations have been incorporated into your software design, these security testing methods also contribute to your security strategy.

Production and Monitoring

Beyond development, security is an integral part of production and post-production processes. In these stages, we focus on network and access control in microservices.

You should also think about the platform where your services are deployed - on the public internet or behind a virtual private cloud. The point of contact between potential end-users and services determines who can access which services. For example, an e-commerce platform will only allow registered sellers to access the backend for their shops. This can have consequences in terms of data storage and protection for specific microservices.

Services often rely on one another to respond to a request from an end-user. Having a standard authentication schema between services, and keeping an eye on it, is of utmost importance. Such a schema presents a standard way for every service to authenticate with another. If a service makes a request to another within the same environment, each needs to verify that the request is valid. This standardization can be handled using a service mesh which can be secured through Transport Layer Security (TLS). TLS encrypts the traffic between microservices to secure the communication between them.

The authentication protocol should be put into place and exist through shared libraries. With a shared library, every service is not rebuilding the same logic as the connections and data are tracked in a central database. If you are using shared libraries, you need to keep track of the library versions that all of your services use and ensure they are up-to-date. Such uniformity across teams makes the enforcement of security easier.

In a microservice architecture, APIs are used to call the services. An API gateway centralizes the authentication process such that it is the entry point of security policy enforcement. The end-user is not required to share their information with each service that needs it. Instead, the API gateway issues a token that the user can show to each service. Subsequently, the services communicate with the gateway to verify the authenticity of the token. This strategy establishes end-to-end user-level trust and secures the service on multiple levels. Adding multiple layers of security to a microservice or adopting a defense in depth strategy delays or reduces the impact of a cyberattack.

Finally, monitoring and observability are crucial for threat detection and identifying security failures. Adopting these practices allows you to keep an eye on the software post-release. You can also use automation to speed up some of the processes. At the API level, too, all notable events must be logged, and the data should be stored in a centralized database. Securing the API gateway behind a firewall is also a strategic precaution against a security breach. You can extract and analyze potential security risks and take appropriate measures to stop any attacks.

Security is an Ongoing Process

Akin to testing, security is an ongoing process. Although it is important for developers to incorporate security considerations into their processes, they cannot replace other risk assessment strategies. For the services in production, professional penetration testing and working with bug bounty programs can significantly improve ongoing security checks. A penetration test simulates a cyberattack on the software to reveal bugs and weaknesses, as well as makes a note of the strengths of the microservices ecosystem.

Furthermore, the benefit of making your code open-source or visible to a larger group of people is that multiple perspectives are likely to spot risks faster. This is a double-edged sword, as this may also mean giving code access to hackers. However, while working in secrecy has its benefits, it does not shield your software from threats and hacking attempts. Running bug bounty programs incentivize entities outside of your team to identify and report vulnerabilities so that you can fix them as soon as possible.

You should be running continual vulnerability scans as part of your CI/CD process to deter a potential attacker. Zero-day vulnerabilities can severely harm your software if neglected for long periods of time. Capturing these every three to six months is a good practice to integrate into your workflow.

Additionally, you may be in a situation where you push some code today but do not release the microservice immediately after. Should you choose to return and release the code after some time, new vulnerabilities may have surfaced. Running a scan here would reveal any vulnerabilities that may have cropped up when the service was in a dormant state. Outside of your CI process, run continuous scans asynchronously to be in the loop if new vulnerabilities are introduced.

Microservices applications often use containers for deployment. It does not then suffice to merely check the code or the dependency of the service. If you are using container images like Docker, the actual underlying operating system for your container or the packages in it could have vulnerabilities. New container versions may also introduce unprecedented risks. So, implementing a robust container security strategy might help secure the microservices applications inside the container. Ongoing maintenance and security, then, benefit from regular container scans that ensure container security.

Finally, you need to have a cohesive strategy. This includes defining your long-term security posture. You should build a security team and give visibility to developers.

It is not enough for leadership to only look at reliability metrics or costs. They must also focus their attention on security practices and standards across the company. Teams look to leaders for guidance. If these leaders are not prioritizing security, it is unlikely that teams will do so.

There need to be clear reporting mechanisms and protocols to ensure executive-level employees are kept in the loop about security initiatives. Periodically engaging in reflection and brainstorming exercises are intangible and non-technical ways of injecting a security mindset into the teams. It is also good practice to regularly ask questions about the progress made as well as the largest risk areas to be confronted.

Giving developers visibility has far-reaching benefits. If they spot a vulnerability, they must know to alert the security team and communicate it to the service owners. They can learn to enforce standards and ask external service providers to meet baseline expectations.

With centralized standards and policies in place, teams can adapt them to their workflows and services. There is no need for everyone to come up with their own policies. This ensures consistency and saves time and effort. Some specialized needs, however, may require service-specific policies to be fulfilled.

A solid documentation practice, too, has advantages for your security strategy. Ask your developers, testers, and security teams to maintain clear documentation about security challenges and subsequent fixes. This allows new recruits or teams in the future to learn from the experiences of those who worked on similar problems before them. They can then focus their efforts elsewhere.

Implementing your Strategy

Having a high-quality security infrastructure in place can boost your software’s quality and performance and help you scale rapidly. In addition to prioritizing security, how you integrate it into your workflows and systems is telling of its efficacy. Incorporating it at every stage and encouraging developers to do so is not an effortless task. Change takes time, especially when you are used to certain processes and are juggling competing priorities.

At Cortex, we offer a range of tools to help you effectively manage your microservices architecture. Our service catalog lets you keep an eye on your services. You need not spend time looking for documentation or information on dependencies, tools, or even the ownership of each service. It saves you both time and effort that is better spent on actually fixing the bug or acting on pressing vulnerabilities.

Furthermore, to successfully adopt a DevSecOps system, you must establish standards and communication channels across the organization. Developers and security experts, for example, need to share knowledge. When these teams are on the same page, the process of developing and deploying secure microservices becomes much smoother. Scorecards make it easy for you to define best practices for microservices and communicate these across teams. Cortex centralizes all your relevant data, facilitating even the process of tracking and responding to security-related concerns.

Reach out to us at team@getcortexapp.com if you have any questions or would like to learn more.