Access

Control access for workloads in your service mesh.

For example, you might want to enforce a “zero trust” network model for all of your services. In your workspace settings, you can enable service isolation so that only services within the same workspace (or imported workspaces) can communicate with each other. For even more control, you can set up access policies. With access policies, you can deny all access to a specific destination except for the clients that you explicitly allow.

For more information, see the following resources.

Before you begin

  1. Complete the demo setup to install Gloo Mesh, Istio, and Bookinfo in your cluster.

  2. Create the Gloo Mesh resources for this policy in the management and workload clusters.

    The following files are examples only for testing purposes. Your actual setup might vary. You can use the files as a reference for creating your own tests.

    1. Download the following Gloo Mesh resources:
    2. Apply the files to your management cluster.
      kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-1.yaml --context ${MGMT_CONTEXT}
      kubectl apply -f kubernetes-cluster_gloo-mesh_cluster-2.yaml --context ${MGMT_CONTEXT}
      kubectl apply -f workspace_gloo-mesh_anything.yaml --context ${MGMT_CONTEXT}
      
    1. Download the following Gloo Mesh resources:
    2. Apply the files to your workload cluster.
      kubectl apply -f workspace-settings_bookinfo_anything.yaml --context ${REMOTE_CONTEXT1}
      
  3. Send a request to verify that the Bookinfo apps can talk to each other before applying access policies.

    Create a temporary curl pod in the bookinfo namespace, so that you can test the app setup. You can also use this method in Kubernetes 1.23 or later, but an ephemeral container might be simpler, as shown in the other tab.

    1. Create the curl pod.

      kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \
        --image=curlimages/curl:7.73.0 --rm  -- sh
      
    2. Send a request to the ratings app.

      curl http://ratings:9080/ratings/1 -w "${http_code}"
      

      Example output:

      {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}200
      
    3. Exit the temporary pod. The pod deletes itself.

      exit
      

    Use the kubernetes debug command to create an ephemeral curl container in the deployment. This way, the curl container inherits any permissions from the app that you want to test. If you don't run Kubernetes 1.23 or later, you can deploy a separate curl pod or manually add the curl container as shown in the other tab.

    kubectl --context ${REMOTE_CONTEXT1} -n bookinfo debug -i pods/$(kubectl get pod --context ${REMOTE_CONTEXT1} -l app=reviews -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -v http://ratings:9080/ratings/1
    

    Example output:

    HTTP/1.1 200 OK
    ...
    {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
    

    If the output has an error about EphemeralContainers, see Ephemeral containers don’t work when testing Bookinfo.

Configure access policies

You can apply an access policy at the destination level. For more information, see Applying policies.

The following example is for a simple access policy that allows only the product page app to access the ratings app.

apiVersion: security.policy.gloo.solo.io/v2
kind: AccessPolicy
metadata:
  name: ratings-access
  namespace: bookinfo
spec:
  applyToDestinations:
  - port:
      number: 9080
    selector:
      labels:
        app: ratings
  config:
    authn:
      tlsMode: STRICT
    authz:
      allowedClients:
      - serviceAccountSelector:
          labels:
            app: productpage
      allowedPaths:
      - /ratings*

Review the following table to understand this configuration. For more information, see the API docs.

Setting Description
applyToDestinations Configure which destinations to apply the policy to, by using labels. Destinations can be a Kubernetes service, VirtualService, or ExternalService. If you do not specify any destinations or routes, the rate limit policy applies to all destinations in the workspace by default. If you do not specify any destinations but you do specify a route, the rate limit applies to the route but to no destinations.
authn For authentication, set the type of TLS policy to enforce when connecting to the destination. If you set up service isolation for the workspace, this setting is always set to STRICT. Other modes include PERMISSIVE to set up a TLS connection to the upstream endpoint, or DISABLE to not set up a connection to the upstream endpoint.
authz Set up which clients are permitted to access the destination.
allowedClients Configure which clients are permitted to access the destination. In this example, the allowed clients are restricted to the product page app, as selected by the label of its Kubernetes service account.
allowedPaths Optionally, you can restrict which path to allow. For HTTP paths, exact match, prefix match, and suffix match are supported. In this example, requests are restricted to the suffix match path /ratings*.
allowedMethods Optionally, you can restrict the HTTP methods to allow, such as GET or POST. If the request is made via gRPC, this value is ignored because the method is always POST. In this example, no method is set, so all methods are allowed by default.

Verify access policies

  1. Apply an Istio AuthorizationPolicy to deny all requests in the Bookinfo namespace.

    cat << EOF | kubectl --context ${REMOTE_CONTEXT1} apply -f -
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: default-deny
     namespace: bookinfo
    spec:
      {}
    EOF
    
  2. Verify that requests are now blocked. You get back a 403 Forbidden response.

    Create a temporary curl pod in the bookinfo namespace, so that you can test the app setup. You can also use this method in Kubernetes 1.23 or later, but an ephemeral container might be simpler, as shown in the other tab.

    1. Create the curl pod.

      kubectl run -it -n bookinfo --context $REMOTE_CONTEXT1 curl \
        --image=curlimages/curl:7.73.0 --rm  -- sh
      
    2. Send a request to the ratings app.

      curl http://ratings:9080/ratings/1 -w "${http_code}"
      

      Example output:

      {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}200
      
    3. Exit the temporary pod. The pod deletes itself.

      exit
      

    Use the kubernetes debug command to create an ephemeral curl container in the deployment. This way, the curl container inherits any permissions from the app that you want to test. If you don't run Kubernetes 1.23 or later, you can deploy a separate curl pod or manually add the curl container as shown in the other tab.

    kubectl --context ${REMOTE_CONTEXT1} -n bookinfo debug -i pods/$(kubectl get pod --context ${REMOTE_CONTEXT1} -l app=productpage -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -v http://ratings:9080/ratings/1
    

    If the output has an error about EphemeralContainers, see Ephemeral containers don’t work when testing Bookinfo.

  3. Apply the example access policy to allow the product page app to access to the ratings app.

    kubectl apply --context ${REMOTE_CONTEXT1} -f - << EOF
    apiVersion: security.policy.gloo.solo.io/v2
    kind: AccessPolicy
    metadata:
      name: ratings-access
      namespace: bookinfo
    spec:
      applyToDestinations:
      - port:
          number: 9080
        selector:
          labels:
            app: ratings
      config:
        authn:
          tlsMode: STRICT
        authz:
          allowedClients:
          - serviceAccountSelector:
              labels:
                app: productpage
          allowedPaths:
          - /ratings*
    EOF
    
  4. Try the request again from the product page app. This time, the request succeeds with a 200 response because you allowed access.

    Add a curl container to your app deployment so that you can test the app setup. You can also use this method in Kubernetes 1.23 or later, but an ephemeral container might be simpler, as shown in the other tab.

    1. Create the curl container.
      kubectl apply --context ${REMOTE_CONTEXT1} -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/productpage-with-curl.yaml
      
    2. Verify that requests now succeed. You get back a 200 response.
      kubectl exec $(kubectl get pod -l app=productpage -A --context ${REMOTE_CONTEXT1}  -o jsonpath='{.items[0].metadata.name}') -n bookinfo -c curl --context ${REMOTE_CONTEXT1} -- curl -v http://ratings:9080/ratings/1
      

    Use the kubernetes debug command to create an ephemeral curl container in the deployment. This way, the curl container inherits any permissions from the app that you want to test. If you don't run Kubernetes 1.23 or later, you can deploy a separate curl pod or manually add the curl container as shown in the other tab.

    kubectl --context ${REMOTE_CONTEXT1} -n bookinfo debug -i pods/$(kubectl get pod --context ${REMOTE_CONTEXT1} -l app=productpage -A -o jsonpath='{.items[0].metadata.name}') --image=curlimages/curl -- curl -v http://ratings:9080/ratings/1
    

    Example output:

    HTTP/1.1 200 OK
    ...
    {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}