The migration to microservice architecture from monolithic applications is happening en masse as enterprises realize its scalability and efficiency benefits. According to an IBM report1, 56% of nonuser organizations plan on adopting the microservice architecture by 2023.
Breaking an application into small, loosely coupled services lets independent teams quickly design and deploy these components. Nonetheless, this strategy is only viable with secure data sharing and communication between microservice instances.
This blog discusses various service-to-service communication methods and the means of securing these channels. Also check out our free online course for more on the subject.
How do microservices communicate with each other?
Since microservice applications are distributed systems with independently designed components, devising interservice communication can take time and effort. Each service has its own instance and process and communicates on the network level using protocols such as HTTP. According to a survey by The Software House, 77% of respondents reported using HTTP protocol for interservice communication in their applications.
There are 2 styles of communication between services:
- Synchronous communication
This messaging pattern involves waiting for a response from the receiver. HTTP or gRPC protocols are used to return sync responses. The caller becomes locked in the interaction and can’t move on to another task until a response is received. This pattern is suitable for login or purchase actions but there is a risk of cascading failures and strong coupling of participating services.
- Asynchronous communication
In this pattern, the request and response are independent of each other. The caller doesn’t have to block a thread while waiting for an answer and is not locked in the interaction. Usually, message brokers facilitate asynchronous communication using the Advanced Message Queuing Protocol (AMQP).
Asynchronous communication reduces coupling between participating services and increases responsiveness. When using an event-driven asynchronous communication pattern, there can be multiple receivers. Event-driven architecture also reduces coupling between services, a service doesn’t have to know who the other message producers and consumers are.
The challenges of service-to-service communication
Developers face the following security challenges when designing microservices communication:
- In a microservice architecture, there are many more API endpoints to secure compared to a monolithic application. In addition, the preference for stateless services make traditional session-based security approach more difficult.
- A request or transaction may pass through several services, making it difficult to monitor the system. Service logs and metrics need to be aggregated in a distributed architecture to obtain a holistic view of the entire application.
- Managing multiple versions of a service running concurrently introduces complexities, such as directing requests to the appropriate service version. Uncoordinated version roll-outs or ineffective request routing can lead to data exchange inconsistencies, potentially exposing sensitive information or creating points of vulnerability for attacks.
- It is necessary to authenticate and authorize all service requests for security purposes. Developers must also encrypt inter-service communication traffic using transport layer security (TLS).
Read our whitepaper to learn more about microservice authorization for zero trust security.
4 ways to secure communication between microservices
Communication between microservices can be secured using these four techniques:
- Mutual TLS or mTLS
Mutual TLS is a version of TLS where the client will send a signed certificate to the server (and vice versa). The server will expect the client’s certificate to be signed using a certain Certificate Authority (CA) specific to the system, thus proving that the client is allowed access. The certificate can also contain metadata about the client which can further inform authorization decisions.
- OpenID Connect (OIDC)
OIDC is a protocol built on top of OAuth2 that allows a central identity server to authenticate users on behalf of other services that user wished to access. This is widely used both privately and in companies to create a Single Sign On (SSO) environment, where the user only has to authenticate once instead of with each service individually. Once authenticated the user receives a JSON Web Token (JWT) from the identity provider and sends this in every request. Services receiving requests from users can validate the JWT and extract information about the user from it.
Authentication only confirms the identity of the service sending the request. Microservice authorization is the process of determining whether the service or the user on whose behalf the service is acting is allowed to access the requested data or perform the requested action. Authorization logic can be hard-coded into the business logic but this coupling makes implementing policy changes difficult.
A better alternative is to decouple the policy code and entrust all authorization decisions to a policy decision point, such as the Open Policy Agent (OPA). OPA can be deployed alongside each service as a sidecar to handle authorization decisions based on fine-grained policies and rules. Access is granted only when all the policy conditions are met and the decision is saved in an audit log, allowing security teams to check for suspicious requests.
- Service meshes
A service mesh is a dedicated infrastructure layer that uses sidecar proxies to control all service-to-service communication within a microservice application. Service meshes also use mTLS to secure communication channels between services and decouple monitoring and security from the application.
The service mesh also solves several critical challenges of communication between microservices, such as load balancing, circuit breaking and distributed tracing. These capabilities explain why the service mesh is an important component in many cloud-native systems. In fact, the service mesh market is expected to exhibit a compound annual growth rate (CAGR) of 41.3% to reach a value of $1.44 billion by 2027, according to Business Research Insights.
Microservice authorization with OPA and Styra DAS
A graduate project of the Cloud Native Computing Foundation (CNCF), OPA is the standard for providing authorization checks throughout the cloud-native ecosystem.
Using policy as code to decouple authorization decision-making from the software, OPA can be deployed anywhere and as many times as needed within the microservice application. It can handle access control for all components, including individual services, service meshes and API gateways.
You can control and monitor all OPA deployments within the system through the Styra Declarative Authorization Service (DAS), a management plane for OPA. Styra DAS lets you apply any combination of access control models and static policies — depending on your microservice application’s requirements.
With Styra DAS and OPA, you get a ready-made authorization solution that lets you bring the application to market much faster while keeping you compliant and secure.
Schedule a demo to see Styra DAS in action.
When to use OIDC vs mTLS?
OIDC is better suited for authenticating end-users as it gives them the convenience of SSO. mTLS on the other hand is difficult to manage for end-users but is useful for service to service communication.
When do you move authorization logic out of service code?
When authorization logic starts to become more complex it is a good idea to start thinking about moving it out of service logic for better management and auditing. Another factor is the number of services and whether they are written using different languages and technology stacks. The more complexity there is the more benefits to move authorization to a dedicated component like OPA.