In the first part, we established the purpose of Service Mesh and explained the Authentication part of the process. In this article, we’ll focus on Authorization.
Once the identity of the requester is known, the next step is to check whether the requester is authorized to access the requested data.
User to service
Users must have access to Application Service to submit applications.
When a request reaches the Application Service, the service must first check the "internal token" to ensure that a valid user sent the request. Then it checks whether the requesting user has access to the service or a specific endpoint of the service. In this case, this is done by checking the description of the user access in the "internal token." As this process has nothing to do with the business logic for the Application Service, it’s better to delegate it to a sidecar.
Service to service
A request from a user can be handled entirely by one microservice in the system, or by multiple microservices together. For microservices, the requester can be a user or other microservice. In our system, there will be interactions between microservices, but they are limited. When Application Service receives a request for creating an application, it needs to access the Domain Specific User Information Service for user data to create the application. For Domain Specific User Information Service, requests from Application Service should be processed, otherwise they should be rejected.
The accessibility configuration between services is provided by another service. When performing this check, we must first retrieve the accessibility configuration between services so that we can handle the request according to the configuration. Since this process also has nothing to do with the business logic for the Domain Specific User Information Service, it’s better to delegate it to a sidecar as well.
User to data from services
Access data from Application Service as a team member in an application
When a team member submits an application on behalf of the team, the system needs to allow other team members to view the application. Since the application contains team members’ mobile numbers, the system can know who can access the application according to authenticated users’ mobile numbers. In this scenario, the configuration of whether the application can be accessed is from the application itself. In other words: only Application Service itself knows who can access what applications.
Authorization check delegated to a sidecar
Since the authorization information can only be from the Application Service, the microservice must provide an API for the sidecar to perform the authorization check, which results in the microservice being essentially involved in the authorization check and the authorization check not being fully delegated to the sidecar.
Authorization check within the service
For many microservices that use relational databases, authorization checks may be just the filtering of the INNER JOIN in SQL without doing anything more. If we need to filter the data received from the database, communicating within a service is easier than communicating between services.
As we mentioned, only Application Service itself knows who can access what applications. Therefore, in this scenario, incorporating the authorization check within the service can make the logic more coherent and reduce unnecessary work if the microservices do it themselves.
Access data from Application Service as an application reviewer
Assume that applicants come from 10 cities. There are 5 application reviewers, with each reviewer taking responsibility for applications from 2 cities. No information is shared among them.
City 1 and city 2 are under the management of reviewer 1. When reviewer 1 wants to view applications under their management, they need to call an endpoint similar to the following.
The reviewer may only want to view applications from city 1 submitted in recent days.
The reviewer isn’t authorized to view applications from cities other than 1 and 2. So the request below must be rejected.
Delegate the authorization check to a sidecar
Since the accessibility configuration is provided by other services, the microservice doesn’t need or have the ability to provide support for the sidecar, or to know that the sidecar exists. But the sidecar, which is used for the authorization check, needs to learn the microservice's business.
Although the sidecar must learn the business of the microservice and become the service’s exclusive sidecar, from the perspective of the microservice, the logic of data authorization checking is completely delegated, and the microservice can be cleaner. When developers build the microservice, they can also focus more on implementing the business.
Before microservices process requests, identifying the requesting user, meaning verifying the authentication, should be delegated to the infrastructure layer.
When the authorization configuration is provided by other services, if it's "service to service" or "user to service," it should be delegated to the infrastructure layer. If it's "user to data from service," like the scenario where application reviewers review applications, delegating the authorization check to the infrastructure layer should be considered a priority.
When the authorization configuration can only be provided by the microservice itself, if it's "user to data from services," maintaining the configuration is the service’s job. Like the scenario where the relationship between team members and applications. Having the microservice to perform the authorization check should be considered a priority.
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.