Service Mesh (ASM) simplifies security configuration by providing the ASM security policy feature, which abstracts Istio's native security resources. ASM integrates with Open Policy Agent (OPA), which allows you to define fine-grained access control policies for your applications. This guide explains how to connect your services to an external OPA execution engine by using an ASM security policy.
Prerequisites
-
A managed Kubernetes cluster has been added to an ASM instance, version 1.15.3.25 or later. For instructions, see Add a cluster to an ASM instance and Upgrade an ASM instance.
-
The httpbin application is deployed and accessible. For instructions, see Deploy the httpbin application.
-
Automatic sidecar injection is enabled for the
defaultnamespace. For instructions, see Configure a sidecar injection policy.
How it works
By default, ASM deploys OPA in sidecar mode. When OPA is enabled, ASM injects an OPA container into the application Pod when the Pod restarts. All requests to the application container are then validated by the OPA sidecar. Because communication happens within the Pod, sidecar mode offers low latency and is suitable for latency-sensitive workloads.
However, sidecar mode has drawbacks, including higher resource consumption, required Pod restarts, and limited flexibility. A centralized OPA deployment complements the sidecar mode by offering lower resource usage, connecting applications without restarts, and allowing selective application of OPA policies to specific requests. This section describes how to deploy a centralized OPA authorization service and connect it to your application.

Step 1: Deploy OPA
-
Create a file named
asm-opa.yamlwith the following content.This YAML manifest deploys an OPA Service, Deployment, and Secret.
Kind
Description
Deployment
-
In the image path
registry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-static, replacecn-hangzhouwith your cluster's region ID. -
This OPA execution engine enables decision logging by default (
--set=decision_logs.console=true) to simplify debugging.
Secret
The Secret defines an OPA policy with the following rules:
-
Allow requests if the path is
health. -
Allow requests if the method is
HEAD. -
Allow requests if the username is
alice.NoteThe username is extracted from the
Authorizationheader, which must be in the formatAuthorization: Basic ${base64_encoded_username:password}.
-
-
Run the following command to deploy OPA.
kubectl apply -f asm-opa.yaml
Step 2: Connect to OPA via ASM security policy
-
Log on to the ASM console. In the left-side navigation pane, choose .
-
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
-
On the ASMSecurityPolicy page, click Create. In the Create ASMSecurityPolicy dialog box, click the Custom Authorization Service card, and then click OK.
-
Configure the custom authorization service.
-
On the Create Custom Authorization Service page, configure the OPA authorization service that you deployed in Step 1, and then click Next.
Set the following parameters: ASM Security Policy Name to
opa, Protocol to GRPC, Service Address toasm-opa.default.svc.cluster.local, Service Port to9191, and Timeout to10seconds. -
In the Workload and Match Rules wizard, click Add Workload Group. In the New Workload Group dialog box, enter a Workload Group Name and click Add Workload.
-
In the Add Workload dialog box, select Workload Scope, set Namespaces to default, and set Workload Type to Service. In the Select workloads area, select httpbin, click the
icon, and then click OK. -
In the New Workload Group dialog box, find the Match Rule List section. Set Match Mode to The selected request must be authenticated and Matching Rules to Custom Matching Rules. Turn on the Path switch, set the value to
/status/*, and then click OK.This workload group is named
httpbin, and its workload list contains the httpbin Service with theapp:httpbinlabel. -
In the Workload and Match Rules wizard, click Submit.
After the policy is created, a success message is displayed, along with the generated Istio resources: an ASMExtensionProvider (resource name
grpcextauth-asmsecuritypolicy-opa) and an AuthorizationPolicy (resource nameopa-ap-wg-httpbin-default-service-httpbin). You can click View YAML to check the resource details, and then click Done.
-
Step 3: Test httpbin access
-
Run the following command to access the
/path.curl ${ASM_GATEWAY_IP}/ -I -X GETHTTP/1.1 200 OK server: istio-envoy date: Tue, 25 Jul 2023 08:30:58 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 2The output shows that the request is allowed because this path does not require authentication.
-
Run the following command to access the
/status/201path without valid credentials.curl ${ASM_GATEWAY_IP}/status/201 -I -X GETExpected output:
HTTP/1.1 403 Forbidden date: Tue, 25 Jul 2023 08:31:18 GMT server: istio-envoy content-length: 0 x-envoy-upstream-service-time: 1The
403 Forbiddenresponse indicates the request was denied due to missing credentials. -
Run the following command to access the
/status/201path with valid credentials for the useralice.curl ${ASM_GATEWAY_IP}/status/201 -I -X GET --user alice:testpasswordExpected output:
HTTP/1.1 201 Created server: istio-envoy date: Tue, 25 Jul 2023 08:31:38 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 3The
201 Createdresponse confirms the request was allowed, as useraliceis authorized by the OPA policy.
Step 4: Update the OPA policy
You can update the OPA policy at runtime by calling the OPA engine's HTTP API.
-
Run the following command to update the policy. The new policy allows access only for the user
boband denies access foralice.kubectl exec deployment/httpbin -c istio-proxy -- curl asm-opa:8181/v1/policies/policy/policy.rego -XPUT --data-binary 'package asm.authz import future.keywords import input.attributes.request.http as http_request import input.parsed_path default allow := false allow if { parsed_path[0] == "health" } allow if { http_request.method == "HEAD" } allow if { user_name == "bob" } user_name := parsed if { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") }' -
Run the following command to test access as the user
bob.curl ${ASM_GATEWAY_IP}/status/201 -I -X GET --user bob:testpasswordExpected output:
HTTP/1.1 201 Created server: istio-envoy date: Tue, 25 Jul 2023 08:32:16 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 3The
201 Createdresponse shows that the userbobcan successfully access the path. -
Run the following command to test access as the user
alice.curl ${ASM_GATEWAY_IP}/status/201 -I -X GET --user alice:testpasswordExpected output:
HTTP/1.1 403 Forbidden date: Tue, 25 Jul 2023 08:32:49 GMT server: istio-envoy content-length: 0 x-envoy-upstream-service-time: 1The
403 Forbiddenresponse confirms that useraliceis now denied access, validating the policy update.