Skip to main content
emnode
Compliance High severity MCSB NS-2

Microsoft Defender for Cloud · Azure Kubernetes Service

Kubernetes API server should be configured with restricted access

Written and reviewed by Emnode · Last reviewed

What does the recommendation "Kubernetes API server should be configured with restricted access" check?

Flags any AKS cluster whose public API server endpoint has no authorised IP ranges defined, meaning the Kubernetes control plane is reachable from any address on the internet. It checks only whether the 'authorizedIPRanges' list on the cluster's API server access profile is populated; it does not validate that the ranges you set are sensibly scoped, so a list as wide as 0.0.0.0/0 would technically satisfy it while leaving you wide open. It also does not apply to private clusters, where the API server has no public endpoint to restrict in the first place, and it says nothing about who can authenticate once a request reaches the server: it is a network reachability gate, not an authorisation control. Authentication, role bindings and audit logging remain entirely your responsibility.

Why does "Kubernetes API server should be configured with restricted access" matter?

An internet-exposed API server is the single highest-value target on a cluster: it is the door to every workload, secret and service account token AKS holds. Leaving it open invites continuous credential-stuffing, token-replay and exploitation of any unpatched control-plane CVE, and a successful authentication or bypass hands an attacker the whole cluster, including the ability to schedule containers, exfiltrate data and pivot deeper into the subscription. Restricting the endpoint to known operator, CI and bastion addresses shrinks that attack surface to a handful of trusted networks, so a leaked kubeconfig or stolen token is useless from anywhere else. For a regulated workload this is often the difference between a contained incident and a reportable breach, because the blast radius is bounded by who can even reach the door.

How do I fix "Kubernetes API server should be configured with restricted access"?

  1. Restrict the public endpoint with az CLI, supplying the comma-separated CIDRs that must reach the control plane (your egress NAT, CI runners and bastion): az aks update --resource-group <rg> --name <cluster> --api-server-authorized-ip-ranges 203.0.113.0/29,198.51.100.10/32. Use the network address of each CIDR; this requires the cluster to use the Standard Load Balancer SKU.
  2. Bake the safe default into infrastructure as code by setting properties.apiServerAccessProfile.authorizedIPRanges on the managed cluster resource in your Bicep or Terraform module so new clusters ship locked down.
  3. Enforce it at scale by assigning the built-in audit policy, looking the definition up by display name rather than hardcoding a GUID: pid=$(az policy definition list --query "[?displayName=='Authorized IP ranges should be defined on Kubernetes Services'].name" -o tsv); az policy assignment create --name aks-authorized-ip --policy "$pid" --scope <subscription-or-mg-scope>.

Remediation script · bash

RG=prod-rg
CLUSTER=prod-payments
SUB=$(az account show --query id -o tsv)

# 1. Restrict the API server to known networks (office egress + CI runners).
#    Use a private cluster instead where the public endpoint is not needed.
az aks update --resource-group "$RG" --name "$CLUSTER" \
  --api-server-authorized-ip-ranges "203.0.113.0/24,198.51.100.10/32"

# 2. Install the policy engine so guardrails are actually enforced in-cluster.
az provider register --namespace Microsoft.PolicyInsights
az aks enable-addons --resource-group "$RG" --name "$CLUSTER" --addons azure-policy

# For an Azure Arc-connected cluster, install the extension instead of the add-on:
# az k8s-extension create --name azurepolicy --extension-type Microsoft.PolicyInsights \
#   --cluster-type connectedClusters --cluster-name <arc-cluster> --resource-group "$RG"

# 3. Ratchet it shut: audit any future cluster missing the policy add-on.
#    Look the built-in policy up by its EXACT display name (never hardcode the GUID).
pid=$(az policy definition list \
  --query "[?displayName=='Azure Policy Add-on for Kubernetes service (AKS) should be installed and enabled on your clusters'].name" -o tsv)
az policy assignment create --name audit-aks-policy-addon \
  --policy "$pid" --scope "/subscriptions/$SUB"

Full walkthrough (console steps, edge cases and verification) in the lesson Harden the AKS control plane.

Is "Kubernetes API server should be configured with restricted access" a false positive?

A fully private AKS cluster, created with --enable-private-cluster, has no public API server endpoint, so authorised IP ranges do not apply and cannot be set. Such clusters already meet the intent of NS-2 because the control plane is only reachable over the virtual network through a private endpoint, which is a stronger posture than a restricted public endpoint, even though an account-level scan may still surface them as missing the IP range list. Treat this as an accepted exception rather than a finding to remediate.