Strengthen your app's security with Cloud Service Mesh, Config Sync, and Policy Controller

This tutorial shows you how to improve your cluster and app's security posture.Imagine you are a platform administrator whose organization is managing the appsfor their online store withCloud Service Mesh, asuite of tools that helps you monitor and manage a reliable service mesh. Youare responsible for ensuring that your mesh and apps are secure.

You can prevent misconfiguration and automatically validate your Cloud Service Meshpolicies by usingPolicy Controller andConfig Sync.Policy Controller enables the enforcement of fully programmable policies foryour clusters. Policy Controller also comes with a default library ofconstraint templatesthat you can use with theCloud Service Mesh security bundle to audit the compliance of your mesh security vulnerabilities and best practices.Config Sync continuously reconciles the state of clusterswith a central set of Kubernetes declarative configuration files. UsingPolicy Controller and Config Sync together enables you to continuouslyenforceconstraintson your Cloud Service Mesh policy configurations.

The following diagram shows you an overview of how Cloud Service Mesh,Policy Controller, and Config Sync work together in this tutorial to manageand protect aningress gateway and theOnline Boutique sample apps that you use in this tutorial:

A diagram showing the architecture that you create for this tutorial

Objectives

  • Create a Google Kubernetes Engine (GKE) cluster and register the cluster to afleet.
  • Install Policy Controller, Config Sync, and Cloud Service Mesh on a cluster.
  • Configure Config Sync tosync multiple repositories
  • Apply best practices to deploy configs, apps and Istio resources withConfig Sync.
  • Deploy cluster configs, the Online Boutique sample apps, and an ingressgateway with Config Sync.
  • Leverage theCloud Service Mesh policy bundleof Policy Controller to enforce the following security best practices:
    • Ensure that all workloads in the mesh have automatic sidecar injection.
    • Encrypt all traffic in the mesh.
    • Guarantee that all workloads in the mesh have granular access control.

Costs

In this document, you use the following billable components of Google Cloud:

  • GKE.
  • GKE Enterprise. The billing for GKE Enterprise includes billing for theCloud Service Mesh, Config Sync, and Policy Controller.

To generate a cost estimate based on your projected usage, use thepricing calculator.

New Google Cloud users might be eligible for afree trial.

When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, seeClean up.

Before you begin

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
    Note: If you don't plan to keep the resources that you create in this procedure, create a project instead of selecting an existing project. After you finish these steps, you can delete the project, removing all resources associated with the project.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

Prepare your environment

In this section, you prepare your environment so that you can installCloud Service Mesh, Policy Controller, and Config Sync:

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  2. Upgrade to the latest version of the Google Cloud CLI:

    gcloudcomponentsupdate
  3. To store the files that you create in this tutorial, create a directory:

    mkdir~/asm-acm-tutorial-dir
  4. To simplify the remainder of the tutorial, create the following environmentvariables:

    PROJECT_ID=PROJECT_IDgcloudconfigsetproject$PROJECT_IDCLUSTER=asm-acm-tutorialCLUSTER_ZONE=us-east4-aMEMBERSHIP=asm-acm-tutorialPROJECT_NUMBER=$(gcloudprojectsdescribe${PROJECT_ID}--format='get(projectNumber)')

    ReplacePROJECT_ID with the project ID thatyou want to use for this tutorial.

    If you're asked to authorize Cloud Shell, clickAuthorize tocomplete the operation.

  5. Enable the APIs that you need for this tutorial:

    gcloud

    gcloudservicesenable\mesh.googleapis.com\anthos.googleapis.com

    Config Connector

    This tutorial includesConfig Connectorresources. You can use these resources to complete the same tasks that youcomplete in thegcloud tab. To utilize these resources,install Config Connectorand apply the resources in the way that works best for your environment.

    Use the followingServicesmanifest:

    apiVersion:serviceusage.cnrm.cloud.google.com/v1beta1kind:Servicemetadata:annotations:cnrm.cloud.google.com/deletion-policy:"abandon"cnrm.cloud.google.com/disable-dependent-services:"false"name:mesh.googleapis.comspec:resourceID:mesh.googleapis.comprojectRef:external:PROJECT_ID---apiVersion:serviceusage.cnrm.cloud.google.com/v1beta1kind:Servicemetadata:annotations:cnrm.cloud.google.com/deletion-policy:"abandon"cnrm.cloud.google.com/disable-dependent-services:"false"name:anthos.googleapis.comspec:resourceID:anthos.googleapis.comprojectRef:external:PROJECT_ID

    This operation can take over one minute to complete.

Set up a GKE cluster

In this section, you create a GKE cluster and then registerit to afleet. Fleets are aGoogle Cloud concept for logically organizing clusters and other resources,letting you use and manage multi-cluster capabilities and apply consistentpolicies across your systems.

The cluster that you create in this section is the cluster that you installCloud Service Mesh, Policy Controller, and Config Sync on. It's also the clusterwhere you deploy the Online Boutique sample apps.

To set up your cluster, complete the following steps:

  1. Create a GKE cluster:

    gcloud

    gcloudcontainerclusterscreate${CLUSTER}\--zone${CLUSTER_ZONE}\--machine-type=e2-standard-4\--num-nodes4\--workload-pool${PROJECT_ID}.svc.id.goog\--labelsmesh_id=proj-${PROJECT_NUMBER}

    Config Connector

    Use the followingContainerClusterandContainerNodePoolmanifests:

    apiVersion:container.cnrm.cloud.google.com/v1beta1kind:ContainerNodePoolmetadata:annotations:cnrm.cloud.google.com/project-id:PROJECT_IDname:asm-acm-tutorialspec:clusterRef:name:asm-acm-tutoriallocation:us-east4-anodeConfig:machineType:e2-standard-4nodeCount:4---apiVersion:container.cnrm.cloud.google.com/v1beta1kind:ContainerClustermetadata:annotations:cnrm.cloud.google.com/project-id:PROJECT_IDcnrm.cloud.google.com/remove-default-node-pool:"true"labels:mesh_id:proj-PROJECT_NUMBERname:asm-acm-tutorialspec:location:us-east4-ainitialNodeCount:1workloadIdentityConfig:workloadPool:PROJECT_ID.svc.id.goog

    ReplacePROJECT_NUMBER by the value of thePROJECT_NUMBER environmentvariable retrieved earlier.

    This operation can take over five minutes to complete.

  2. To ensure the successful creation of the GKE cluster, describe itsstatus:

    gcloudcontainerclusterslist\--zone${CLUSTER_ZONE}\--project${PROJECT_ID}

    The output is similar to the following:

    NAME                LOCATION      MASTER_VERSION   MASTER_IP      MACHINE_TYPE   NODE_VERSION     NUM_NODES  STATUSasm-acm-tutorial    us-east4-a    1.23.12-gke.100  35.186.179.30  e2-standard-4  1.23.12-gke.100  3          RUNNING
  3. Connect to the GKE cluster:

    gcloudcontainerclustersget-credentials${CLUSTER}\--zone${CLUSTER_ZONE}\--project${PROJECT_ID}
  4. Register your cluster to a fleet:

    gcloud

    gcloudcontainerfleetmembershipsregister${MEMBERSHIP}\--project${PROJECT_ID}\--gke-cluster${CLUSTER_ZONE}/${CLUSTER}\--enable-workload-identity

    The output is similar to the following:

    kubeconfig entry generated for asm-acm-tutorial.Waiting for membership to be created...done.Created a new membership [projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial] for the cluster [asm-acm-tutorial]Generating the Connect Agent manifest...Deploying the Connect Agent on cluster [asm-acm-tutorial] in namespace [gke-connect]...Deployed the Connect Agent on cluster [asm-acm-tutorial] in namespace [gke-connect].Finished registering the cluster [asm-acm-tutorial] with the Fleet.

    Config Connector

    Use the followingGKEHubMembershipmanifest:

    apiVersion:gkehub.cnrm.cloud.google.com/v1beta1kind:GKEHubMembershipmetadata:annotations:cnrm.cloud.google.com/project-id:PROJECT_IDname:asm-acm-tutorialspec:location:globalauthority:issuer:https://container.googleapis.com/v1/projects/PROJECT_ID/locations/us-east4-a/clusters/asm-acm-tutorialendpoint:gkeCluster:resourceRef:name:asm-acm-tutorial
  5. To ensure the successful registration of the GKE cluster,describe its status:

    gcloudcontainerfleetmembershipslist

    The output is similar to the following:

    NAME              EXTERNAL_ID                           LOCATIONasm-acm-tutorial  0e12258c-8831-4d81-b5c0-5e7099a468cc  global

Explore the repositories

In the followinginstallation section, you apply amanifestacm-config.yaml file. This manifest configuresyour cluster to sync from theasm-acm-tutorial folder of the sample repository. This folder contains allthe configuration files that you need to complete the remainder of the tutorial.

To simplify this tutorial, you usesed commands to update theacm-config.yaml. With theacm-config.yaml file,Config Sync deploys the manifests required for each step of this tutorial.Updating a single file helps you focus on the concepts and the flow of securingyour clusters, mesh, and applications without repeatedly manipulating the filesand repeatedly runninggit commands.

To utilize Config Sync's ability tosync multiple repositories,you use the following resources:

  • root-sync,as aRootSyncrepository, contains all the configs across your cluster includingRepoSyncs,Constraints,ClusterRole,RoleBindings, and resources included in some systemnamespaces such asistio-system.
  • ingress-gateway,as a firstRepoSync, contains all the resources needed to deploy aningress gateway and progressively secure it throughout this tutorial.
  • online-boutique,as a secondRepoSync, contains all the resources needed to deploy theOnline Boutique apps and progressively secure them throughout this tutorial.

Install Policy Controller, Config Sync, and managed Cloud Service Mesh

Now that you have created and registered your cluster, you can installConfig Sync, Policy Controller, and Cloud Service Mesh on your cluster andconfigure your cluster to sync from the configs of the defaultRootSync:

  1. Enable theConfigManagement operator, which manages Config Syncand Policy Controller:

    gcloud

    gcloudbetacontainerfleetconfig-managementenable

    Config Connector

    Use the followingGKEHubFeaturemanifest:

    apiVersion:gkehub.cnrm.cloud.google.com/v1beta1kind:GKEHubFeaturemetadata:name:configmanagementspec:projectRef:external:PROJECT_IDlocation:globalresourceID:configmanagement
  2. Enable Cloud Service Mesh in your fleet.

    gcloud

    gcloudcontainerfleetmeshenable

    Config Connector

    Use the followingGKEHubFeaturemanifest:

    apiVersion:gkehub.cnrm.cloud.google.com/v1beta1kind:GKEHubFeaturemetadata:name:servicemeshspec:projectRef:external:PROJECT_IDlocation:globalresourceID:servicemesh
  3. Enable the Cloud Service Mesh automatic management to let Googleapply the recommended configuration of managed Cloud Service Mesh:

    gcloud

    gcloudcontainerfleetmeshupdate\--managementautomatic\--memberships${MEMBERSHIP}

    Config Connector

    Use the followingGKEHubFeatureMembershipmanifest:

    apiVersion:gkehub.cnrm.cloud.google.com/v1beta1kind:GKEHubFeatureMembershipmetadata:name:servicemesh-membershipspec:projectRef:external:PROJECT_IDlocation:globalmembershipRef:name:asm-acm-tutorialfeatureRef:name:servicemeshmesh:management:MANAGEMENT_AUTOMATIC
  4. Enable Config Sync and Policy Controller:

    gcloud

    Save the following manifest asacm-config.yamlin the~/asm-acm-tutorial-dir directory:

    applySpecVersion:1spec:configSync:enabled:truepolicyDir:asm-acm-tutorial/root-sync/initsecretType:nonesourceFormat:unstructuredsyncRepo:https://github.com/GoogleCloudPlatform/anthos-config-management-samplessyncBranch:mainpolicyController:enabled:truereferentialRulesEnabled:truetemplateLibraryInstalled:true

    To learn more about the Google Cloud CLI config fields, seegcloud apply spec fields.

    Apply the file:

    gcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    Config Connector

    Use the followingGKEHubFeatureMembershipmanifest:

    apiVersion:gkehub.cnrm.cloud.google.com/v1beta1kind:GKEHubFeatureMembershipmetadata:name:configmanagement-membershipspec:projectRef:external:PROJECT_IDlocation:globalmembershipRef:name:asm-acm-tutorialfeatureRef:name:configmanagementconfigmanagement:configSync:sourceFormat:unstructuredgit:policyDir:asm-acm-tutorial/root-sync/initsecretType:nonesyncBranch:mainsyncRepo:https://github.com/GoogleCloudPlatform/anthos-config-management-samplespolicyController:enabled:truereferentialRulesEnabled:truetemplateLibraryInstalled:true

    Policy Controller and Config Sync are installed on your cluster. Next,Config Sync begins syncing all the configs of the defaultRootSync toyour cluster. These configs install and configure the following keycomponents:

    • TheRepoSync objects that configure the Online Boutique apps and theingress gateway are synced:

      apiVersion:configsync.gke.io/v1beta1kind:RepoSyncmetadata:name:repo-syncspec:override:enableShellInRendering:truesourceFormat:unstructuredgit:repo:https://github.com/GoogleCloudPlatform/anthos-config-management-samplesrevision:HEADbranch:maindir:asm-acm-tutorial/online-boutique/initauth:none
      apiVersion:configsync.gke.io/v1beta1kind:RepoSyncmetadata:name:repo-syncspec:override:enableShellInRendering:truesourceFormat:unstructuredgit:repo:https://github.com/GoogleCloudPlatform/anthos-config-management-samplesrevision:HEADbranch:maindir:asm-acm-tutorial/ingress-gateway/initauth:none
    • Since theRepoSync reconcilers need additional permissionsto create Istio resources, aClusterRole and twoRoleBinding objectsto grant these permissions are also applied to your cluster:

      apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:labels:rbac.authorization.k8s.io/aggregate-to-edit:"true"name:custom:aggregate-to-edit:istiorules:-apiGroups:-"networking.istio.io"-"security.istio.io"resources:-"virtualservices"-"authorizationpolicies"-"gateways"verbs:-"*"
      apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:repo-syncsubjects:-kind:ServiceAccountname:ns-reconciler-onlineboutiquenamespace:config-management-systemroleRef:kind:ClusterRolename:editapiGroup:rbac.authorization.k8s.io
      apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:repo-syncsubjects:-kind:ServiceAccountname:ns-reconciler-asm-ingressnamespace:config-management-systemroleRef:kind:ClusterRolename:editapiGroup:rbac.authorization.k8s.io
  5. To ensure the successful installation of Policy Controller andConfig Sync, check the status:

    gcloudbetacontainerfleetconfig-managementstatus

    The output is similar to the following:

    Name: asm-acm-tutorialStatus: SYNCEDLast_Synced_Token: 4b3384dSync_Branch: mainLast_Synced_Time: 2022-05-04T21:32:58ZPolicy_Controller: INSTALLED

    If you seePENDING orNOT_INSTALLED in theStatus orPolicy_Controllerrows, wait a few minutes and rungcloud beta container fleet config-management status again.

  6. To ensure the successful installation of Cloud Service Mesh, describe its status:

    gcloudcontainerfleetmeshdescribe

    The output is similar to the following:

    createTime: '2022-09-13T23:12:56.477042921Z'membershipSpecs:  projects/PROJECT_NUMBER/locations/global/memberships/asm-acm-tutorial:    mesh:      management: MANAGEMENT_AUTOMATICmembershipStates:  projects/PROJECT_NUMBER/locations/global/memberships/asm-acm-tutorial:    servicemesh:      controlPlaneManagement:        details:        - code: REVISION_READY          details: 'Ready: asm-managed'        state: ACTIVE      dataPlaneManagement:        details:        - code: OK          details: Service is running.        state: ACTIVE    state:      code: OK      description: |-        Revision(s) ready for use: asm-managed.        All Canonical Services have been reconciled successfully.      updateTime: '2022-09-14T00:19:10.571552206Z'name: projects/PROJECT_ID/locations/global/features/servicemeshresourceState:  state: ACTIVEspec: {}state:  state: {}updateTime: '2022-09-14T00:19:14.135113118Z'

    If you seestate.code: ERROR instead ofstate.code: OK, wait a few minutes and rungcloud container fleet mesh describe again. Before moving forward with the tutorial,you need to make sure that theservicemesh.controlPlaneManagement.details.code fieldhas theREVISION_READY value.

Deploy an ingress gateway and a sample application

In this section, you deploy theOnline Boutique sample application and aningress gateway to manage ingress traffic.

  1. Deploy the Online Boutique sample application and the ingress gateway.

    The following command usessed to update theacm-config.yaml manifest toget Config Sync deploying the resources you need to deploy the ingressgateway and sample app.

    sed-i"s,root-sync/init,root-sync/deployments,g"~/asm-acm-tutorial-dir/acm-config.yamlgcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    Note this step can take a few minutes to complete.

  2. View the Config Sync status for theRootSync and the twoRepoSyncs:

    gcloudalphaanthosconfigsyncrepodescribe

    The output is similar to:

    getting 3 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial[  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "95a30c052566357afb9db3d7f6153d9c0f219c03",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/deployments@main",    "status": "SYNCED"  },  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "95a30c052566357afb9db3d7f6153d9c0f219c03",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/ingress-gateway/deployments@main",    "status": "SYNCED"  },  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "95a30c052566357afb9db3d7f6153d9c0f219c03",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/online-boutique/deployments@main",    "status": "SYNCED"  }]

    If you seestatus: RECONCILING instead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describe again.

    To only view the information of one repository you can use the--sync-nameand--sync-namespace flags. To view the managed resources in detail,add the--managed-resources flag.For more information, seeView Config Sync status across multiple clusters.

  3. Wait for the ingress gateway's public IP address to be provisioned:

    untilkubectl-nasm-ingressgetsvcasm-ingressgateway-ojsonpath='{.status.loadBalancer}'|grep"ingress";do:;done
  4. Get the ingress gateway's public IP address:

    EXTERNAL_IP=$(kubectlgetsvcasm-ingressgateway-nasm-ingress-ojsonpath="{.status.loadBalancer.ingress[*].ip}")
  5. Visit the IP address from your browser to verify that the Online Boutique apphas successfully deployed:

    echohttp://${EXTERNAL_IP}

Enforce policies to secure your mesh

In the following sections, you leveragePolicy Controllerto enforce policies from theCloud Service Mesh policy bundlebycreating constraints.

Enforce sidecar proxies injection

In this section you enforce policies to ensure that all workloads in the mesh haveautomatic sidecar injectionenabled.

  1. To enforce sidecar proxies injection, apply constraints.

    The following command usessed to update theacm-config.yaml manifest to get Config Sync deploying the associated resources.

    sed-i"s,root-sync/deployments,root-sync/enforce-sidecar-injection,g"~/asm-acm-tutorial-dir/acm-config.yamlgcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    The preceding command deploys the following resources:

    • AK8sRequiredLabelsConstraint that requires anyNamespace in the mesh to contain the specificCloud Service Mesh sidecar proxy injection label:

      apiVersion:constraints.gatekeeper.sh/v1beta1kind:K8sRequiredLabelsmetadata:name:namespace-sidecar-injection-labelspec:enforcementAction:denymatch:kinds:-apiGroups:-""kinds:-NamespaceexcludedNamespaces:-config-management-monitoring-config-management-system-default-gatekeeper-system-gke-connect-istio-system-kube-node-lease-kube-public-kube-system-resource-group-systemparameters:labels:-allowedRegex:enabledkey:istio-injection
    • AnAsmSidecarInjectionConstraint that prohibits anyPod in the mesh from bypassing the Istioproxy sidecar injection:

      apiVersion:constraints.gatekeeper.sh/v1beta1kind:AsmSidecarInjectionmetadata:name:pod-sidecar-injection-annotationspec:enforcementAction:denymatch:kinds:-apiGroups:-""kinds:-PodexcludedNamespaces:-kube-systemparameters:strictnessLevel:High
  2. View the Config Sync status for theRootSync:

    gcloud alpha anthos config sync repo describe \    --sync-name root-sync \    --sync-namespace config-management-system

    The output is similar to:

    getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial[  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/enforce-sidecar-injection@main",    "status": "SYNCED"  }]

    If you seestatus: RECONCILING instead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describe again.

  3. Verify theConstraints are created:

    kubectlgetconstraints

    It can take a few minutes for Policy Controller to evaluate theseconstraints. If you don't see values in theTOTAL-VIOLATIONS column, waitand runkubectl get constraints again.

    The output is similar to:

    NAME                                                                                       ENFORCEMENT-ACTION   TOTAL-VIOLATIONSpodsidecarinjectionannotation.constraints.gatekeeper.sh/pod-sidecar-injection-annotation   deny                 0NAME                                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONSk8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label   deny                 0

    Because we properly set up ourNamespaces andPods, there are0TOTAL-VIOLATIONS for theseConstraints.

  4. To see theseConstraints at work, try to create aNamespace in your clusterwith neither alabel nor anannotation:

    kubectlcreatenamespacetest

    The output is similar is the following error:

    Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: [namespace-sidecar-injection-label] you must provide labels: {"istio-injection"}

Enforce traffic encryption

In this section you enforce policies to ensure that all traffic in the mesh isencrypted.

  1. To enforce traffic encryption, apply constraints.

    The following command usessed to update theacm-config.yaml manifest to get Config Sync deploying the associated resources.

    sed-i"s,root-sync/enforce-sidecar-injection,root-sync/enforce-strict-mtls,g"~/asm-acm-tutorial-dir/acm-config.yamlgcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    The preceding command deploys the following resources:

    • AnAsmPeerAuthnMeshStrictMtlsConstraint which enforces the mesh-level mTLSPeerAuthentication in theistio-system namespace:

      apiVersion:constraints.gatekeeper.sh/v1beta1kind:AsmPeerAuthnMeshStrictMtlsmetadata:name:mesh-level-strict-mtlsspec:enforcementAction:denyparameters:rootNamespace:istio-systemstrictnessLevel:High
    • Areferential constraintConfig in thegatekeeper-system namespace. This referential constraintenables theAsmPeerAuthnMeshStrictMtlsConstraint to reference anotherobject in its definition (for example, searching for anyPeerAuthentication in theistio-systemNamespace):

      apiVersion:config.gatekeeper.sh/v1alpha1kind:Configmetadata:name:configspec:sync:syncOnly:-group:""version:"v1"kind:"Namespace"-group:"security.istio.io"version:"v1beta1"kind:"PeerAuthentication"-group:"security.istio.io"version:"v1beta1"kind:"AuthorizationPolicy"
    • ADestinationRuleTLSEnabledConstraint which prohibits disabling TLS for all hosts and host subsets inIstioDestinationRules:

      apiVersion:constraints.gatekeeper.sh/v1beta1kind:DestinationRuleTLSEnabledmetadata:name:destination-rule-tls-enabledspec:enforcementAction:denymatch:kinds:-apiGroups:-networking.istio.iokinds:-DestinationRule
    • AnAsmPeerAuthnStrictMtlsConstraint which enforces that allPeerAuthentications cannot overwriteSTRICT mTLS:

      apiVersion:constraints.gatekeeper.sh/v1beta1kind:AsmPeerAuthnStrictMtlsmetadata:name:peerauthentication-strict-mtlsspec:enforcementAction:denymatch:kinds:-apiGroups:-security.istio.iokinds:-PeerAuthenticationparameters:strictnessLevel:High
  2. View the Config Sync status for theRootSync:

    gcloud alpha anthos config sync repo describe \    --sync-name root-sync \    --sync-namespace config-management-system

    The output is similar to:

    getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial[  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/enforce-strict-mtls@main",    "status": "SYNCED"  }]

    If you seestatus: RECONCILING instead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describe again.

  3. Run the following command to get more information about thePeerAuthentication violation:

    kubectlgetasmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls-ojsonpath='{.status.violations}'|jq

    The output is similar to:

    [  {    "enforcementAction": "deny",    "group": "constraints.gatekeeper.sh",    "kind": "AsmPeerAuthnMeshStrictMtls",    "message": "Root namespace <istio-system> does not have a strict mTLS PeerAuthentication",    "name": "mesh-level-strict-mtls",    "version": "v1beta1"  }]
  4. Fix the issue by deploying aPeerAuthentication in theistio-system. To prevent all your servicesin the mesh from accepting plaintext traffic, set a mesh-widePeerAuthentication policy with the mTLSmode set toSTRICT. When you deploy the policy, the control plane automatically provisions TLS certificatesso that workloads can authenticate with each other.

    The following command usessed to update theacm-config.yaml manifest to get Config Sync deploying the associated resources.

    sed-i"s,root-sync/enforce-strict-mtls,root-sync/fix-strict-mtls,g"~/asm-acm-tutorial-dir/acm-config.yamlgcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    The preceding command deploys the followingSTRICT mTLSPeerAuthentication in theistio-systemnamespace. This applies mTLSSTRICT to the entire mesh:

    apiVersion:security.istio.io/v1beta1kind:PeerAuthenticationmetadata:name:defaultspec:mtls:mode:STRICT
  5. View the Config Sync status for theRootSync:

    gcloudalphaanthosconfigsyncrepodescribe\--sync-nameroot-sync\--sync-namespaceconfig-management-system

    The output is similar to:

    getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial[  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/fix-strict-mtls@main",    "status": "SYNCED"  }]

    If you seestatus: RECONCILING instead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describe again.

  6. Verify theConstraints are created:

    kubectlgetconstraints

    Note this can take a few minutes to get Policy Controller evaluating theseConstraints. Wait and run again thiskubectl get constraints command until you get values under theTOTAL-VIOLATIONS column for each line.

    The output is similar to:

    NAME                                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONSk8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label   deny                 0NAME                                                                          ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls   deny                 0NAME                                                                               ENFORCEMENT-ACTION   TOTAL-VIOLATIONSdestinationruletlsenabled.constraints.gatekeeper.sh/destination-rule-tls-enabled   deny                 0NAME                                                                              ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmpeerauthnstrictmtls.constraints.gatekeeper.sh/peerauthentication-strict-mtls   deny                 0NAME                                                                             ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmsidecarinjection.constraints.gatekeeper.sh/pod-sidecar-injection-annotation   deny                 0

Enforce granular access control

In this section you enforce policies to ensure that all workloads in the meshhavegranular access control.

  1. To enforce granular access control, apply constraints.

    The following command usessed to update theacm-config.yaml manifest to get Config Sync deploying the associated resources.

    sed-i"s,root-sync/fix-strict-mtls,root-sync/enforce-authorization-policies,g"~/asm-acm-tutorial-dir/acm-config.yamlgcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    The preceding command deploys the following resources:

    • AnAsmAuthzPolicyDefaultDenyConstraint which enforces themesh-level default denyAuthorizationPolicy in theistio-system namespace:

      apiVersion:constraints.gatekeeper.sh/v1beta1kind:AsmAuthzPolicyDefaultDenymetadata:name:default-deny-authorization-policiesspec:enforcementAction:denyparameters:rootNamespace:istio-systemstrictnessLevel:High
    • AnAsmAuthzPolicyEnforceSourcePrincipalsConstraintwhich enforces that anyAuthorizationPolicies is defining granular source principals (other than "*"). Only the ingress gateway in theasm-ingress namespace isan exception to this rule in order to receive the traffic from the end-users and redirect the traffic to the Online Boutique'sfrontend app.

      apiVersion:constraints.gatekeeper.sh/v1beta1kind:AsmAuthzPolicyEnforceSourcePrincipalsmetadata:name:authz-source-principals-not-allspec:enforcementAction:denymatch:kinds:-apiGroups:-security.istio.iokinds:-AuthorizationPolicyexcludedNamespaces:-asm-ingress
  2. View the Config Sync status for theRootSync:

    gcloudalphaanthosconfigsyncrepodescribe\--sync-nameroot-sync\--sync-namespaceconfig-management-system

    The output is similar to:

    getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial[  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/enforce-authorization-policies@main",    "status": "SYNCED"  }]

    If you seestatus: RECONCILING instead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describe again.

  3. Run the following command to get more information about the associated violation:

    kubectlgetasmauthzpolicydefaultdeny.constraints.gatekeeper.sh/default-deny-authorization-policies-ojsonpath='{.status.violations}'|jq

    The output is similar to:

    [  {    "enforcementAction": "deny",    "group": "constraints.gatekeeper.sh",    "kind": "AsmAuthzPolicyDefaultDeny",    "message": "Root namespace <istio-system> does not have a default deny AuthorizationPolicy",    "name": "default-deny-authorization-policies",    "version": "v1beta1"  }]
  4. Fix the issue by deploying theAuthorizationPolicy in theistio-systemnamespace.

    The following command usessed to update theacm-config.yaml manifest to get Config Sync deploying the associated resources.

    sed-i"s,root-sync/enforce-authorization-policies,root-sync/fix-default-deny-authorization-policy,g"~/asm-acm-tutorial-dir/acm-config.yamlgcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    The preceding command deploys the following deny-allAuthorizationPolicy in theistio-systemnamespace:

    apiVersion:security.istio.io/v1beta1kind:AuthorizationPolicymetadata:name:deny-allspec:{}
  5. View the Config Sync status for theRootSync:

    gcloudalphaanthosconfigsyncrepodescribe\--sync-nameroot-sync\--sync-namespaceconfig-management-system

    The output is similar to:

    getting 1 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial[  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/fix-default-deny-authorization-policy@main",    "status": "SYNCED"  }]

    If you seestatus: RECONCILING instead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describe again.

  6. Verify theConstraints are created:

    kubectlgetconstraints

    Note this can take a few minutes to get Policy Controller evaluating theseConstraints. Wait and run again thiskubectl get constraints command until you get values under theTOTAL-VIOLATIONS column for each line.

    The output is similar to:

    NAME                                                                             ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmsidecarinjection.constraints.gatekeeper.sh/pod-sidecar-injection-annotation   deny                 0NAME                                                                            ENFORCEMENT-ACTION   TOTAL-VIOLATIONSk8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label   deny                 0NAME                                                                                      ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmauthzpolicydefaultdeny.constraints.gatekeeper.sh/default-deny-authorization-policies   deny                 0NAME                                                                          ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls   deny                 0NAME                                                                               ENFORCEMENT-ACTION   TOTAL-VIOLATIONSdestinationruletlsenabled.constraints.gatekeeper.sh/destination-rule-tls-enabled   deny                 0NAME                                                                              ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmpeerauthnstrictmtls.constraints.gatekeeper.sh/peerauthentication-strict-mtls   deny                 0NAME                                                                                              ENFORCEMENT-ACTION   TOTAL-VIOLATIONSasmauthzpolicyenforcesourceprincipals.constraints.gatekeeper.sh/authz-source-principals-not-all   deny                 0
  7. Visit the Online Boutique app from your browser:

    echohttp://${EXTERNAL_IP}

    You should receive the error:RBAC: access denied which confirms that thedefault denyAuthorizationPolicy is applied to the entire mesh.

  8. Fix this issue by deploying more granularAuthorizationPolicies intheasm-ingress andonlineboutique namespaces.

    The following command usessed to update theacm-config.yaml manifest to get Config Sync deploying the associated resources.

    sed-i"s,root-sync/fix-default-deny-authorization-policy,root-sync/deploy-authorization-policies,g"~/asm-acm-tutorial-dir/acm-config.yamlgcloudbetacontainerfleetconfig-managementapply\--membership${MEMBERSHIP}\--config~/asm-acm-tutorial-dir/acm-config.yaml

    The preceding command deploys the following resources:

    • AnAuthorizationPolicy in theasm-ingressnamespace:

      apiVersion:security.istio.io/v1beta1kind:AuthorizationPolicymetadata:name:asm-ingressgatewayspec:selector:matchLabels:asm:ingressgatewayrules:-to:-operation:ports:-"8080"
    • AnAuthorizationPolicy per app in theonlineboutiquenamespace, here is the example for thecartservice app:

      apiVersion:security.istio.io/v1beta1kind:AuthorizationPolicymetadata:name:cartservicespec:selector:matchLabels:app:cartservicerules:-from:-source:principals:-cluster.local/ns/onlineboutique/sa/frontend-cluster.local/ns/onlineboutique/sa/checkoutserviceto:-operation:paths:-/hipstershop.CartService/AddItem-/hipstershop.CartService/GetCart-/hipstershop.CartService/EmptyCartmethods:-POSTports:-"7070"
    • AServiceAccount per app in theasm-ingress andonlineboutiquenamespaces in order to have a unique identity per app evaluated asprincipal in theAuthorizationPolicies. Here is the example for thecartservice app:

      apiVersion:v1kind:ServiceAccountmetadata:name:cartservice
  9. View the Config Sync status for theRootSync and the twoRepoSyncs:

    gcloudalphaanthosconfigsyncrepodescribe

    The output is similar to:

    getting 3 RepoSync and RootSync from projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial[  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/root-sync/deploy-authorization-policies@main",    "status": "SYNCED"  },  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/ingress-gateway/authorization-policies@main",    "status": "SYNCED"  },  {    "clusters": [      "projects/PROJECT_ID/locations/global/memberships/asm-acm-tutorial"    ],    "commit": "7d15d49af13c44aa531a4565b2277ddcf8b81884",    "errors": [],    "source": "https://github.com/GoogleCloudPlatform/anthos-config-management-samples//asm-acm-tutorial/online-boutique/authorization-policies@main",    "status": "SYNCED"  }]

    If you seestatus: RECONCILING instead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describe again.

    To only view the information of one repository you can use the--sync-nameand--sync-namespace flags. And to view in detail the managed resources,you can add the--managed-resources flag.For more information, seeView Config Sync status across multiple clusters.

  10. Visit the Online Boutique app again from your browser:

    echohttp://${EXTERNAL_IP}

    If you wait a few minutes, you should now see the website working successfully again as expected.

View the status of GKE Enterprise security features

You can view the status of GKE Enterprise security features, including authenticationand authorization policies, in the Google Cloud console.

  1. In the Google Cloud console, go to theGKE Enterprise Security page.

    Go to GKE Enterprise Security

    ThePolicy Summary displays the status of application security,including Service access control (AuthorizationPolicies) and mTLS.

  2. ClickPolicy Audit to view workload policy statuses for the cluster andboth namespaces (asm-ingress andonlineboutique).

    TheService access control andmTLS status cards provide ahigh-level overview.

    High-level overview of service access control and mTLS status

    TheWorkloads list shows the Service access control and mTLS status ofeach workload.

    Detailed list of each workload and its service access control and mTLS status

You now have secured your cluster and your mesh with Policy Controller andConfig Sync.

Clean up

To avoid incurring charges to your Google Cloud account for the resources used in this tutorial, either delete the project that contains the resources, or keep the project and delete the individual resources.

Delete the project

    Caution: Deleting a project has the following effects:
    • Everything in the project is deleted. If you used an existing project for the tasks in this document, when you delete it, you also delete any other work you've done in the project.
    • Custom project IDs are lost. When you created this project, you might have created a custom project ID that you want to use in the future. To preserve the URLs that use the project ID, such as anappspot.com URL, delete selected resources inside the project instead of deleting the whole project.

    If you plan to explore multiple architectures, tutorials, or quickstarts, reusing projects can help you avoid exceeding project quota limits.

    Delete a Google Cloud project:

    gcloud projects deletePROJECT_ID

Delete individual resources

To delete the individual resources:

  1. Unregister your cluster from the fleet:

  2. Delete your cluster:

  3. Delete the files that you created:

    rm-r~/asm-acm-tutorial-dir

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.