An AKS cluster that still issues certificate-based admin kubeconfigs, lets every pod reach the node's managed identity, or relies on deprecated pod-managed identity has an access model that bypasses Microsoft Entra ID entirely. Microsoft calls the --admin credential a "non-auditable backdoor", and it exists even on clusters with Entra integration and RBAC enabled. This guide covers the AKS-specific controls that put all cluster and workload access behind Entra: managed Entra integration, disabling local accounts, Azure RBAC for Kubernetes authorisation, the kubeconfig roles, Microsoft Entra Workload ID, the cluster and kubelet identities, IMDS restriction and the logs that prove it works. Generic Kubernetes service account and federation material is in the Kubernetes NHI Security Guide and the Workload Identity Federation Guide; this page goes deeper on AKS only. It is for platform engineers, Azure security teams and auditors.
Key takeaways
- Enable managed Entra integration, then disable local accounts. Integration cannot be undone once on;
--disable-local-accountsremoves the static admin path, and on existing clusters you must rotate cluster certificates afterwards to revoke credentials already handed out. - Use Azure RBAC for Kubernetes authorisation where you want central control. Four built-in data-plane roles, assignable at cluster or namespace scope, replace per-cluster RoleBindings and can be governed with PIM. Writer and Admin can still reach every service account's permissions in their namespace.
- Control-plane Azure roles are cluster access.
listClusterAdminCredentialand the ability to re-enable local accounts sit on the Azure resource, so Contributor-level rights on the cluster are a path to cluster-admin. - Workload ID replaces pod-managed identity. The open source pod-managed identity was deprecated on 24 October 2022 and its add-on supported only until September 2025. Each federated credential should bind one managed identity to exactly one service account.
- Close the kubelet identity path. By default every pod can reach IMDS at
169.254.169.254. IMDS restriction (preview) blocks non-host-network pods but conflicts with several add-ons, so plan around it.
How identity and access work in AKS
AKS has two authorisation layers that are easy to conflate. The Azure Resource Manager (control plane) layer governs the Microsoft.ContainerService/managedClusters resource: who can update the cluster, download kubeconfigs or change identity settings. The Kubernetes (data plane) layer governs what an authenticated identity can do against the API server, using either Kubernetes RBAC or Azure RBAC data actions. Workloads then reach Azure through managed identities.
| Identity | Purpose | Default | Hardening concern |
|---|---|---|---|
| Entra users, groups and service principals | Human and pipeline access to the API server through kubelogin | Requires managed Entra integration | Admin group membership; Conditional Access; PIM |
Local accounts (clusterAdmin, clusterUser certificates) | Certificate-based kubeconfig, bypasses Entra | Enabled unless disabled | Non-auditable, long-lived; must be disabled and certificates rotated |
| Cluster (control plane) identity | Manages load balancers, public IPs, autoscaler, CSI drivers | System-assigned; Contributor on the node resource group | Over-broad if you bring your own VNet and grant wider roles |
Kubelet identity (<cluster>-agentpool) | Pulls images from Azure Container Registry | User-assigned in the node resource group, no default permissions | Reachable by pods through IMDS; often given extra roles for convenience |
| Workload identities | Pods accessing Azure services | Workload ID with user-assigned managed identity or app registration | Federated credential subject scope; shared identities |
Prefer managed identities over application service principals for the cluster identity; Microsoft's guidance recommends managed identity for security and ease of use, and existing clusters can be updated. Wider Azure role design is covered in the Azure RBAC and Service Principals Guide and the Azure Managed Identities Security Guide.
Admin roles and privileged access
Entra integration and local accounts
Managed Entra integration (az aks create or update with --enable-aad, --aad-admin-group-object-ids and --aad-tenant-id) lets AKS manage the client and server applications for you. Members of the admin groups get cluster-admin. The same command migrates clusters from legacy Entra integration; on Free tier clusters the API server may be briefly unavailable, so schedule it. From Kubernetes 1.24 kubeconfigs use the kubelogin exec plugin automatically; pipelines need a non-interactive kubelogin mode (service principal, managed identity or workload identity) rather than an admin certificate.
Then disable local accounts with az aks update --disable-local-accounts, which sets properties.disableLocalAccounts to true. Verify with az aks get-credentials --admin, which should fail with "Getting static credential isn't allowed because this cluster is set to disable local accounts." On a cluster where local accounts were ever used, rotate the cluster certificates (az aks rotate-certs) so certificates already in circulation stop working.
Kubeconfig roles and control-plane rights
| Azure role or right | Action | Effect |
|---|---|---|
| Azure Kubernetes Service Cluster User Role | listClusterUserCredential/action | On Entra clusters, a kubeconfig with no credentials that prompts sign-in; access then follows the user's Entra and RBAC grants. On non-Entra clusters it equals admin |
| Azure Kubernetes Service Cluster Admin Role | listClusterAdminCredential/action | Downloads the clusterAdmin certificate kubeconfig (blocked once local accounts are disabled) |
| Azure Kubernetes Service Contributor, Contributor, Owner | managedClusters/write | Can change admin groups, re-enable local accounts, change identity and network settings |
The write permission is the real root of the cluster. Microsoft's break-glass procedure for an Entra outage is to re-enable local accounts, fetch the admin kubeconfig and disable them again, and it needs only Azure Kubernetes Service Contributor. Treat that role as privileged, make it eligible through Privileged Identity Management rather than permanently assigned, and alert on every managedClusters/write that touches disableLocalAccounts or aadProfile. If only the admin group is wrong, fix it with az aks update --aad-admin-group-object-ids instead of using break-glass. The Storm-2949 Azure attack shows the general pattern: custom Azure RBAC roles held by one compromised Entra account were enough to pull publishing credentials and Key Vault secrets. Management-plane roles over an AKS cluster deserve the same scrutiny.
Azure RBAC for Kubernetes authorisation
With --enable-azure-rbac (default on AKS Automatic), Kubernetes authorisation decisions for Entra identities come from Azure role assignments. The Entra tenant must be the subscription's tenant, and assignments can take up to five minutes to propagate.
| Built-in role | Grants | Escalation note |
|---|---|---|
| Azure Kubernetes Service RBAC Reader | Read most namespaced objects; no Secrets, Roles or RoleBindings | Safe default for developers and support |
| Azure Kubernetes Service RBAC Writer | Read and write most namespaced objects; no Roles or RoleBindings | Reads Secrets and can run pods as any service account in the namespace, so gains every service account's API access and federated Azure identity |
| Azure Kubernetes Service RBAC Admin | Namespace admin including Roles and RoleBindings; no quota or namespace writes | Can grant itself anything within the namespace |
| Azure Kubernetes Service RBAC Cluster Admin | Every action on every resource | Break-glass and platform automation only, through PIM |
Scope namespace assignments to <cluster resource ID>/namespaces/<name>. Custom roles use DataActions such as Microsoft.ContainerService/managedClusters/apps/deployments/read; CRD filtering by group and kind needs an ABAC condition that is still in preview.
Choosing between Azure RBAC and Kubernetes RBAC: Azure RBAC suits organisations that want one access review, PIM activation and Entra group governance across many clusters, and small teams who do not want to maintain RoleBindings. Kubernetes RBAC with Entra groups as subjects suits GitOps teams who keep authorisation in version control with the workloads, and is needed for fine-grained rules the built-in roles do not express. Both can run together: Azure RBAC for humans, Kubernetes RBAC for service accounts. Whichever you choose, review both sources, because a ClusterRoleBinding to an Entra group grants access that no Azure assignment report will show. See the Kubernetes RBAC Guide.
Integrations, API tokens and service accounts
Microsoft Entra Workload ID on AKS
Enable the OIDC issuer and Workload ID with --enable-oidc-issuer --enable-workload-identity. The issuer URL has the form https://{region}.oic.prod-aks.azure.com/{tenant_id}/{uuid}/, where the UUID is an immutable per-cluster key. The exchange mechanics are in the Workload Identity Federation Guide; the AKS-specific hardening points are:
- Subject: create each federated credential with
--subject system:serviceaccount:<namespace>:<name>for one service account, and keep the default audienceapi://AzureADTokenExchange. - Limit: a managed identity holds at most 20 federated credentials. Hitting it is a sign one identity is being shared across too many workloads or clusters.
- Opt-in label: only pods labelled
azure.workload.identity/use: "true"are mutated by the webhook; the service account carriesazure.workload.identity/client-id. - Token lifetime:
azure.workload.identity/service-account-token-expirationdefaults to 3600 seconds (range 3600 to 86400). Leave it at the default; the Entra access token obtained lasts up to 24 hours regardless. - Token file: read the path from
AZURE_FEDERATED_TOKEN_FILEon every exchange; Kubernetes refreshes the file in place. - Who can edit federated credentials: rights to write
federatedIdentityCredentialson a managed identity let someone point it at their own cluster's service account. Restrict that permission as tightly as role assignments. - Unsupported: the virtual nodes add-on does not support Workload ID.
Migrating from pod-managed identity
Pod-managed identity (the NMI DaemonSet intercepting IMDS calls) was deprecated on 24 October 2022 and the managed add-on's support ended in September 2025. Any cluster still running it depends on unsupported components. Microsoft documents a short-term migration sidecar for applications that cannot move to a current Azure Identity library; plan to remove it.
Cluster and kubelet identities
- Kubelet identity: give it only
AcrPull(or Container Registry Repository Reader in ABAC repository mode) on the specific registries. Never add Key Vault, Storage or Contributor roles to it for application convenience: without IMDS restriction any pod on the node can request its tokens (ATT&CK T1552.005). - Bring-your-own kubelet identity outside the node resource group requires Managed Identity Operator for the control plane identity, scoped to that kubelet identity only.
- Cluster identity: scope extra roles (Network Contributor on a subnet for AGIC, for example) to the specific resource, not the subscription.
IMDS restriction (preview)
--enable-imds-restriction (feature flag IMDSRestrictionPreview, OIDC issuer required) blocks non-host-network pods from 169.254.169.254; host-network pods and node processes keep access. Nodes must be reimaged (az aks upgrade --node-image-only) after enabling. It is preview and not for production SLAs, Windows node pools are unsupported, and it cannot coexist with Azure Policy, Container Insights, AGIC, virtual nodes, application routing or extensions such as Flux and Dapr. Where you cannot enable it, compensate with a network policy denying egress to 169.254.169.254/32 from application namespaces, keep the kubelet identity minimal, and block hostNetwork pods through admission control (see the Kubernetes Admission Control Guide). Microsoft also advises disabling node SSH, because the iptables rules can be altered from the node.
Logging and detection
AKS resource logs are off until you create a diagnostic setting. Use resource-specific mode so audit data lands in dedicated tables.
| Source | Watch for | Why |
|---|---|---|
kube-audit-admin (table AKSAuditAdmin) | ClusterRoleBindings to cluster-admin, new RoleBindings to Entra groups, serviceaccounts/token creation, pods/exec, annotation of service accounts with a new client ID | Kubernetes-side escalation (T1098.006) at lower cost than kube-audit |
kube-audit (table AKSAudit) | Secret get and list by unexpected identities; discovery sweeps (T1613) | Includes read events; high volume, consider the Basic logs tier |
guard | Entra authentication and Azure RBAC authorisation decisions, including denials | Ties API calls to Entra object IDs |
| Azure Activity Log | listClusterAdminCredential/action, managedClusters/write changing local accounts or admin groups, role assignments at cluster scope, federatedIdentityCredentials/write | Control-plane paths to cluster-admin and workload identity hijack (T1078.004) |
| Entra sign-in logs (managed identity and service principal) | Workload identity token use from unexpected IP ranges or outside the cluster's egress | Token theft and replay (T1528) |
Metrics:
- Percentage of clusters with
disableLocalAccounts = true(target 100%), checked with Azure Resource Graph. - Number of permanent (non-PIM) assignments of RBAC Cluster Admin, Cluster Admin Role or AKS Contributor per cluster.
- Percentage of pods calling Azure that use Workload ID rather than secrets or the kubelet identity.
- Number of federated credentials whose subject does not match an existing service account.
- Percentage of clusters sending
kube-audit-adminandguardto the SIEM. - Count of
listClusterAdminCredentialcalls (target zero outside documented break-glass).
Hardening baseline
- Assess: query Azure Resource Graph for each cluster's
aadProfile,disableLocalAccounts,enableAzureRbac, OIDC issuer and Workload ID status; export Azure role assignments at cluster scope and Kubernetes bindings; list pod-managed identity resources. - Turn on logging (
kube-audit-admin,guard,kube-apiserver) so you can see who uses admin credentials before you remove them. - Enable managed Entra integration with a dedicated admin group whose membership is PIM-eligible, not permanent. Point pipelines at
kubeloginwith a workload or managed identity. - Pilot disabling local accounts on one non-production cluster; watch Activity Log for
listClusterAdminCredentialcallers and move them. Rollback is--enable-local-accounts. Then disable everywhere and rotate certificates on existing clusters. - Decide the authorisation model (Azure RBAC, Kubernetes RBAC or both) and replace broad assignments with namespace-scoped Reader and Writer.
- Migrate workloads to Workload ID, one federated credential per service account, and retire pod-managed identity and client secrets.
- Reduce the kubelet identity to registry pull only, then block IMDS from pods by IMDS restriction where add-ons allow, or by network policy.
- Restrict the API server with a private cluster or authorised IP ranges, and apply Conditional Access policies to human sign-in for cluster access.
- Enforce with Azure Policy so new clusters cannot be created with local accounts enabled.
Framework mapping
| Control area | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 | CIS Controls v8.1 | ISO/IEC 27001:2022 Annex A |
|---|---|---|---|---|
| Entra integration, local accounts disabled | IA-2, AC-2 | PR.AA-01 | Control 5, Control 6 | A.5.16, A.8.5 |
| Azure RBAC, PIM, kubeconfig roles | AC-6 | PR.AA-05 | Control 6 | A.5.18, A.8.2 |
| Workload ID, kubelet identity minimised | IA-5, IA-9 | PR.AA-01 | Control 6 | A.5.17 |
| kube-audit-admin, guard, Activity Log | AU-2, AU-6 | DE.CM-03 | Control 8 | A.8.15 |
Common misconfigurations
- Entra enabled, local accounts left on. Teams assume integration closed the admin path; anyone with Cluster Admin Role or Contributor can still download a certificate kubeconfig that appears in no Entra sign-in log.
- Local accounts disabled without certificate rotation. Kubeconfigs downloaded before the change keep working until the cluster certificates are rotated.
- Writer treated as low risk. Azure Kubernetes Service RBAC Writer can run pods as any service account in its namespace, including those federated to managed identities with Key Vault or Storage access.
- Kubelet identity used as an application identity. Granting it Key Vault Secrets User or Storage roles hands those rights to every pod on the node pool.
- One managed identity, many federated credentials. A single identity trusted by service accounts in several clusters and namespaces means a compromise of any one namespace reaches all the data that identity can read.
- Pod-managed identity still running. Unsupported since September 2025 and dependent on IMDS interception; migrate to Workload ID.
Practitioner checklist
- Managed Entra integration is enabled on every cluster with a PIM-governed admin group.
disableLocalAccountsis true everywhere, certificates were rotated afterwards, and Azure Policy blocks new clusters with local accounts.- Cluster Admin Role, RBAC Cluster Admin and AKS Contributor are eligible through PIM, not permanently assigned; break-glass is documented and alerted.
- Human access uses namespace-scoped RBAC Reader or Writer, and Writer grants are reviewed alongside the service accounts in that namespace.
- Every Azure-calling workload uses Workload ID with one federated credential per service account and the default audience.
- Pod-managed identity, client secrets in Kubernetes Secrets and application roles on the kubelet identity are gone.
- Pods cannot reach IMDS (IMDS restriction or egress network policy), and
hostNetworkpods are blocked outside system namespaces. kube-audit-admin,guardand the Activity Log reach the SIEM with alerts onlistClusterAdminCredentialand local-account changes.- The API server is private or limited to authorised IP ranges.
Standards and references
- Microsoft Learn: Enable Microsoft Entra ID authentication for AKS
- Microsoft Learn: Manage local accounts with AKS-managed Microsoft Entra integration
- Microsoft Learn: Use Azure RBAC for Kubernetes authorisation
- Microsoft Learn: Control access to cluster configuration files
- Microsoft Learn: Microsoft Entra Workload ID with AKS
- Microsoft Learn: Use a managed identity in AKS
- Microsoft Learn: Block pod access to IMDS (preview)
- Microsoft Learn: Monitor Azure Kubernetes Service
Related NHI Mgmt Group resources: Kubernetes NHI Security Guide · Workload Identity Federation Guide · EKS Identity Hardening Guide · GKE Identity Hardening Guide · Azure Managed Identities Security Guide