Explicit Deny

    Before you begin this task, do the following:

    • Read the .

    • Follow the Istio installation guide to install Istio.

    • Deploy workloads:

      This task uses two workloads, httpbin and sleep, deployed on one namespace, foo. Both workloads run with an Envoy proxy in front of each. Deploy the example namespace and workloads with the following command:

    • Verify that sleep talks to httpbin with the following command:

    1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl http://httpbin.foo:8000/ip -sS -o /dev/null -w "%{http_code}\n"
    2. 200

    If you don’t see the expected output as you follow the task, retry after a few seconds. Caching and propagation overhead can cause some delay.

    1. The following command creates the deny-method-get authorization policy for the httpbin workload in the foo namespace. The policy sets the action to DENY to deny requests that satisfy the conditions set in the rules section. This type of policy is better known as deny policy. In this case, the policy denies requests if their method is GET.

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: security.istio.io/v1beta1
      3. kind: AuthorizationPolicy
      4. metadata:
      5. name: deny-method-get
      6. namespace: foo
      7. spec:
      8. selector:
      9. matchLabels:
      10. app: httpbin
      11. action: DENY
      12. - to:
      13. - operation:
      14. methods: ["GET"]
    2. Verify that GET requests are denied:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/get" -X GET -sS -o /dev/null -w "%{http_code}\n"
      2. 403
    3. Verify that POST requests are allowed:

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: security.istio.io/v1beta1
      3. kind: AuthorizationPolicy
      4. metadata:
      5. name: deny-method-get
      6. namespace: foo
      7. spec:
      8. selector:
      9. matchLabels:
      10. app: httpbin
      11. action: DENY
      12. rules:
      13. - operation:
      14. methods: ["GET"]
      15. when:
      16. - key: request.headers[x-token]
      17. notValues: ["admin"]
    4. Verify that GET requests with the HTTP header x-token: admin are allowed:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: admin" -sS -o /dev/null -w "%{http_code}\n"
      2. 200
    5. Verify that GET requests with the HTTP header x-token: guest are denied:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: guest" -sS -o /dev/null -w "%{http_code}\n"
      2. 403
    6. The following command creates the allow-path-ip authorization policy to allow requests at the /ip path to the httpbin workload. This authorization policy sets the action field to ALLOW. This type of policy is better known as an allow policy.

    7. Verify that GET requests with the HTTP header x-token: guest at path /ip are denied by the deny-method-get policy. Deny policies takes precedence over the allow policies:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -X GET -H "x-token: guest" -s -o /dev/null -w "%{http_code}\n"
      2. 403
    8. Verify that GET requests with the HTTP header x-token: admin at path /ip are allowed by the allow-path-ip policy:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/ip" -X GET -H "x-token: admin" -s -o /dev/null -w "%{http_code}\n"
      2. 200
      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: admin" -s -o /dev/null -w "%{http_code}\n"
    1. Remove the namespace foo from your configuration: