Enforce authorization policies

After you have added your application to the ambient mesh, you can secure application access using Layer 4 authorization policies.

This feature lets you control access to and from a service based on the client workload identities that are automatically issued to all workloads in the mesh.

Enforce Layer 4 authorization policy

Let’s create an authorization policy that restricts which services can communicate with the productpage service. The policy is applied to pods with the app: productpage label, and it allows calls only from the the service account cluster.local/ns/default/sa/bookinfo-gateway-istio. (This is the service account that is used by the Bookinfo gateway you deployed in the previous step.)

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: security.istio.io/v1
  3. kind: AuthorizationPolicy
  4. metadata:
  5. name: productpage-viewer
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: productpage
  11. action: ALLOW
  12. rules:
  13. - from:
  14. - source:
  15. principals:
  16. - cluster.local/ns/default/sa/bookinfo-gateway-istio
  17. EOF

If you open the Bookinfo application in your browser (http://localhost:8080/productpage), you will see the product page, just as before. However, if you try to access the productpage service from a different service account, you should see an error.

Let’s try accessing Bookinfo application from a curl pod:

  1. $ kubectl apply -f samples/curl/curl.yaml

Since the curl pod is using a different service account, it will not have access the productpage service:

  1. $ kubectl exec deploy/curl -- curl -s "http://productpage:9080/productpage"
  2. command terminated with exit code 56

Enforce Layer 7 authorization policy

To enforce Layer 7 policies, you first need a waypoint proxy for the namespace. This proxy will handle all Layer 7 traffic entering the namespace.

  1. $ istioctl waypoint apply --enroll-namespace --wait
  2. waypoint default/waypoint applied
  3. namespace default labeled with "istio.io/use-waypoint: waypoint"

You can view the waypoint proxy and make sure it has the Programmed=True status:

  1. $ kubectl get gtw waypoint
  2. NAME CLASS ADDRESS PROGRAMMED AGE
  3. waypoint istio-waypoint 10.96.58.95 True 42s

Adding a L7 authorization policy will explicitly allow the curl service to send GET requests to the productpage service, but perform no other operations:

  1. $ kubectl apply -f - <<EOF
  2. apiVersion: security.istio.io/v1
  3. kind: AuthorizationPolicy
  4. metadata:
  5. name: productpage-viewer
  6. namespace: default
  7. spec:
  8. targetRefs:
  9. - kind: Service
  10. group: ""
  11. name: productpage
  12. action: ALLOW
  13. rules:
  14. - from:
  15. - source:
  16. principals:
  17. - cluster.local/ns/default/sa/curl
  18. to:
  19. - operation:
  20. methods: ["GET"]
  21. EOF

Note the targetRefs field is used to specify the target service for the authorization policy of a waypoint proxy. The rules section is similar as before, but this time we added the to section to specify the operation that is allowed.

To learn about how to enable more Istio’s features, read the Use Layer 7 features user guide.

Confirm the new waypoint proxy is enforcing the updated authorization policy:

  1. $ # This fails with an RBAC error because we're not using a GET operation
  2. $ kubectl exec deploy/curl -- curl -s "http://productpage:9080/productpage" -X DELETE
  3. RBAC: access denied
  1. $ # This fails with an RBAC error because the identity of the reviews-v1 service is not allowed
  2. $ kubectl exec deploy/reviews-v1 -- curl -s http://productpage:9080/productpage
  3. RBAC: access denied
  1. $ # This works as we're explicitly allowing GET requests from the curl pod
  2. $ kubectl exec deploy/curl -- curl -s http://productpage:9080/productpage | grep -o "<title>.*</title>"
  3. <title>Simple Bookstore App</title>

Next steps

With the waypoint proxy in place, you can now enforce Layer 7 policies in the namespace. In addition to authorization policies, we can use the waypoint proxy to split traffic between services. This is useful when doing canary deployments or A/B testing.