Explicit Deny
This task shows you how to set up Istio authorization policy of DENY action to explicitly deny traffic in an Istio
mesh. This is different from the ALLOW action because the DENY action has higher priority and will not be
bypassed by any ALLOW actions.
Before you begin
Before you begin this task, do the following:
Read the Istio authorization concepts.
Follow the Istio installation guide to install Istio.
Deploy workloads:
This task uses two workloads,
httpbinandcurl, 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:$ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f @samples/httpbin/httpbin.yaml@) -n foo $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n fooVerify that
curltalks tohttpbinwith the following command:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl http://httpbin.foo:8000/ip -sS -o /dev/null -w "%{http_code}\n" 200
Explicitly deny a request
The following command creates the
deny-method-getauthorization policy for thehttpbinworkload in thefoonamespace. The policy sets theactiontoDENYto deny requests that satisfy the conditions set in therulessection. This type of policy is better known as a deny policy. In this case, the policy denies requests if their method isGET.$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: deny-method-get namespace: foo spec: selector: matchLabels: app: httpbin action: DENY rules: - to: - operation: methods: ["GET"] EOFVerify that
GETrequests are denied:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -sS -o /dev/null -w "%{http_code}\n" 403Verify that
POSTrequests are allowed:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/post" -X POST -sS -o /dev/null -w "%{http_code}\n" 200Update the
deny-method-getauthorization policy to denyGETrequests only if thex-tokenvalue of the HTTP header is notadmin. The following example policy sets the value of thenotValuesfield to["admin"]to deny requests with a header value that is notadmin:$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: deny-method-get namespace: foo spec: selector: matchLabels: app: httpbin action: DENY rules: - to: - operation: methods: ["GET"] when: - key: request.headers[x-token] notValues: ["admin"] EOFVerify that
GETrequests with the HTTP headerx-token: adminare allowed:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: admin" -sS -o /dev/null -w "%{http_code}\n" 200Verify that GET requests with the HTTP header
x-token: guestare denied:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: guest" -sS -o /dev/null -w "%{http_code}\n" 403The following command creates the
allow-path-ipauthorization policy to allow requests at the/ippath to thehttpbinworkload. This authorization policy sets theactionfield toALLOW. This type of policy is better known as an allow policy.$ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-path-ip namespace: foo spec: selector: matchLabels: app: httpbin action: ALLOW rules: - to: - operation: paths: ["/ip"] EOFVerify that
GETrequests with the HTTP headerx-token: guestat path/ipare denied by thedeny-method-getpolicy. Deny policies takes precedence over the allow policies:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/ip" -X GET -H "x-token: guest" -s -o /dev/null -w "%{http_code}\n" 403Verify that
GETrequests with the HTTP headerx-token: adminat path/ipare allowed by theallow-path-ippolicy:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/ip" -X GET -H "x-token: admin" -s -o /dev/null -w "%{http_code}\n" 200Verify that
GETrequests with the HTTP headerx-token: adminat path/getare denied because they don’t match theallow-path-ippolicy:$ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" -c curl -n foo -- curl "http://httpbin.foo:8000/get" -X GET -H "x-token: admin" -s -o /dev/null -w "%{http_code}\n" 403
Clean up
Remove the namespace foo from your configuration:
$ kubectl delete namespace foo