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 apps for their online store with Cloud Service Mesh, a suite of tools that helps you monitor and manage a reliable service mesh. You are responsible for ensuring that your mesh and apps are secure.
You can prevent misconfiguration and automatically validate your Cloud Service Mesh policies by using Policy Controller and Config Sync. Policy Controller enables the enforcement of fully programmable policies for your clusters. Policy Controller also comes with a default library of constraint templates that you can use with the Cloud Service Mesh security bundle to audit the compliance of your mesh security vulnerabilities and best practices. Config Sync continuously reconciles the state of clusters with a central set of Kubernetes declarative configuration files. Using Policy Controller and Config Sync together enables you to continuously enforce constraints on 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 manage and protect an ingress gateway and the Online Boutique sample apps that you use in this tutorial:
Objectives
- Create a Google Kubernetes Engine (GKE) cluster and register the cluster to a fleet.
- Install Policy Controller, Config Sync, and Cloud Service Mesh on a cluster.
- Configure Config Sync to sync multiple repositories
- Apply best practices to deploy configs, apps and Istio resources with Config Sync.
- Deploy cluster configs, the Online Boutique sample apps, and an ingress gateway with Config Sync.
- Leverage the
Cloud Service Mesh policy bundle
of 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 the Cloud Service Mesh, Config Sync, and Policy Controller.
To generate a cost estimate based on your projected usage,
use the pricing calculator.
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, see Clean up.
Before you begin
-
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
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Prepare your environment
In this section, you prepare your environment so that you can install Cloud Service Mesh, Policy Controller, and Config Sync:
-
In the Google Cloud console, activate Cloud Shell.
Upgrade to the latest version of the Google Cloud CLI:
gcloud components updateTo store the files that you create in this tutorial, create a directory:
mkdir ~/asm-acm-tutorial-dirTo simplify the remainder of the tutorial, create the following environment variables:
PROJECT_ID=PROJECT_ID gcloud config set project $PROJECT_ID CLUSTER=asm-acm-tutorial CLUSTER_ZONE=us-east4-a MEMBERSHIP=asm-acm-tutorial PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format='get(projectNumber)')Replace
PROJECT_IDwith the project ID that you want to use for this tutorial.If you're asked to authorize Cloud Shell, click Authorize to complete the operation.
Enable the APIs that you need for this tutorial:
gcloud
gcloud services enable \ mesh.googleapis.com \ anthos.googleapis.comConfig Connector
This tutorial includes Config Connector resources. You can use these resources to complete the same tasks that you complete in the
gcloudtab. To utilize these resources, install Config Connector and apply the resources in the way that works best for your environment.Use the following
Servicesmanifest:apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1 kind: Service metadata: annotations: cnrm.cloud.google.com/deletion-policy: "abandon" cnrm.cloud.google.com/disable-dependent-services: "false" name: mesh.googleapis.com spec: resourceID: mesh.googleapis.com projectRef: external: PROJECT_ID --- apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1 kind: Service metadata: annotations: cnrm.cloud.google.com/deletion-policy: "abandon" cnrm.cloud.google.com/disable-dependent-services: "false" name: anthos.googleapis.com spec: resourceID: anthos.googleapis.com projectRef: external: PROJECT_IDThis operation can take over one minute to complete.
Set up a GKE cluster
In this section, you create a GKE cluster and then register it to a fleet. Fleets are a Google Cloud concept for logically organizing clusters and other resources, letting you use and manage multi-cluster capabilities and apply consistent policies across your systems.
The cluster that you create in this section is the cluster that you install Cloud Service Mesh, Policy Controller, and Config Sync on. It's also the cluster where you deploy the Online Boutique sample apps.
To set up your cluster, complete the following steps:
Create a GKE cluster:
gcloud
gcloud container clusters create ${CLUSTER} \ --zone ${CLUSTER_ZONE} \ --machine-type=e2-standard-4 \ --num-nodes 4 \ --workload-pool ${PROJECT_ID}.svc.id.goog \ --labels mesh_id=proj-${PROJECT_NUMBER}Config Connector
Use the following
ContainerClusterandContainerNodePoolmanifests:apiVersion: container.cnrm.cloud.google.com/v1beta1 kind: ContainerNodePool metadata: annotations: cnrm.cloud.google.com/project-id: PROJECT_ID name: asm-acm-tutorial spec: clusterRef: name: asm-acm-tutorial location: us-east4-a nodeConfig: machineType: e2-standard-4 nodeCount: 4 --- apiVersion: container.cnrm.cloud.google.com/v1beta1 kind: ContainerCluster metadata: annotations: cnrm.cloud.google.com/project-id: PROJECT_ID cnrm.cloud.google.com/remove-default-node-pool: "true" labels: mesh_id: proj-PROJECT_NUMBER name: asm-acm-tutorial spec: location: us-east4-a initialNodeCount: 1 workloadIdentityConfig: workloadPool: PROJECT_ID.svc.id.googReplace
PROJECT_NUMBERby the value of thePROJECT_NUMBERenvironment variable retrieved earlier.This operation can take over five minutes to complete.
To ensure the successful creation of the GKE cluster, describe its status:
gcloud container clusters list \ --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 STATUS asm-acm-tutorial us-east4-a 1.23.12-gke.100 35.186.179.30 e2-standard-4 1.23.12-gke.100 3 RUNNINGConnect to the GKE cluster:
gcloud container clusters get-credentials ${CLUSTER} \ --zone ${CLUSTER_ZONE} \ --project ${PROJECT_ID}Register your cluster to a fleet:
gcloud
gcloud container fleet memberships register ${MEMBERSHIP} \ --project ${PROJECT_ID} \ --gke-cluster ${CLUSTER_ZONE}/${CLUSTER} \ --enable-workload-identityThe 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 following
GKEHubMembershipmanifest:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubMembership metadata: annotations: cnrm.cloud.google.com/project-id: PROJECT_ID name: asm-acm-tutorial spec: location: global authority: issuer: https://container.googleapis.com/v1/projects/PROJECT_ID/locations/us-east4-a/clusters/asm-acm-tutorial endpoint: gkeCluster: resourceRef: name: asm-acm-tutorialTo ensure the successful registration of the GKE cluster, describe its status:
gcloud container fleet memberships listThe output is similar to the following:
NAME EXTERNAL_ID LOCATION asm-acm-tutorial 0e12258c-8831-4d81-b5c0-5e7099a468cc global
Explore the repositories
In the following installation section, you apply a
manifest acm-config.yaml file. This manifest configures
your cluster to sync from the
asm-acm-tutorial folder
of the sample repository. This folder contains all
the configuration files that you need to complete the remainder of the tutorial.
To simplify this tutorial, you use sed commands to update the
acm-config.yaml. With the acm-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 securing
your clusters, mesh, and applications without repeatedly manipulating the files
and repeatedly running git commands.
To utilize Config Sync's ability to sync 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 system namespaces such asistio-system.ingress-gateway, as a firstRepoSync, contains all the resources needed to deploy an ingress gateway and progressively secure it throughout this tutorial.online-boutique, as a secondRepoSync, contains all the resources needed to deploy the Online 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 install
Config Sync, Policy Controller, and Cloud Service Mesh on your cluster and
configure your cluster to sync from the configs of the default RootSync:
Enable the
ConfigManagementoperator, which manages Config Sync and Policy Controller:gcloud
gcloud beta container fleet config-management enableConfig Connector
Use the following
GKEHubFeaturemanifest:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubFeature metadata: name: configmanagement spec: projectRef: external: PROJECT_ID location: global resourceID: configmanagementEnable Cloud Service Mesh in your fleet.
gcloud
gcloud container fleet mesh enableConfig Connector
Use the following
GKEHubFeaturemanifest:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubFeature metadata: name: servicemesh spec: projectRef: external: PROJECT_ID location: global resourceID: servicemeshEnable the Cloud Service Mesh automatic management to let Google apply the recommended configuration of managed Cloud Service Mesh:
gcloud
gcloud container fleet mesh update \ --management automatic \ --memberships ${MEMBERSHIP}Config Connector
Use the following
GKEHubFeatureMembershipmanifest:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubFeatureMembership metadata: name: servicemesh-membership spec: projectRef: external: PROJECT_ID location: global membershipRef: name: asm-acm-tutorial featureRef: name: servicemesh mesh: management: MANAGEMENT_AUTOMATICEnable Config Sync and Policy Controller:
gcloud
Save the following manifest as
acm-config.yamlin the~/asm-acm-tutorial-dirdirectory:applySpecVersion: 1 spec: configSync: enabled: true policyDir: asm-acm-tutorial/root-sync/init secretType: none sourceFormat: unstructured syncRepo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples syncBranch: main policyController: enabled: true referentialRulesEnabled: true templateLibraryInstalled: trueTo learn more about the Google Cloud CLI config fields, see gcloud apply spec fields.
Apply the file:
gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlConfig Connector
Use the following
GKEHubFeatureMembershipmanifest:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubFeatureMembership metadata: name: configmanagement-membership spec: projectRef: external: PROJECT_ID location: global membershipRef: name: asm-acm-tutorial featureRef: name: configmanagement configmanagement: configSync: sourceFormat: unstructured git: policyDir: asm-acm-tutorial/root-sync/init secretType: none syncBranch: main syncRepo: https://github.com/GoogleCloudPlatform/anthos-config-management-samples policyController: enabled: true referentialRulesEnabled: true templateLibraryInstalled: truePolicy Controller and Config Sync are installed on your cluster. Next, Config Sync begins syncing all the configs of the default
RootSyncto your cluster. These configs install and configure the following key components:The
RepoSyncobjects that configure the Online Boutique apps and the ingress gateway are synced:Since the
RepoSyncreconcilers need additional permissions to create Istio resources, aClusterRoleand twoRoleBindingobjects to grant these permissions are also applied to your cluster:
To ensure the successful installation of Policy Controller and Config Sync, check the status:
gcloud beta container fleet config-management statusThe output is similar to the following:
Name: asm-acm-tutorial Status: SYNCED Last_Synced_Token: 4b3384d Sync_Branch: main Last_Synced_Time: 2022-05-04T21:32:58Z Policy_Controller: INSTALLEDIf you see
PENDINGorNOT_INSTALLEDin theStatusorPolicy_Controllerrows, wait a few minutes and rungcloud beta container fleet config-management statusagain.To ensure the successful installation of Cloud Service Mesh, describe its status:
gcloud container fleet mesh describeThe 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_AUTOMATIC membershipStates: 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/servicemesh resourceState: state: ACTIVE spec: {} state: state: {} updateTime: '2022-09-14T00:19:14.135113118Z'If you see
state.code: ERRORinstead ofstate.code: OK, wait a few minutes and rungcloud container fleet mesh describeagain. Before moving forward with the tutorial, you need to make sure that theservicemesh.controlPlaneManagement.details.codefield has theREVISION_READYvalue.
Deploy an ingress gateway and a sample application
In this section, you deploy the Online Boutique sample application and an ingress gateway to manage ingress traffic.
Deploy the Online Boutique sample application and the ingress gateway.
The following command uses
sedto update theacm-config.yamlmanifest to get Config Sync deploying the resources you need to deploy the ingress gateway and sample app.sed -i "s,root-sync/init,root-sync/deployments,g" ~/asm-acm-tutorial-dir/acm-config.yaml gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlNote this step can take a few minutes to complete.
View the Config Sync status for the
RootSyncand the twoRepoSyncs:gcloud alpha anthos config sync repo describeThe 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 see
status: RECONCILINGinstead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describeagain.To only view the information of one repository you can use the
--sync-nameand--sync-namespaceflags. To view the managed resources in detail, add the--managed-resourcesflag. For more information, see View Config Sync status across multiple clusters.Wait for the ingress gateway's public IP address to be provisioned:
until kubectl -n asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"; do : ; doneGet the ingress gateway's public IP address:
EXTERNAL_IP=$(kubectl get svc asm-ingressgateway -n asm-ingress -o jsonpath="{.status.loadBalancer.ingress[*].ip}")Visit the IP address from your browser to verify that the Online Boutique app has successfully deployed:
echo http://${EXTERNAL_IP}
Enforce policies to secure your mesh
In the following sections, you leverage Policy Controller to enforce policies from the Cloud Service Mesh policy bundle by creating constraints.
Enforce sidecar proxies injection
In this section you enforce policies to ensure that all workloads in the mesh have automatic sidecar injection enabled.
To enforce sidecar proxies injection, apply constraints.
The following command uses
sedto update theacm-config.yamlmanifest 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.yaml gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlThe preceding command deploys the following resources:
A
K8sRequiredLabelsConstraintthat requires anyNamespacein the mesh to contain the specific Cloud Service Mesh sidecar proxy injection label:An
AsmSidecarInjectionConstraintthat prohibits anyPodin the mesh from bypassing the Istio proxy sidecar injection:
View the Config Sync status for the
RootSync:gcloud alpha anthos config sync repo describe \ --sync-name root-sync \ --sync-namespace config-management-systemThe 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 see
status: RECONCILINGinstead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describeagain.Verify the
Constraintsare created:kubectl get constraintsIt can take a few minutes for Policy Controller to evaluate these constraints. If you don't see values in the
TOTAL-VIOLATIONScolumn, wait and runkubectl get constraintsagain.The output is similar to:
NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS podsidecarinjectionannotation.constraints.gatekeeper.sh/pod-sidecar-injection-annotation deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS k8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label deny 0Because we properly set up our
NamespacesandPods, there are0TOTAL-VIOLATIONSfor theseConstraints.To see these
Constraintsat work, try to create aNamespacein your cluster with neither alabelnor anannotation:kubectl create namespace testThe 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 is encrypted.
To enforce traffic encryption, apply constraints.
The following command uses
sedto update theacm-config.yamlmanifest 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.yaml gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlThe preceding command deploys the following resources:
An
AsmPeerAuthnMeshStrictMtlsConstraintwhich enforces the mesh-level mTLSPeerAuthenticationin theistio-systemnamespace:A referential constraint
Configin thegatekeeper-systemnamespace. This referential constraint enables theAsmPeerAuthnMeshStrictMtlsConstraintto reference another object in its definition (for example, searching for anyPeerAuthenticationin theistio-systemNamespace):A
DestinationRuleTLSEnabledConstraintwhich prohibits disabling TLS for all hosts and host subsets in IstioDestinationRules:An
AsmPeerAuthnStrictMtlsConstraintwhich enforces that allPeerAuthenticationscannot overwriteSTRICTmTLS:
View the Config Sync status for the
RootSync:gcloud alpha anthos config sync repo describe \ --sync-name root-sync \ --sync-namespace config-management-systemThe 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 see
status: RECONCILINGinstead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describeagain.Run the following command to get more information about the
PeerAuthenticationviolation:kubectl get asmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls -ojsonpath='{.status.violations}' | jqThe 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" } ]Fix the issue by deploying a
PeerAuthenticationin theistio-system. To prevent all your services in the mesh from accepting plaintext traffic, set a mesh-widePeerAuthenticationpolicy with the mTLS mode set toSTRICT. When you deploy the policy, the control plane automatically provisions TLS certificates so that workloads can authenticate with each other.The following command uses
sedto update theacm-config.yamlmanifest 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.yaml gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlThe preceding command deploys the following
STRICTmTLSPeerAuthenticationin theistio-systemnamespace. This applies mTLSSTRICTto the entire mesh:View the Config Sync status for the
RootSync:gcloud alpha anthos config sync repo describe \ --sync-name root-sync \ --sync-namespace config-management-systemThe 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 see
status: RECONCILINGinstead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describeagain.Verify the
Constraintsare created:kubectl get constraintsNote this can take a few minutes to get Policy Controller evaluating these
Constraints. Wait and run again thiskubectl get constraintscommand until you get values under theTOTAL-VIOLATIONScolumn for each line.The output is similar to:
NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS k8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS destinationruletlsenabled.constraints.gatekeeper.sh/destination-rule-tls-enabled deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmpeerauthnstrictmtls.constraints.gatekeeper.sh/peerauthentication-strict-mtls deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmsidecarinjection.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 mesh have granular access control.
To enforce granular access control, apply constraints.
The following command uses
sedto update theacm-config.yamlmanifest 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.yaml gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlThe preceding command deploys the following resources:
An
AsmAuthzPolicyDefaultDenyConstraintwhich enforces the mesh-level default denyAuthorizationPolicyin theistio-systemnamespace:An
AsmAuthzPolicyEnforceSourcePrincipalsConstraintwhich enforces that anyAuthorizationPoliciesis defining granular source principals (other than "*"). Only the ingress gateway in theasm-ingressnamespace is an exception to this rule in order to receive the traffic from the end-users and redirect the traffic to the Online Boutique'sfrontendapp.
View the Config Sync status for the
RootSync:gcloud alpha anthos config sync repo describe \ --sync-name root-sync \ --sync-namespace config-management-systemThe 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 see
status: RECONCILINGinstead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describeagain.Run the following command to get more information about the associated violation:
kubectl get asmauthzpolicydefaultdeny.constraints.gatekeeper.sh/default-deny-authorization-policies -ojsonpath='{.status.violations}' | jqThe 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" } ]Fix the issue by deploying the
AuthorizationPolicyin theistio-systemnamespace.The following command uses
sedto update theacm-config.yamlmanifest 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.yaml gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlThe preceding command deploys the following deny-all
AuthorizationPolicyin theistio-systemnamespace:View the Config Sync status for the
RootSync:gcloud alpha anthos config sync repo describe \ --sync-name root-sync \ --sync-namespace config-management-systemThe 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 see
status: RECONCILINGinstead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describeagain.Verify the
Constraintsare created:kubectl get constraintsNote this can take a few minutes to get Policy Controller evaluating these
Constraints. Wait and run again thiskubectl get constraintscommand until you get values under theTOTAL-VIOLATIONScolumn for each line.The output is similar to:
NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmsidecarinjection.constraints.gatekeeper.sh/pod-sidecar-injection-annotation deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS k8srequiredlabels.constraints.gatekeeper.sh/namespace-sidecar-injection-label deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmauthzpolicydefaultdeny.constraints.gatekeeper.sh/default-deny-authorization-policies deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmpeerauthnmeshstrictmtls.constraints.gatekeeper.sh/mesh-level-strict-mtls deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS destinationruletlsenabled.constraints.gatekeeper.sh/destination-rule-tls-enabled deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmpeerauthnstrictmtls.constraints.gatekeeper.sh/peerauthentication-strict-mtls deny 0 NAME ENFORCEMENT-ACTION TOTAL-VIOLATIONS asmauthzpolicyenforcesourceprincipals.constraints.gatekeeper.sh/authz-source-principals-not-all deny 0Visit the Online Boutique app from your browser:
echo http://${EXTERNAL_IP}You should receive the error:
RBAC: access deniedwhich confirms that the default denyAuthorizationPolicyis applied to the entire mesh.Fix this issue by deploying more granular
AuthorizationPoliciesin theasm-ingressandonlineboutiquenamespaces.The following command uses
sedto update theacm-config.yamlmanifest 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.yaml gcloud beta container fleet config-management apply \ --membership ${MEMBERSHIP} \ --config ~/asm-acm-tutorial-dir/acm-config.yamlThe preceding command deploys the following resources:
An
AuthorizationPolicyin theasm-ingressnamespace:An
AuthorizationPolicyper app in theonlineboutiquenamespace, here is the example for thecartserviceapp:A
ServiceAccountper app in theasm-ingressandonlineboutiquenamespaces in order to have a unique identity per app evaluated asprincipalin theAuthorizationPolicies. Here is the example for thecartserviceapp:
View the Config Sync status for the
RootSyncand the twoRepoSyncs:gcloud alpha anthos config sync repo describeThe 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 see
status: RECONCILINGinstead ofstatus: SYNCED, wait a few minutes and rungcloud alpha anthos config sync repo describeagain.To only view the information of one repository you can use the
--sync-nameand--sync-namespaceflags. And to view in detail the managed resources, you can add the--managed-resourcesflag. For more information, see View Config Sync status across multiple clusters.Visit the Online Boutique app again from your browser:
echo http://${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 authentication and authorization policies, in the Google Cloud console.
In the Google Cloud console, go to the GKE Enterprise Security page.
The Policy Summary displays the status of application security, including Service access control (
AuthorizationPolicies) and mTLS.Click Policy Audit to view workload policy statuses for the cluster and both namespaces (
asm-ingressandonlineboutique).The Service access control and mTLS status cards provide a high-level overview.

The Workloads list shows the Service access control and mTLS status of each workload.

You now have secured your cluster and your mesh with Policy Controller and Config 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
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
Delete individual resources
To delete the individual resources:
Unregister your cluster from the fleet:
gcloud
gcloud container fleet memberships unregister ${CLUSTER} \ --project=${PROJECT_ID} \ --gke-cluster=${CLUSTER_ZONE}/${CLUSTER}The output is similar to the following:
kubeconfig entry generated for asm-acm-tutorial. Waiting for membership to be deleted...done. Deleting membership CR in the cluster...done. Deleting namespace [gke-connect] in the cluster...done.Config Connector
kubectl delete -f ~/asm-acm-tutorial-dir/fleet-membership.yamlDelete your cluster:
gcloud
gcloud container clusters delete ${CLUSTER} \ --zone ${CLUSTER_ZONE}Press
ywhen prompted. This command can take over five minutes to complete.The output is similar to the following:
Deleting cluster asm-acm-tutorial...done. Deleted [https://container.googleapis.com/v1/projects/PROJECT_ID/zones/us-east4-a/clusters/asm-acm-tutorial].Config Connector
kubectl delete -f ~/asm-acm-tutorial-dir/container-cluster.yamlDelete the files that you created:
rm -r ~/asm-acm-tutorial-dir
What's next
- Discover Cloud Service Mesh security best practices.
- Learn more about the Cloud Service Mesh policy bundle.
- Explore the Policy Controller constraint template library.
- Explore reference architectures, diagrams, and best practices about Google Cloud. Take a look at our Cloud Architecture Center.