Microservices Security Consideration
- Posted by Omnia Anany
- On December 12, 2023
What is Microservices architectural?
Microservices are an architectural and organizational approach to software development where software is composed of small independent services that communicate over well-defined APIs, the many benefits of microservices architecture, such as improved scalability and agility, explain why organizations are migrating from the traditional monolithic architecture, this modularity makes them more resilient to attack than monolithic applications. It also introduces new microservices security challenges.
Why is microservice security so important?
Microservices are susceptible to cyberattacks such as man-in-the-middle, injection attacks, cross-site scripting, and DDoS, to name a few. They have a much larger attack surface than monolithic applications and it can be a challenge to aggregate security logs from many different services and platforms.
Security Challenges examples:
Authentication and authorization
One of the key security challenges in a microservices security architecture pattern is how to ensure that only authorized users and services can access the resources they need. Unlike a monolithic application, where a single authentication and authorization mechanism can be applied at the entry point, a microservices application may have multiple entry points and service-to-service interactions. This means that each service needs to verify the identity and permissions of the incoming requests, which can increase the complexity and overhead of the security logic.
Data protection and encryption
Another security challenge in a microservices security architecture pattern is how to protect the data that flows between the services and the external sources. Since each service may have its own data store and communication protocol, there is a risk of data leakage, tampering, or interception by malicious actors.
How to secure microservices:
When it comes to securing a microservice, there are four fundamental areas to consider:
1. Control access to microservices(north-south) :
In most cases, the microservices you create will be internal-facing ones that power specific components of your system. These shouldn’t be accessible outside your Kubernetes cluster or cloud environment. Blocking access to all but essential public services will reduce the likelihood of vulnerabilities in service APIs being found and exploited.
This layer of protection, referred to as “north-south” security, secures the perimeter of your services by creating a barrier that separates your system from the public network. While effective north-south protection measures prevent attackers from penetrating your system, they shouldn’t be your only line of defense.
1.1 Using API gateways
API gateways are a reliable means for implementing north-south security, with the gateway placed between your users and the backend services it protects.
Using a gateway correctly requires configuring your networking so that the gateway fields all external requests. The software will then evaluate each request using policies that you set. These policies will determine whether access should be granted and then route the traffic to the correct backend service.
A reverse proxy that forwards traffic to whitelisted endpoints is the simplest type of gateway. You can use popular software such as NGINX to set one up. Kubernetes ingress controllers also count as gateways, because they automatically route traffic to the specific services you choose.
Placing all your services behind a consistent gateway provides centralized monitoring and clear visibility into publicly accessible endpoints; whereas, not using a gateway would be risky, since you might unintentionally expose services that should be private.
1.2 Implementing rate limiting
Rate limiting defends against misuse of your services. Attackers may attempt to overwhelm your infrastructure using brute force methods, such as credentials or common endpoints like /auth and /admin. Similarly, denial-of-service attacks occur when malicious actors send an overwhelming number of requests, thus preventing legitimate traffic from being handled.
Rate limiting provides protection against both attack methods by tracking the number of requests made by each client IP address. Sending too many requests in a defined period will cause subsequent requests to be dropped for that IP. The overhead of handling the rate-limit check is far less than it would be if the request were allowed to reach its destination server unimpeded.
API gateways and rate limiting thus complement each other. Applying rate limiting within your API gateway guarantees it will be applied globally before traffic hits your microservice endpoints. Rate limiting can also be directly incorporated into specific services for fine-grained configuration and enhanced interservice protection.
2. Control internal communications between microservices (east-west)
While north-south security secures your perimeter, the east-west plane deals with traffic flowing between your services. Each component should be isolated, without the ability to connect with or discover other services, even when they are deployed adjacently.
You can create exceptions to facilitate your application’s legitimate interservice communications by designating the components that can call a service (e.g., an invoice generator that makes requests to your payment layer). This “blocked-by-default,” “enabled-on-demand” model forces you to be intentional when opening up interfaces.
Allowing unrelated services to access each other opens pathways for threat actors to move through your system. Permitting only the bare minimum number of connections to each component, therefore, will slow attackers down and mitigate any damages. If malicious actors do manage to compromise a low-risk system, they shouldn’t have the opportunity to stage threats against more sensitive ones.
East-west security measures relate to how your microservices are individually isolated and connected. These protections make it harder for an attack against one service to spread to other services. East-west also helps you achieve a robust zero-trust security model by acknowledging the potential fallibility of the API gateway, as well as the risks that individual services pose to each other.
Protecting services with authorization
Service-level authorization permits implementation of specific access control policies for each application in your stack. This can take on several different forms, including both centralized and decentralized policy management approaches.
Decentralized vs. centralized authorization
Decentralized authorization incorporates policy decisions and enforcement into the code of your microservices. Each service defines the rules, attributes, and enforcement checks it needs to verify whether a particular request is authorized to proceed. This approach is ideal when your services have highly specific authorization requirements.
Centralized authorization models place your policies and their evaluation routines within a separate repository that microservices can interact with. The code within your microservice communicates with the authorization system using an API it provides. The microservice will need to supply the user’s identity and any attributes relevant to the target endpoint. The authorization provider assesses the information and produces an “accept” or “reject” response.
Centralization is not as flexible, but it can be easier to set up and maintain due to there being one central place to set up authorization policies, implement their enforcement routines, and register user associations. This works well with identity federation solutions such as OAuth and SAML.
Authorization tokens
Microservices usually authenticate to each other by including a signed authorization token in their HTTP requests. Each token should include the identity of the calling service and the permissions it has been granted. Standards such as JSON Web Tokens (JWTs) allow the recipient service to verify whether the token is genuine.
Tokens can be difficult to deploy across many services, however. Mutual TLS (mTLS) is an alternative method that works at the transport level. With mTLS, microservices are assigned their own public/private key pairs that allow them to authenticate to other services over the mTLS protocol. This helps keep network communications secret while facilitating built-in authorization. However, you will still need to issue certificates to each service before mTLS authorization can be verified.
Enable transport-level security
Communications between services must also be secured at the network level. TLS can be used to encrypt your cluster’s traffic, prevent eavesdropping, and verify the identity of callers.
TLS can be enabled for microservices deployed to Kubernetes by ensuring all traffic flows through Services that are protected by your own certificates. The cert-manager operator is the easiest way to automate TLS configuration in your cluster. It lets you provision new certificates by creating Certificate objects. Certificate is a custom resource definition included with the operator.
Dedicated service meshes like Istio make it even easier to network many different services securely. These complement container orchestrators such as Kubernetes, offering improved support for traffic management, authorization, and interservice security.
Implementing Kubernetes networking policies
Networking policies are a specific Kubernetes tool for implementing east-west security. You can set per-pod criteria that define which other pods are allowed to communicate with the target.
This simple policy stipulates that pods with the component=payment label can only be accessed by other pods with the component
3. Audit your microservices before deployment
Security is only as good as the weakest link in the chain. A backdoor in a package used by one of your services could be exploited to allow movement into other services.
Thoroughly auditing your containers before you deploy them into your environment will help mitigate these risks. In addition, using hardened base images or assembling your own from scratch will help to ensure there is nothing dangerous lurking within.
Automated security testing techniques like DAST, SAST, and IAST can be used to detect possible flaws in your code. Likewise, vulnerability scanners can help to identify redundant and outdated packages in your container images. Modern scanners cover both the dependencies used by your code and the OS libraries installed with system package managers.
Adopting a secure-by-design mindset means that developers, operators, and project managers alike must prioritize security and incorporate design changes to address any weaknesses. In keeping with this approach, you should harden your microservices as you create them.
Microservices are dynamic, complex, and assemble large-scale systems. It is therefore important to plan and establish strong container-level security as a first line of defense.
4. Harden your cloud environment
Hardening the environment that hosts your deployment is the final element of microservices security. Basic cloud security hygiene measures (e.g., limiting user privileges and regularly rotating access tokens) are vital, but there are also specific best practices for distributed systems like Kubernetes.
Scanning your cloud
Cloud security scanners offer a convenient way to detect misconfigurations and security weaknesses. Regularly using tools such as Amazon Inspector, Oracle OCI’s vulnerability scanner, or Google Cloud’s embedded scanner can alert you to vulnerabilities in your deployments and your management infrastructure.
While even a positive result doesn’t guarantee full protection, these tools can help you efficiently uncover improvement opportunities. For example, Amazon Inspector continually scans your AWS workloads for known vulnerabilities, probing your virtual machines, containers, networking rules, and other assets to identify threats in real-time. It then issues a security risk score that keeps you informed of your security posture. The other cloud providers offer similar capabilities in their own tools. These methods give you quick and accurate results without any manual intervention.
Conclusion
There’s no single way to harden your microservices or to guarantee your apps are protected. But focusing on the principles discussed before will make it easier to spot potential vulnerabilities early on.