Integrate an OPA engine with an ingress gateway
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, and the version of the ASM instance is 1.15.3.25 or later. For more information, see Add a cluster to an ASM instance and Upgrade an ASM instance.
-
The httpbin application is deployed and accessible. For more information, see Deploy the httpbin application.
-
Automatic sidecar proxy injection is enabled for the
defaultnamespace. For more information, see Configure a sidecar injection policy.
Step 1: Deploy an OPA engine
-
Create a file named
asm-opa.yamlwith the following content.This YAML file deploys an OPA Service, a Deployment, and a Secret.
Kind
Description
Deployment
-
Replace the region ID in the image path
registry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-staticwith the ID of the region where your cluster is located. -
Decision logging is enabled by default (
--set=decision_logs.console=true) for easier debugging.
Secret
The Secret defines an OPA policy with the following rules:
-
Allows requests to paths starting with
health. -
Allows
HEADrequests. -
Allows requests from the user
alice.NoteThe username is derived from the request's
Authorizationheader, which has the formatAuthorization: Basic <base64-encoded 'username:password'>.
-
-
Connect to your ACK cluster and 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_INGRESS_GATEWAY_IP}/ -I -X GETExpected output:
HTTP/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 indicates that the request is allowed because this path does not require authorization.
-
Run the following command to access the
/status/201path without valid credentials.curl ${ASM_INGRESS_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 output indicates that the request is denied because it lacks valid credentials.
-
Run the following command to access the
/status/201path with valid credentials.curl ${ASM_INGRESS_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 output indicates that the request is allowed because it includes valid credentials.
Step 4: Update the OPA policy
You can update the OPA policy at runtime by calling the OPA engine's HTTP API. This lets you change rules without redeploying the OPA service.
-
Run the following command to update the policy to allow access only for the user
bob.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 access httpbin as the user
bob.curl ${ASM_INGRESS_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 output indicates that access is granted for the user
bob. -
Run the following command to access httpbin as the user
alice.curl ${ASM_INGRESS_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 output indicates that access is denied for the user
alice.