Application and data security is one of the main challenges many enterprises face. While security encompasses several aspects that it should concern itself with, Authorization who can access what – is at the core of the required solution. This document is about best practices for implementing authorizations in the service mesh.
A service mesh is a transparent infrastructure layer that sits between a network and the microservices, as such it’s the perfect place to ensure data encryption, authentication and authorization.
Istio is a service mesh implementation developed by Google, Lyft, and IBM. It’s open source, and the most popular service mesh implementation. Istio offers service components that can control the communication to and between services. More precisely, which pods running service A can reach pods running service B.
This by itself is not enough, authorization policies should also consider the identities that are operating within those services and what they are trying to do. So while Istio supports enforcement of access control policies, the question still remains how and where they are managed and deployed.
There are four aspects you should consider when deciding on an authorization solution:
How to best enforce access to services and data? Enforcement should be part of the technology of the application/service, and it should be based on the assets and resources they are using.
How decisions are made about who can access what? Ideally, decisions are dynamic, based on multiple factors so that they can be as accurate as possible with respect to the continuously changing circumstances of who, when and what.
Management of access policies is mostly about processes. Access decisions should be consistent across all services, up to date and expressed in a business-oriented language. In addition, who can manage the policies, version control, deployment should be addressed as part of the policies management.
That’s where accountability comes in, understanding and gaining visibility to who can access what, across all services, is essential part of the authorization management and control solution.
How can microservices architecture fundamentals be combined with the authorization basics?
The answer is – by separating management, decision, and enforcement, to well defined components in the architecture, where each component is optimized to the functions it should address.
In the microservices framework, access decisions are expected to be efficient and fast. The decision whether an action can or can’t be performed should be taken in a matter of microseconds or less. Therefore the authorization decision should be as close as possible to the service, within the same pod, to reduce any communication latency, which is common in other types of architectures.
Having the decision within proximity to the service, within the same pod, addresses an important security concern. The service doesn’t have to reach out to the network in order to know whether access is permitted or denied.
Development of microservices is typically lean and focused on the relevant functionality of the microservice. Supporting authorization enforcement in this type of architecture reduces the workload from the developer, since access decisions are made and enforced outside of the service.
In a distributed architecture, central control is crucial for enabling consistency in the access decisions across all components, and full visibility into who has access to what.
The Authorization system
point The interface which is used to define and manage the access control policies. Those policies are then stored in the Policy Store.
The decision point is responsible to check whether access is granted or blocked, based on the request information and additional attributes it fetches from the information points.
The information points are the source of attributes of both identities and assets.
The enforcement point typically sits between the service you want to protect and the client application/service.
PlainID runs as a sidecar next to each instance of Envoy.
When a request hits the Envoy proxy, it asks PlainID Sidecar directly for an authorization decision. PlainID decides, and Envoy enforces it. The benefit to this approach is that all decisions are made locally on the same server as the microservice and requires no network hops, yielding better availability and performance.
Authorization for the service mesh
The client sends its access/id token in the request header.
The request is intercepted by the envoy proxy, and passed to the PlainID sidecar.
PlainID sidecar is another container that is automatically injected to the pods, similarly to the Envoy proxy.
The PlainID sidecar makes a permit/deny decision, based on the defined policies.
A. The PlainID sidecar can base the decision on the request URL, request header and request body.
B. In addition, there is an option to inject entitlements/additional information to the request header, to provide specific access data to the service.
If the authorization decision is permit, the Envoy proxy passes the request to the service container. Otherwise, If the authorization decision is deny, the request never reaches the actual service container and a 403 response is returned immediately.
Policies for the service mesh
The Policy Manager enables definition of policies that are based on: