Authorization Policy Trust Domain Migration

This task shows you how to migrate from one trust domain to another without changing authorization policy.

In Istio 1.4, we introduce an alpha feature to support trust domain migration for authorization policy. This means if anIstio mesh needs to change its trust domain, the authorization policy doesn’t need to be changed manually.In Istio, if a workload is running in namespace foo with the service account bar, and the trust domain of the system is my-td,the identity of said workload is spiffe://my-td/ns/foo/sa/bar. By default, the Istio mesh trust domain is cluster.local,unless you specify it during the installation.

Before you begin

  1. $ cat <<EOF > ./td-installation.yaml
  2. apiVersion: install.istio.io/v1alpha2
  3. kind: IstioControlPlane
  4. spec:
  5. values:
  6. global:
  7. controlPlaneSecurityEnabled: false
  8. mtls:
  9. enabled: true
  10. trustDomain: old-td
  11. EOF
  12. $ istioctl manifest apply --set profile=demo -f td-installation.yaml
  • Deploy the httpbin sample in the default namespaceand the sleep sample in the default and sleep-allow namespaces:

ZipZipZip

  1. $ kubectl label namespace default istio-injection=enabled
  2. $ kubectl apply -f @samples/httpbin/httpbin.yaml@
  3. $ kubectl apply -f @samples/sleep/sleep.yaml@
  4. $ kubectl create namespace sleep-allow
  5. $ kubectl label namespace sleep-allow istio-injection=enabled
  6. $ kubectl apply -f @samples/sleep/sleep.yaml@ -n sleep-allow
  • Apply the authorization policy below to deny all requests to httpbin except from sleep in the sleep-allow namespace.
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: security.istio.io/v1beta1
  3. kind: AuthorizationPolicy
  4. metadata:
  5. name: service-httpbin.default.svc.cluster.local
  6. namespace: default
  7. spec:
  8. rules:
  9. - from:
  10. - source:
  11. principals:
  12. - old-td/ns/sleep-allow/sa/sleep
  13. to:
  14. - operation:
  15. methods:
  16. - GET
  17. selector:
  18. matchLabels:
  19. app: httpbin
  20. ---
  21. EOF

Notice that it may take tens of seconds for the authorization policy to be propagated to the sidecars.

  • Verify that requests to httpbin from:

    • sleep in the default namespace are denied.
  1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  2. 403
  • sleep in the sleep-allow namespace are allowed.
  1. $ kubectl exec $(kubectl -n sleep-allow get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -n sleep-allow -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  2. 200

Migrate trust domain without trust domain aliases

  • Install Istio with a new trust domain.
  1. $ cat <<EOF > ./td-installation.yaml
  2. apiVersion: install.istio.io/v1alpha2
  3. kind: IstioControlPlane
  4. spec:
  5. values:
  6. global:
  7. controlPlaneSecurityEnabled: false
  8. mtls:
  9. enabled: true
  10. trustDomain: new-td
  11. EOF
  12. $ istioctl manifest apply --set profile=demo -f td-installation.yaml

Istio mesh is now running with a new trust domain, new-td.

  • Delete secrets of sleep and httpbin in default namespace and in sleep-allow namespace. Notice if you install Istio with SDS,you don’t need to follow this step. Learn more about Provisioning Identity through SDS
  1. $ kubectl delete secrets istio.sleep; kubectl delete secrets istio.httpbin;
  1. $ kubectl delete secrets istio.sleep -n sleep-allow
  • Redeploy the httpbin and sleep applications to pick up changes from the new Istio control plane.
  1. $ kubectl delete pod --all
  1. $ kubectl delete pod --all -n sleep-allow
  • Verify that requests to httpbin from both sleep in default namespace and sleep-allow namespace are denied.
  1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  2. 403
  1. $ kubectl exec $(kubectl -n sleep-allow get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -n sleep-allow -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  2. 403

This is because we specified an authorization policy that deny all requests to httpbin, except the onesthe old-td/ns/sleep-allow/sa/sleep identity, which is the old identity of the sleep application in sleep-allow namespace.When we migrated to a new trust domain above, i.e. new-td, the identity of this sleep application is now new-td/ns/sleep-allow/sa/sleep,which is not the same as old-td/ns/sleep-allow/sa/sleep. Therefore, requests from the sleep application in sleep-allow namespaceto httpbin were allowed before are now being denied. Prior to Istio 1.4, the only way to make this work is to change the authorizationpolicy manually. In Istio 1.4, we introduce an easy way, as shown below.

Migrate trust domain with trust domain aliases

  • Install Istio with a new trust domain and trust domain aliases.
  1. $ cat <<EOF > ./td-installation.yaml
  2. apiVersion: install.istio.io/v1alpha2
  3. kind: IstioControlPlane
  4. spec:
  5. values:
  6. global:
  7. controlPlaneSecurityEnabled: false
  8. mtls:
  9. enabled: true
  10. trustDomain: new-td
  11. trustDomainAliases:
  12. - old-td
  13. EOF
  14. $ istioctl manifest apply --set profile=demo -f td-installation.yaml
  • Without changing the authorization policy, verify that requests to httpbin from:

    • sleep in the default namespace are denied.
  1. $ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  2. 403
  • sleep in the sleep-allow namespace are allowed.
  1. $ kubectl exec $(kubectl -n sleep-allow get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -n sleep-allow -- curl http://httpbin.default:8000/ip -s -o /dev/null -w "%{http_code}\n"
  2. 200

Best practices

Starting from Istio 1.4, when writing authorization policy, you should consider using the value cluster.local as thetrust domain part in the policy. For example, instead of old-td/ns/sleep-allow/sa/sleep, it should be cluster.local/ns/sleep-allow/sa/sleep.Notice that in this case, cluster.local is not the Istio mesh trust domain (the trust domain is still old-td). However,in authorization policy, cluster.local is a pointer that points to the current trust domain, i.e. old-td (and later new-td), as well as its aliases.By using cluster.local in the authorization policy, when you migrate to a new trust domain, Istio will detect this and treat the new trust domainas the old trust domain without you having to include the aliases.

Clean up

  1. $ kubectl delete authorizationpolicy service-httpbin.default.svc.cluster.local
  2. $ kubectl delete deploy httpbin; k delete service httpbin; k delete serviceaccount httpbin
  3. $ kubectl delete deploy sleep; k delete service sleep; k delete serviceaccount sleep
  4. $ kubectl delete namespace sleep-allow
  5. $ istioctl manifest generate --set profile=demo -f td-installation.yaml | kubectl delete -f -

See also

Authorization for HTTP traffic

Shows how to set up role-based access control for HTTP traffic.

Authorization for TCP traffic

Shows how to set up access control for TCP traffic.

Security

Describes Istio's authorization and authentication functionality.

Micro-Segmentation with Istio Authorization

Describe Istio's authorization feature and how to use it in various use cases.

Introducing the Istio v1beta1 Authorization Policy

Introduction, motivation and design principles for the Istio v1beta1 Authorization Policy.

Authorization for groups and list claims

Tutorial on how to configure the groups-base authorization and configure the authorization of list-typed claims in Istio.