When dynamic access control is required, you can integrate an Open Policy Agent (OPA) engine in an ingress gateway to customize authorization policies based on user identities or request content and control communication between services in real time. This effectively prevents unauthorized access, reduces the risks of data breach, and enhances the security of applications in a Service Mesh (ASM) instance. This topic describes how to use an OPA engine to authenticate and authorize requests that are received by an ingress gateway. In this example, requests flow through the ingress gateway to access the HTTPBin application.
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.
Step 1: Deploy an OPA engine
-
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: Use the external authorization feature of the ingress gateway to integrate the OPA engine with the ingress gateway
-
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 Ingress Gateway page, find the gateway that you want to integrate with OPA and click Gateway Security.
-
In the left-side navigation pane of the gateway, choose .
-
Configure a custom authorization service.
-
In the Custom Authorization Service Configuration wizard, configure OPA as the custom authorization service for the gateway, and then click Next.
Turn on the Enable Gateway Custom Authorization Service switch, select the Custom authorization service based on envoy.ext_authz (HTTP or gRPC) tab, set Protocol to GRPC, service address to
asm-opa.default.svc.cluster.local, service port to 9191, and timeout to 10 seconds. -
In the Matching Rules wizard, configure matching rules to specify which requests require OPA authorization, and then click Submit.
Set Matching Mode to Selected requests must be authorized, select Custom matching rules, turn on HTTP Path (Path), and enter
/status/*.A message appears, confirming that the Gateway Custom Authorization Service was created successfully and listing the created Istio native resources: an ASMExtensionProvider (resource name:
grpcextauth-asmsecuritypolicy-ingressgateway-extauthz) and an AuthorizationPolicy (resource name:ingressgateway-extauthz-ap-wg-gateway-istio-system-gateway-ingressgateway). You can click View YAML to view the resource configuration or click Edit to modify the authorization service.
-
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.