Alibaba Cloud Service Mesh (ASM) integrates with Open Policy Agent (OPA). You can use OPA to define access control policies to implement fine-grained access control on your applications.

Prerequisites

Background information

OPA is an incubation-level project that is managed by Cloud Native Computing Foundation (CNCF). As a policy engine, OPA can be used to implement fine-grained access control on your applications. You can deploy OPA as a standalone service along with microservices. To protect an application, make sure each request coming to a microservice is authorized before the request can be processed. To check the authorization, the microservice makes an API call to OPA to decide whether the request is authorized. OPA

Step 1: Enable OPA

  1. Log on to the ASM console.
  2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
  3. On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column of the ASM instance.
  4. In the Basic Information section, click Settings in the upper-right corner.
  5. In the Settings Update panel, select Enable OPA Plug-in.
  6. Click OK.
    In the Basic Information section, you can find that the status in the OPA Plug-in field changes to Enabled.

Step 2: Deploy OPA ConfigMaps

Before you deploy business pods, you must deploy the ConfigMaps of an OPA configuration file and an OPA policy.

  1. Use the kubectl client to connect to the ACK cluster that is added to the ASM instance. Run the following command to deploy an OPA configuration file:
    kubectl apply -n {The namespace where the ACK cluster resides} -f - <<EOF
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: opa-istio-config
    data:
      config.yaml: |
        plugins:
          envoy_ext_authz_grpc:
            addr: :9191
            path: istio/authz/allow
    EOF        
  2. Use the kubectl client to connect to the ACK cluster that is added to the ASM instance. Run the following command to deploy an OPA policy:
    kubectl apply -n {The namespace where the ACK cluster resides} -f - <<EOF
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: opa-policy
    data:
      policy.rego: |  ### The following code shows the definition of a sample policy. Define a policy based on your actual needs. 
        package istio.authz
        import input.attributes.request.http as http_request
        default allow = false
        allow {
            roles_for_user[r]
            required_roles[r]
        }
        roles_for_user[r] {
            r := user_roles[user_name][_]
        }
        required_roles[r] {
            perm := role_perms[r][_]
            perm.method = http_request.method
            perm.path = http_request.path
        }
        user_name = parsed {
            [_, encoded] := split(http_request.headers.authorization, " ")
            [parsed, _] := split(base64url.decode(encoded), ":")
        }
        user_roles = {
            "guest1": ["guest"],
            "admin1": ["admin"]
        }
        role_perms = {
            "guest": [
                {"method": "GET",  "path": "/productpage"},
            ],
            "admin": [
                {"method": "GET",  "path": "/productpage"},
                {"method": "GET",  "path": "/api/v1/products"},
            ],
        }
    EOF        
    • user_roles: assigns roles to users. In this example, assign the guest role to the guest1 user and the admin role to the admin1 user.
    • role_perms: specifies the permissions of each role. In this example, grant the guest role the permissions to access an application by using a URL that contains /productpage, and grant the admin role the permissions to access an application by using a URL that contains /productpage or /api/v1/products.

Step 3: Inject an OPA sidecar

Deploy the sample application Bookinfo in the ASM instance and check whether an OPA sidecar is injected into each pod of the Bookinfo application.

  1. Deploy the Bookinfo application in the ASM instance. For more information, see Deploy an application in an ASM instance.
  2. Define Istio virtual services and an ingress gateway service as required. For more information, see Define Istio resources.
  3. Check whether an OPA sidecar is injected into the pods of each application in the Bookinfo application.
    1. Log on to the ACK console.
    2. In the left-side navigation pane of the ACK console, click Clusters.
    3. On the Clusters page, find the cluster that you want to manage and click the name of the cluster or click Details in the Actions column. The details page of the cluster appears.
    4. In the left-side navigation pane of the details page, choose Workloads > Pods.
    5. At the top of the Pods page, select default from the Namespace drop-down list. Click the pod name of an application.
      On the Container tab, you can find that a sidecar proxy that is named istio-proxy and an OPA sidecar that is named opa-istio are injected into each container. Check the containers of each application in turn to ensure that the sidecar proxy and OPA sidecar are injected into each container. Inject an OPA sidecar

Result

The defined OPA policy implements the following access control on the Bookinfo application:
  • Run the following cURL commands. The results indicate that the guest role is assigned to the guest1 user. In addition, the guest1 user has the permissions to access the application by using a URL that contains /productpage, but not /api/v1/products.
    curl -X GET http://{{The IP address of the ingress gateway service}}/productpage --user guest1:password -I

    The following output is expected:

    HTTP/1.1 200 OK
    curl -X GET http://{{The IP address of the ingress gateway service}}/api/v1/products --user guest1:password -I

    The following output is expected:

    HTTP/1.1 403 Forbidden
  • Run the following cURL commands. The results indicate that the admin role is assigned to the admin1 user. In addition, the admin1 user has the permissions to access the application by using a URL that contains /productpage or /api/v1/products.
    curl -X GET http://{{The IP address of the ingress gateway service}}/productpage --user admin1:password -I

    The following output is expected:

    HTTP/1.1 200 OK
    curl -X GET http://{{The IP address of the ingress gateway service}}/api/v1/products --user admin1:password -I

    The following output is expected:

    HTTP/1.1 200 OK

    The preceding results indicate that the defined OPA policy implements access control as expected.