Join our Newsletter — 33% off our NHI Course
Home› Guides› Azure Kubernetes Service Security Hardening Guide: Network, Nodes,…
Guide Cloud Security

Azure Kubernetes Service Security Hardening Guide: Network, Nodes, Upgrades and Logging

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 13 min read
On this page

Most AKS clusters are created with a public API server, no network policy, no audit log collection and no cluster auto-upgrade, and each of those defaults stays in place until someone changes it. Identity gets most of the attention in AKS reviews, but a cluster with perfect Entra ID integration can still let every pod reach the instance metadata endpoint, run node images that are weeks behind on patches, and fall out of Kubernetes support. This guide covers the layers beyond identity: API server exposure, network policy and egress, node OS and Kubernetes upgrades, node access, workload guardrails with Azure Policy, image hygiene and logging. It is for platform engineers and security architects running AKS Standard clusters, and it aligns with the CIS Azure Kubernetes Service (AKS) Benchmark 2.0.0. For Entra integration, local accounts, workload identity and kubelet identity, read the AKS Identity Hardening Guide; for Kubernetes-wide controls, the Kubernetes Security Guide.

Key takeaways

  • Close the API server first. Use a private cluster or API Server VNet Integration for production; if the endpoint must stay public, set authorized IP ranges (up to 200, or 2,000 with VNet Integration).
  • Pods talk to everything by default. AKS allows all pod traffic until a network policy engine is enabled and policies are applied. Cilium is Microsoft's recommended engine for new clusters, and Azure NPM on Linux is supported only until 30 September 2028.
  • Cluster auto-upgrade defaults to none. Set a cluster channel (stable or patch) and a node OS channel (NodeImage or SecurityPatch), each with its own maintenance window of at least four hours.
  • Block the metadata endpoint and node SSH. An egress policy denying 169.254.169.254 stops pods borrowing node credentials, and --ssh-access disabled removes the SSH service from nodes.
  • Collect kube-audit-admin, not everything. Full kube-audit is expensive; kube-audit-admin excludes get and list events and lands in the AKSAuditAdmin table.

How identity and access work in Azure Kubernetes Service

AKS has two access planes, and hardening has to cover both. This section is a short orientation only; the detailed identity controls are in the AKS Identity Hardening Guide.

PlaneWhat it controlsMain non-identity control
Azure Resource ManagerCreating, upgrading and reconfiguring the cluster and node pools; Run Command on the node scale setsAzure Policy on the resource, resource locks, Activity Log alerts
Kubernetes API serverWorkloads, secrets, RBAC objects, admissionNetwork exposure of the endpoint (private, VNet integrated or authorized ranges)
Node (VMSS instances)Container runtime, kubelet, host OSNode OS channel, SSH access mode, metadata endpoint blocking
Pod networkEast-west and egress trafficNetwork policy engine and egress through a firewall

Microsoft's operator guidance is to integrate Entra ID with Kubernetes RBAC and grant the minimum permissions, ideally scoped to a single namespace. Everything else on this page assumes that is done.

Admin roles and privileged access

API server exposure

OptionHow it worksStrengthsLimits
Public endpoint with authorized IP ranges--api-server-authorized-ip-ranges limits source IPs; AKS also adds the API server and Standard Load Balancer outbound IPs on createSimple; works with Microsoft-hosted CI agentsUp to 200 ranges; Standard Load Balancer only; az aks update replaces the list rather than appending
Private cluster--enable-private-cluster; API server reached through a Private Link private endpoint in your subnet; --disable-public-fqdn removes the public nameNo public control-plane exposureNeeds private DNS (privatelink.<region>.azmk8s.io); Microsoft-hosted Azure DevOps agents unsupported; authorized ranges do not apply to the private endpoint
API Server VNet IntegrationAPI server projected into a delegated subnet in your VNetPrivate traffic without Private Link; up to 2,000 authorized ranges; can enable private mode laterSubnet planning; check region support
  • Use 0.0.0.0/32 deliberately: as the authorized range it allows only the load balancer's outbound IP, so the cluster can manage itself while all external clients are blocked.
  • Remember the egress IP: with a firewall egress path, include the firewall's public frontend IP every time you update the range list, or nodes and in-cluster tooling lose access.
  • Treat ARM rights as cluster admin: anyone who can update the managed cluster can change network policy, upgrade channels or authorized ranges. Keep Azure Kubernetes Service Contributor and Owner on cluster resource groups eligible through PIM rather than permanent. See the JIT Access Guide.

Node access

  • SSH modes: --ssh-access takes localuser (key-based, the default), entraid or disabled. On an existing pool the change applies only after az aks nodepool upgrade --node-image-only, and new pools default back to SSH enabled, so set it on every pool. Microsoft labels these SSH options preview at the time of writing.
  • Debug without SSH: kubectl debug node still works when SSH is disabled, which makes it the controlled route for troubleshooting. Restrict who can create debug pods through Kubernetes RBAC.
  • Node resource group: the MC_ resource group holds the VM scale sets. Rights there allow az vmss run-command invoke on nodes, a path around Kubernetes RBAC entirely (ATT&CK T1651 Cloud Administration Command).

Integrations, API tokens and service accounts

The main credential risk beyond identity configuration is pods reaching credentials they should never see.

  • Block instance metadata: Microsoft recommends a NetworkPolicy in every user namespace that denies pod egress to 169.254.169.254/32, so a compromised pod cannot request tokens for the node's managed identity (ATT&CK T1552.005 Cloud Instance Metadata API). Workloads that need Azure access should use workload identity instead. See the Kubernetes NHI Security Guide.
  • Egress control: outbound type userDefinedRouting forces all node and pod egress through Azure Firewall (or another appliance) via a 0.0.0.0/0 route. Use the AzureKubernetesService FQDN tag for required AKS endpoints on TCP 443 and allow only the registries you actually use. Clusters using konnectivity do not need outbound TCP 9000 or UDP 1194.
  • CI/CD access: pipelines that deploy to a private cluster need self-hosted agents inside the network. Their service connections hold cluster-admin-level credentials; scope them per namespace. See the Azure DevOps Security Guide.
  • Secrets in images and manifests: credentials baked into images remain on every node that pulled them. The Tesla Kubernetes cryptojacking incident started with cloud credentials stored in a pod behind an unauthenticated console. Use the Secrets Store CSI driver with Key Vault. See the Kubernetes Secrets Security Guide.

Network policy engines

EngineWorks withCapabilityStatus and limits
CiliumAzure CNI Powered by Cilium (Linux)All Kubernetes policy types plus L7 and FQDN filtering; eBPF dataplaneRecommended for new deployments
Azure Network Policy ManagerAzure CNI (Linux)Kubernetes NetworkPolicy via iptables250 nodes and 20,000 pods; no IPv6; Windows support ends 30 September 2026, Linux 30 September 2028
Calico (AKS-managed)Azure CNI (Linux and Windows), kubenet (Linux)AKS supports only networking.k8s.io policiesDo not run alongside Calico Cloud or Enterprise; kubenet itself ends 31 March 2028

Choosing an engine is a cluster-creation decision in practice, because changing CNI or dataplane later is a migration. Once enabled, apply a default-deny ingress and egress policy per namespace and add explicit allows for DNS, the API server and named dependencies.

Logging and detection

Control-plane logs are off until you create a diagnostic setting on the cluster. Use resource-specific mode so logs land in dedicated tables.

CategoryTable (resource-specific)UseCost note
kube-audit-adminAKSAuditAdminAll audit events except get and list: RBAC changes, exec, secret writes, workload changesDefault choice for security monitoring
kube-auditAKSAuditEverything, including secret reads (get, list)Substantial cost; configure AKSAudit as Basic logs or enable only when needed
kube-apiserverAKSControlPlaneAPI server operational logsLow volume
guardAKSControlPlaneEntra ID and Azure RBAC authentication decisionsUseful for failed sign-in analysis
kube-controller-manager, kube-scheduler, cluster-autoscaler, cloud-controller-managerAKSControlPlaneOperational troubleshootingCollect for production clusters
  • What to alert on: pods/exec and pods/attach in production namespaces (ATT&CK T1609 Container Administration Command); privileged pods or hostPath mounts (T1610 Deploy Container, T1611 Escape to Host); ClusterRoleBinding creation; images from unapproved registries (T1525 Implant Internal Image); bursts of list calls across namespaces (T1613 Container and Resource Discovery).
  • Azure Activity Log: managed cluster writes that change network profile, API server access profile or auto-upgrade profile, and VMSS Run Command in the node resource group.
  • Runtime: Microsoft Defender for Containers adds a node sensor for runtime detection, agentless vulnerability assessment of nodes and images, and agentless analysis of Kubernetes audit logs. Alerts only cover activity after it is enabled. See the Microsoft Defender for Cloud Guide.
  • Node image version: the node label kubernetes.azure.com/node-image-version shows the base image and the security patch date, which is how you prove nodes are current.

Metrics that show it is working

  • API exposure: percentage of production clusters private or VNet integrated, or with authorized ranges set (target 100 percent).
  • Node patch age: days between today and the patch date in each pool's node image label (target under 14 days with SecurityPatch or NodeImage).
  • Version currency: clusters on a supported minor version with a non-none auto-upgrade channel.
  • Policy coverage: percentage of user namespaces with a default-deny policy and the metadata block applied.
  • Admission denials: Azure Policy deny events per week, trending down as teams fix manifests.

Hardening baseline

AreaSettingBaseline value
API server--enable-private-cluster or API Server VNet Integration; else --api-server-authorized-ip-rangesNo unrestricted public endpoint
Cluster upgrades--auto-upgrade-channelstable (or patch) with aksManagedAutoUpgradeSchedule window of 4 hours or more
Node OS upgrades--node-os-upgrade-channelNodeImage (default since API 2023-06-01) or SecurityPatch with aksManagedNodeOSUpgradeSchedule
Network policy--network-policy / Cilium dataplaneEngine enabled; default-deny per namespace
Egress--outbound-type userDefinedRoutingAll egress via firewall with the AzureKubernetesService FQDN tag
Node SSH--ssh-accessdisabled on every pool, debug with kubectl debug node
Workload guardrailsAzure Policy add-on"Kubernetes cluster pod security baseline standards for Linux-based workloads" initiative in deny
Image hygiene--enable-image-cleanerInterval 24 to 168 hours (CLI default one week)
LoggingDiagnostic setting, resource-specifickube-audit-admin, kube-apiserver, guard to Log Analytics or SIEM
Threat detectionDefender for ContainersSensor deployed on all clusters

Upgrade channels: decision guidance

  • Cluster channel: stable keeps you on N-1 minor with the latest patch and inside the N-2 support window; patch applies patches fastest without minor jumps; rapid suits non-production canaries. The default none leaves you exposed to the platform-initiated upgrade that AKS starts from 1 June 2027 for clusters left unsupported, which ignores maintenance windows and can override Pod Disruption Budgets.
  • Node OS channel: SecurityPatch ships security-only fixes faster and often live-patches without reimage, but is not supported on Windows pools and conflicts with an Azure Policy deny effect that requires customer-managed keys for OS disks. NodeImage is weekly, includes bug fixes and is the safe default.
  • Avoid the legacy node-image cluster channel: it is planned for deprecation and forces the node OS channel to NodeImage.
  • Small vs large estates: a small team can run one cluster on stable with a weekend window; large estates should run a canary cluster on rapid and stagger production windows, and pin a shared maintenance configuration.
  • OS SKU retirements: Azure Linux 2.0 receives no security updates since 30 November 2025 and its node images are removed on 31 October 2026; move to osSku AzureLinux3.

Phased rollout

  1. Assess: run the CIS AKS Benchmark and Defender for Containers recommendations against every cluster and record API exposure, network policy engine, upgrade channels and log settings.
  2. Turn on visibility: enable resource-specific diagnostic settings (kube-audit-admin first) and Defender sensors. This is non-disruptive.
  3. Guardrails in audit: assign the pod security baseline initiative with effect audit; assignments can take up to 20 minutes to sync. Fix violations for two to four weeks.
  4. Network: apply the metadata block and default-deny policies namespace by namespace, starting with non-production, then restrict the API server.
  5. Upgrades: set maintenance windows, then node OS and cluster channels; test on a canary pool first.
  6. Enforce: switch the initiative to deny and disable SSH on each pool with a node image upgrade.
  7. Roll back: policy effect back to audit, --network-policy unchanged but specific policies deleted, channel set to none, or --api-server-authorized-ip-ranges "" to clear ranges in an emergency.

Framework mapping

Control areaNIST SP 800-53 Rev 5NIST CSF 2.0CIS Controls v8.1ISO/IEC 27001:2022 Annex A
API server exposure, egress, network policySC-7, AC-17PR.IR-0112 Network Infrastructure Management, 13 Network Monitoring and DefenseA.8.20 Networks security, A.8.22 Segregation of networks
Upgrade channels and node patchingSI-2, RA-5PR.PS-02, ID.RA-017 Continuous Vulnerability ManagementA.8.8 Management of technical vulnerabilities
Pod security baseline, SSH disabledCM-6, CM-7, CM-2PR.PS-014 Secure ConfigurationA.8.9 Configuration management
Control-plane logs and DefenderAU-2, AU-6, SI-4DE.CM-09, DE.AE-028 Audit Log ManagementA.8.15 Logging, A.8.16 Monitoring activities

Common misconfigurations

  • Network policy engine with no policies: enabling Cilium or NPM changes nothing until policies exist. Clusters often pass a "network policy enabled" check while every pod can still reach every other pod and 169.254.169.254.
  • Authorized ranges overwritten: az aks update replaces the list, so an engineer adding their home IP can remove the firewall IP and break the cluster, or a wide range added "temporarily" never leaves.
  • Auto-upgrade left at none: clusters drift to N-3, then face a forced platform upgrade outside any maintenance window.
  • Unmanaged node patching without reboots: the Unmanaged channel applies OS updates nightly but does not reboot nodes, and new nodes start unpatched. Kernel fixes never take effect unless something like kured reboots them.
  • SSH disabled on one pool only: new pools come up with SSH enabled. Check every pool after scaling changes.
  • Full kube-audit with no budget: teams enable kube-audit, receive a large bill, and disable all audit logging. Start with kube-audit-admin.
  • Exempted namespaces that grow: each exemption from the pod security initiative is a place privileged pods can run. Review them quarterly.

Practitioner checklist

  • Make every production API server private, VNet integrated or restricted by authorized IP ranges, and review the range list monthly.
  • Enable a network policy engine (Cilium for new clusters), apply default-deny per namespace and block 169.254.169.254 from pods.
  • Route egress through a firewall with userDefinedRouting and allow only required FQDNs and registries.
  • Set the cluster auto-upgrade channel to stable or patch and the node OS channel to NodeImage or SecurityPatch, each with a 4-hour maintenance window.
  • Disable SSH on every node pool and use kubectl debug node for troubleshooting.
  • Assign the pod security baseline initiative, audit first, then deny.
  • Enable Image Cleaner and Defender for Containers on all clusters.
  • Collect kube-audit-admin, kube-apiserver and guard logs in resource-specific mode and alert on exec, privileged pods and RBAC changes.
  • Track node image patch age and cluster version currency as standing metrics.
  • Migrate off Azure Linux 2.0, Windows NPM and kubenet before their retirement dates.

Standards and references

Related NHI Mgmt Group resources: AKS Identity Hardening Guide · Kubernetes Security Guide · Kubernetes Admission Control Guide · Container Runtime Security Guide · GKE Security Hardening Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.