Authentication and Authorization are massive components of the safety puzzle that should be solved by cloud architects and DevOps engineers. On this weblog, we’ll particularly have a look at tips on how to obtain authorization/entry management; i.e., what actions the authenticated entity can carry out within the Istio service mesh. It helps to safe the infrastructure by stopping actions with malicious intent.
Authorization in a service mesh might be outlined utilizing OPA insurance policies. OPA is a mechanism that helps DevOps of us outline and implement authorization insurance policies for Kubernetes workloads. On this piece, we’ll see:
- What OPA is
- Why you must combine OPA with Istio service mesh
- How Istio and OPA authorize requests
- The precise steps you’ll be able to observe to combine OPA with Istio
What Is OPA?
OPA (brief for “Open Coverage Agent”) is an open-source, general-purpose policy enforcement engine that lets DevOps define policy as code using a high-level declarative language called Rego. OPA helps centrally outline and implement insurance policies throughout the stack whereas relieving builders from writing authorization insurance policies into the applying code. Right here is how OPA works (discuss with Determine 1):
- The appliance/service receives a request.
- The service sends a JSON authorization request to OPA.
- OPA checks the request in opposition to the outlined authorization insurance policies.
- OPA takes the choice and returns the authorization response (ALLOW/DENY) to the service in JSON format.
Determine 1: Authorization request movement with OPA
Observe that it doesn’t should be an utility written by a developer that’s sending the authorization request: it may be Argo CD, Kubernetes Gateway API useful resource, Terraform, Prometheus, or the rest since OPA is general-purpose. (I’ve talked about and drawn an utility in a Kubernetes cluster right here for the sake of comfort and higher understanding.)
Why Combine OPA With Istio?
Istio has a strong authorization mechanism. Nevertheless, having a devoted coverage enforcement engine like OPA alongside Istio service mesh has its personal advantages:
- Centralized administration system to outline and implement insurance policies: OPA makes it simpler for DevOps to centrally handle authorization insurance policies for the complete stack. This contains meshed workloads, non-meshed stack, and in addition authorization checks (a coverage that forestalls deployment on Fridays, for instance).
- Extra flexibility and granularity in defining insurance policies: For those who have a look at the desk under (Determine 2), it’s clear that Istio authorization can do loads and match a request based mostly on quite a lot of fields from totally different information sources. Nevertheless, Istio AuthorizationPolicy CRD might be restricted in configuring the HTTP request physique or any contextual information within the fields, for which OPA can be utilized. In contrast to Istio, OPA can use any information for coverage analysis.
- Simplified AuthZ configuration: It may be tedious for DevOps to configure advanced authorization guidelines in Istio. OPA is configured utilizing Rego, which is nearer to a programming language. It’s comparatively simpler to set primary to advanced coverage guidelines utilizing Rego.
Determine 2: Tabular comparability between Istio and OPA authorization (supply)
How Istio and OPA Authorize Requests
DevOps can deploy OPA as a separate service altogether or as a sidecar container alongside the Envoy proxy and the applying container in a pod. The sidecar container method is best to scale back latency.
OPA sidecar containers should be injected into the applying pod identical to Istio’s Envoy proxy sidecar containers. We are able to arrange the injected OPA containers to mount ConfigMaps that include the authorization guidelines; each OPA sidecar container within the namespace will then mount the identical configuration and AuthZ guidelines outlined within the ConfigMap.
As soon as the OPA sidecar is injected, the Envoy proxy will ship authorization requests to OPA to make authorization choices when the service receives a request:
Determine 3: Istio-OPA authorization workflow
Suppose DevOps of us don’t need each injected OPA container in the identical namespace to observe the identical configurations and need to implement totally different guidelines. In that case, they should do any of the next:
- Take away arduous coding which lets the present injection coverage use a specific ConfigMap
- Configure mutating webhook and disable sidecar injection on the pod-level
- Serve up coverage bundles from a distant HTTP server
- Deploy the applying and the sidecars in a unique namespace with totally different ConfigMap
Steps To Combine Opa With Istio: Demo
The thought right here is to make OPA the exterior authorizer as an alternative of Envoy proxy sidecars — to make entry management choices.
I’ll use the traditional Bookinfo utility from Istio documentation for the demo. I’ll configure OPA with Istio for entry management and verify whether or not it’s enforced by firing requests to bookinfo/productpage:
Determine 4: Istio-OPA integration tutorial diagram
Observe that /productpage is the UI, which makes inside calls to different providers, similar to critiques and rankings providers (diagram). I’ll inject OPA into each pod within the bookinfo
namespace; all OPA containers mount the identical ConfigMap and have the identical authorization insurance policies due to that. The default conduct of the Bookinfo
utility doesn’t ahead any HTTP authentication so the inner calls will fail authentication and thus authorization.
We’ll observe the given steps so as:
- Configure OPA sidecar injection
- Allow communication between Istio proxy and OPA
- Deploy OPA configuration
- Apply Istio configuration
- Deploy the applying and check the Istio-OPA authorization setup
The prerequisite for the demo is to have Istio v1.19+ put in in your cluster. I’m utilizing Istio v1.21.0 right here.
OPA offers a quickstart.yaml for straightforward set up. I’ve break up the yaml into three for simpler understanding: IMESH GitHub repo.
Step 1: Configure OPA Sidecar Injection
Apply the opa_controller.yaml:
kubectl apply -f opa_controller.yaml
The opa_controller.yaml
deploys the whole lot — TLS certificates, ConfigMap containing injection coverage, admission controller deployment, and mutating webhook configuration — into the opa-istio
namespace (discuss with Determine 5):
- The mutating webhook controller (
opa-istio-admission-controller
) will then hear for a specific label (opa-istio-injection
) with the worth set to enabled. - The webhook controller calls the
admission-controller
, which has the injection coverage. - The injection coverage tells the
admission-controller
tips on how to inject the OPA sidecar container into the pod.
Determine 5: OPA sidecar injection configuration
Now, earlier than deploying the Bookinfo utility, we’ll create bookinfo
namespace and observe the remainder of the steps:
Create the bookinf
o namespace by making use of bookinfo-ns.yaml:
kubectl apply -f bookinfo-ns.yaml
You possibly can see the namespace has the label opa-istio-injection: enabled
, to auto-inject OPA sidecars.
Step 2: Allow Communication Between Istio Proxy and OPA
Edit Istio ConfigMap within the istio-system
namespace and add extensionProviders
(opa-ext-authz-grpc
), in order that it allows exterior authorization within the mesh:
- Copy
extensionProviders
from the remark in opa_controller.yaml. - Edit Istio ConfigMap and add
extensionProviders
within the mesh subject. - Make sure the indentation is right.
- Save the config.
The step makes it potential for istio-proxy
to speak to opa-istio
container within the pod for authorization requests.
For those who have a look at the extensionProviders
, it’s an ExtAuthzGrpc
filter kind in Envoy with a specified service entry and port:
...
extensionProviders:
- title: opa-ext-authz-grpc
envoyExtAuthzGrpc:
service: opa-ext-authz-grpc.native
port: "9191"
...
The extensionProviders
’ title, service tackle, and port needs to be the identical within the opa_authz.yaml and opa_config.yaml.
Step 3: Deploy OPA Configuration
The opa_config.yaml defines open policy-related configurations. It has opa-istio-config
and opa-policy ConfigMaps
— which outline the gRPC service implementation (envoy_ext_authz_grpc
) and the precise authorization insurance policies, respectively.
The authorization insurance policies might be divided into two components: the primary half defines the situations underneath which the authorization is allowed or denied; the second half defines the person roles and the permissions for every position.
The authorization insurance policies may take a while to get used to, as Rego doesn’t use many key phrases right here. Allow a more recent model of Rego to get key phrases (permit if situation key phrase, for instance).
Apply OPA configuration within the bookinfo
namespace, because it goes together with the applying:
kubectl apply -f opa_config.yaml -n bookinfo
Step 4: Apply Istio Configuration
The opa_authz.yaml file accommodates Istio configurations. It has an AuthorizationPolicy
and a ServiceEntry
. Observe that the Authorization Coverage supplier is opa-ext-authz-grpc
, which is the extensionProvider
we configured within the ConfigMap in step 2.
Equally, the hostname outlined within the ServiceEntry
is similar because the service tackle given within the extensionProvider
(opa-ext-authz-grpc.native
). The gRPC service will run on port 9191 at localhost 127.0.0.1, which the ServiceEntry
makes opa-istio
sidecars accessible inside the pod by the istio-proxy
container.
Deploy the configuration:
kubectl apply -f opa_authz.yaml -n bookinfo
Step 5: Deploy the Software and Check the Istio-OPA Authorization Setup
Deploy the Bookinfo utility and the gateway:
kubectl apply -f /your_Istio_directory/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
kubectl apply -f /your_Istio_directory/samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo
Test the pods within the bookinfo
namespace:
kubectl get pods -n bookinfo
You possibly can see that every pod has 3 containers operating in them: the applying, Envoy proxy (istio-proxy
), and OPA (opa-istio
) containers.
Get the IP of the Istio gateway to entry the service:
kubectl get svc -n istio-system
Now the whole lot is ready, and we’re prepared to check the authorization insurance policies. The insurance policies we outlined in opa_config.yaml are the next:
...
user_roles = {
"alice": ["guest"],
"bob": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
...
Alice is a visitor person who can solely entry the /productpage
; Bob is an admin who can entry the paths /productpage
and /api/v1/merchandise
. Allow us to confirm the insurance policies.
Attempting to entry /api/v1/merchandise
from Alice:
curl -vvv your_istio_gateway_ip/api/v1/merchandise -u alice:password
You possibly can see that 403 Forbidden
response since Alice doesn’t have entry to the trail. Allow us to strive the identical path as Bob:
curl -vvv your_istio_gateway_ip/api/v1/merchandise -u bob:password
It exhibits the HTTP standing 200 OK
and the web page content material in direction of the top of the response.
Instance Situation for Entry Management With OPA
You need to use Istio’s AuthorizationPolicy CRD to implement the coverage proven within the demo above. You do not want OPA. Nevertheless, there are cases the place Istio authorization might be restricted, as talked about within the desk initially. Let me give a easy instance.
Suppose there’s a BookReviews utility which is a GraphQL service, the place reviewers submit critiques, editors edit and publish these critiques, and customers learn the revealed critiques.
When a reviewer provides a e-book overview to the service, the request would come with the reviewer’s JWT, containing the teams and roles (reviewer or editor) the reviewer belongs to. The request physique would additionally include a GraphQL mutation question with the newly created overview information.
Allow us to say you need to guarantee the next situations:
- Solely reviewers can submit critiques.
- An editor can solely edit a overview whether it is written by a reviewer belonging to the identical group managed by them.
- Solely editors can mark a overview as “ready to publish”.
Right here is the diagram that features the above insurance policies:
Istio’s AuthorizationPolicy will battle to implement the above situations. The reason being that Istio can not use the GraphQL request physique for authorization checks, which is a JSON object alongside the JWT wanted for coverage analysis.
OPA doesn’t have such limitations. It could possibly load any information for coverage checks, and DevOps can write these guidelines in a extra ergonomic manner utilizing Rego.
Video: Demo in Motion
For those who choose to observe the demo in motion, please verify the video under:S
Enterprise Help for Integrating Istio
Most enterprises use OPA to outline and implement authorization insurance policies for his or her whole stack. Having a central mechanism for entry management improves the general safety and agility of IT groups. In any other case, builders will waste time creating authorization insurance policies into their utility code written in a specific language, which impedes scalability and quicker enterprise logic rollout.