- Knowledge Base
- Microsoft Azure
- AKS
- Enable Trusted Access for AKS Clusters
Ensure that your Azure Kubernetes Service (AKS) clusters are configured to use Trusted Access role bindings to enable the Trusted Access feature. Enabling Trusted Access for AKS clusters enhances security by allowing services to securely access the Kubernetes API server without exposing the cluster to public networks or requiring admin privileges, all while simplifying identity management with system-assigned managed identities. With Trusted Access, you can connect to AKS clusters with various configurations, including private clusters, clusters with local accounts disabled, Microsoft Entra clusters, and clusters restricted by authorized IP ranges.
Many Azure cloud services that integrate with Azure Kubernetes Service (AKS) require access to the Kubernetes API server. Instead of granting these services admin privileges or exposing your AKS clusters to public network access, you can leverage the Trusted Access feature. Trusted Access provides secure access to the Kubernetes API server via dedicated Azure backends, eliminating the need for a private endpoint. Rather than using identities with Microsoft Entra permissions, it leverages your system-assigned managed identity for authentication with the managed services and applications you want to integrate with your AKS clusters.
Audit
To determine if Trusted Access is enabled for your Azure Kubernetes Service (AKS) clusters, perform the following operations:
Checking the Trusted Access feature status for AKS clusters using Microsoft Azure Portal (Azure Console) is not currently supported.Using Azure CLI
01 Run account list command (Windows/macOS/Linux) with custom output filters to list the IDs of the cloud subscriptions available in your Azure cloud account:
az account list --query '[*].id'
02 The command output should return the requested subscription identifiers (IDs):
[ "abcdabcd-1234-abcd-1234-abcdabcdabcd", "abcd1234-abcd-1234-abcd-abcd1234abcd" ]
03 Run account set command (Windows/macOS/Linux) with the ID of the Azure cloud subscription that you want to examine as the identifier parameter to set the selected subscription to be the current active subscription (the command does not produce an output):
az account set --subscription abcdabcd-1234-abcd-1234-abcdabcdabcd
04 Run aks list command (Windows/macOS/Linux) with custom query filters to list the name and the associated resource group for each Azure Kubernetes Service (AKS) cluster available in the selected Azure subscription:
az aks list --output table --query '[*].{name:name, resourceGroup:resourceGroup}'
05 The command output should return the requested AKS cluster names:
Name ResourceGroup ---------------------- ------------------------------ cc-data-mining-cluster cloud-shell-storage-westeurope cc-project5-cluster cloud-shell-storage-westeurope
06 Run aks trustedaccess rolebinding list command (Windows/macOS/Linux) with the name of the AKS cluster that you want to examine (and the associated resource group) as identifier parameters, to list the Trusted Access role bindings configured for the selected AKS cluster. A Trusted Access role binding in Azure Kubernetes Service (AKS) is a mechanism that grants specific permissions to system-assigned managed identities, allowing them to access AKS resources securely by linking them to Azure roles within the cluster. This ensures that only trusted resources have the necessary permissions to interact with the AKS cluster:
az aks trustedaccess rolebinding list --cluster-name cc-data-mining-cluster --resource-group cloud-shell-storage-westeurope
07 The command output should return the list with the Trusted Access role bindings available for the selected cluster:
[]
If the aks trustedaccess rolebinding list command output returns an empty array (i.e. []), as shown in the example above, there are no Trusted Access role bindings configured for your cluster, therefore, the Trusted Access feature is not enabled for the selected AKS cluster.
08 Repeat steps no. 6 and 7 for each AKS cluster provisioned within the selected Azure subscription.
09 Repeat steps no. 3 – 8 for each subscription created in your Microsoft Azure cloud account.
Remediation / Resolution
To enable and configure the Trusted Access feature for your Azure Kubernetes Service (AKS) clusters, perform the following operations:
To implement Trusted Access for Azure Kubernetes Service (AKS), your AKS clusters must use system-assigned managed identities.Enabling Trusted Access for AKS clusters using Microsoft Azure Portal (Azure Console) is not currently supported.
Using Azure CLI
01 Run account list command (Windows/macOS/Linux) with custom output filters to list the IDs of the cloud subscriptions available in your Azure cloud account:
az account list --query '[*].id'
02 The command output should return the requested subscription identifiers (IDs):
[ "abcdabcd-1234-abcd-1234-abcdabcdabcd", "abcd1234-abcd-1234-abcd-abcd1234abcd" ]
03 Run account set command (Windows/macOS/Linux) with the ID of the Azure cloud subscription that you want to examine as the identifier parameter to set the selected subscription to be the current active subscription (the command does not produce an output):
az account set --subscription abcdabcd-1234-abcd-1234-abcdabcdabcd
04 Run aks trustedaccess role list command (OSX/Linux/UNIX) to list the available Trusted Access roles for Azure Kubernetes Service (AKS). This helps in identifying the correct roles needed to configure and enable Trusted Access, ensuring secure and seamless integration between AKS and other Azure cloud services:
az aks trustedaccess role list --location westeurope
05 The command output should return the roles supported by Trusted Access:
[ { "name": "mlworkload", "rules": [ { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "services", "services/proxy" ], "verbs": [ "create", "get", "list", "patch", "update", "delete" ] } ], "sourceResourceType": "Microsoft.MachineLearningServices/workspaces" }, { "name": "backup-operator", "rules": [ { "apiGroups": [ "clusterbackup.dataprotection.microsoft.com" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "backups", "validateforbackups", "restores", "validateforrestores", "deletebackups" ], "verbs": [ "get", "list", "watch", "create", "update", "patch", "delete" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "configmaps" ], "verbs": [ "create", "get", "list", "patch", "update", "delete" ] } ], "sourceResourceType": "Microsoft.DataProtection/backupVaults" }, { "name": "inference-v1", "rules": [ { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "persistentvolumes", "persistentvolumeclaims" ], "verbs": [ "get", "list", "watch", "create", "update", "patch", "delete" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "persistentvolumeclaims/status" ], "verbs": [ "update", "patch" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "events" ], "verbs": [ "get", "list", "watch", "create", "update", "patch" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "nodes", "endpoints" ], "verbs": [ "get", "list", "watch" ] }, { "apiGroups": [ "storage.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "storageclasses" ], "verbs": [ "get", "list", "watch" ] }, { "apiGroups": [ "storage.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "csinodes" ], "verbs": [ "get", "list", "watch" ] }, { "apiGroups": [ "storage.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "csidrivers" ], "verbs": [ "create", "get", "list", "patch", "update", "delete" ] }, { "apiGroups": [ "coordination.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "leases" ], "verbs": [ "get", "list", "watch", "create", "update", "patch" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "namespaces", "pods", "pods/log", "pods/exec", "configmaps", "secrets", "services", "services/proxy", "services/status", "serviceaccounts" ], "verbs": [ "create", "get", "list", "patch", "update", "delete" ] }, { "apiGroups": [ "apps" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "deployments", "replicasets", "daemonsets", "deployments/scale", "deployments/status" ], "verbs": [ "create", "get", "list", "patch", "update", "delete" ] }, { "apiGroups": [ "batch" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "jobs" ], "verbs": [ "create", "get", "list" ] }, { "apiGroups": [ "rbac.authorization.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "clusterroles", "clusterrolebindings" ], "verbs": [ "create", "get", "list", "update", "patch" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "pods", "configmaps", "services" ], "verbs": [ "watch" ] }, { "apiGroups": [ "apps" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "deployments", "deployments/scale" ], "verbs": [ "watch" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "deployments", "deployments/scale" ], "verbs": [ "get", "list", "patch", "update", "watch" ] }, { "apiGroups": [ "apps" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "pods", "configmaps", "endpoints", "nodes", "services" ], "verbs": [ "get", "list", "watch" ] } ], "sourceResourceType": "Microsoft.MachineLearningServices/workspaces" }, { "name": "microsoft-defender-operator", "rules": [ { "apiGroups": [ "rbac.authorization.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "clusterrolebindings", "clusterroles", "rolebindings", "roles" ], "verbs": [ "get", "list" ] }, { "apiGroups": [ "batch" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "cronjobs", "jobs" ], "verbs": [ "get", "list" ] }, { "apiGroups": [ "networking.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "ingresses", "networkpolicies" ], "verbs": [ "get", "list" ] }, { "apiGroups": [ "apps" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "replicasets", "statefulsets", "daemonsets", "deployments" ], "verbs": [ "get", "list" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "namespaces", "nodes", "nodes/proxy", "pods", "services", "serviceaccounts" ], "verbs": [ "get", "list" ] } ], "sourceResourceType": "Microsoft.Security/pricings" }, { "name": "microsoft-defender-policy-operator", "rules": [ { "apiGroups": [ "apiextensions.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "customresourcedefinitions" ], "verbs": [ "get", "list", "create", "update", "delete" ] }, { "apiGroups": [ "defender.microsoft.com" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "*" ], "verbs": [ "get", "list", "create", "update", "delete" ] } ], "sourceResourceType": "Microsoft.Security/pricings" }, { "name": "microsoft-defender-network-policy-operator", "rules": [ { "apiGroups": [ "networking.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "networkpolicies" ], "verbs": [ "get", "list", "create", "update", "patch", "delete" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "pods" ], "verbs": [ "get", "list", "update" ] } ], "sourceResourceType": "Microsoft.Security/pricings" }, { "name": "mdc-response-operator", "rules": [ { "apiGroups": [ "networking.k8s.io" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "networkpolicies" ], "verbs": [ "get", "list", "create", "update", "patch", "delete" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "pods" ], "verbs": [ "get", "list", "update", "delete" ] }, { "apiGroups": [ "" ], "nonResourceUrLs": null, "resourceNames": null, "resources": [ "namespaces", "events" ], "verbs": [ "get", "list", "update" ] } ], "sourceResourceType": "Microsoft.Security/pricings" } ]
06 The role that you select depends on the Azure cloud services that you want to access your AKS cluster. After identifying the appropriate role to use, returned at the previous step, run the aks trustedaccess rolebinding create command (OSX/Linux/UNIX) to create a Trusted Access role binding for your AKS cluster. The role binding associates the selected role with the Azure cloud service. As an example, the following command request uses the mlworkload role for the Trusted Access role binding:
az aks trustedaccess rolebinding create --cluster-name cc-data-mining-cluster --resource-group cloud-shell-storage-westeurope --name tm-aks-role-binding --source-resource-id /subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.MachineLearningServices/workspaces/tm-project5-ml-workspace --roles Microsoft.MachineLearningServices/workspaces/mlworkload
07 The command output should return the information available for the new Trusted Access role binding:
{ "id": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.ContainerService/managedClusters/cc-data-mining-cluster/trustedAccessRoleBindings/tm-aks-role-binding", "name": "tm-aks-role-binding", "provisioningState": "Succeeded", "resourceGroup": "cloud-shell-storage-westeurope", "roles": [ "Microsoft.MachineLearningServices/workspaces/mlworkload" ], "sourceResourceId": "/subscriptions/abcdabcd-1234-abcd-1234-abcdabcdabcd/resourceGroups/cloud-shell-storage-westeurope/providers/Microsoft.MachineLearningServices/workspaces/tm-project5-ml-workspace", "systemData": null, "type": "Microsoft.ContainerService/managedClusters/trustedAccessRoleBindings" }
08 Repeat steps no. 6 and 6 for each AKS cluster that you want to configure, available within the selected Azure subscription.
09 Repeat steps no. 3 – 8 for each subscription created in your Microsoft Azure cloud account.
References
Related AKS rules
- Enable and Configure Node OS Auto-Upgrades (Security)
- Private Kubernetes Clusters (Security)
- Enable Federal Information Process Standard (FIPS) for AKS Cluster Node Pools (Security)
- Use Private Key Vaults for Encryption at Rest in Azure Kubernetes Service (AKS) (Security, operational-excellence, cost-optimisation)