From a2789b7fc6056f9856a1c09ee6e163f4af8314a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20De=20la=20Torre=20Vico?= Date: Mon, 19 Jan 2026 17:25:10 +0100 Subject: [PATCH] chore(azure): enhance metadata for `aks` service (#9611) Co-authored-by: Daniel Barranquero --- prowler/CHANGELOG.md | 1 + .../aks_cluster_rbac_enabled.metadata.json | 32 ++++++++++------- ...s_created_with_private_nodes.metadata.json | 31 +++++++++++------ ...sters_public_access_disabled.metadata.json | 34 ++++++++++++------- .../aks_network_policy_enabled.metadata.json | 32 ++++++++++------- 5 files changed, 83 insertions(+), 47 deletions(-) diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index f787d612ee..7ed8248095 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -55,6 +55,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Update AWS Cognito service metadata to new format [(#8853)](https://github.com/prowler-cloud/prowler/pull/8853) - Update AWS EC2 service metadata to new format [(#9549)](https://github.com/prowler-cloud/prowler/pull/9549) - Update Azure AI Search service metadata to new format [(#9087)](https://github.com/prowler-cloud/prowler/pull/9087) +- Update Azure AKS service metadata to new format [(#9611)](https://github.com/prowler-cloud/prowler/pull/9611) ### Security - `pyasn1` to v0.6.2 to address [CVE-2026-23490](https://nvd.nist.gov/vuln/detail/CVE-2026-23490) diff --git a/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json b/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json index bfd91d3a14..1b3fb3e3d8 100644 --- a/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json +++ b/prowler/providers/azure/services/aks/aks_cluster_rbac_enabled/aks_cluster_rbac_enabled.metadata.json @@ -1,30 +1,38 @@ { "Provider": "azure", "CheckID": "aks_cluster_rbac_enabled", - "CheckTitle": "Ensure AKS RBAC is enabled", + "CheckTitle": "AKS cluster has RBAC enabled", "CheckType": [], "ServiceName": "aks", "SubServiceName": "", "ResourceIdTemplate": "", - "Severity": "medium", - "ResourceType": "Microsoft.ContainerService/ManagedClusters", + "Severity": "high", + "ResourceType": "microsoft.containerservice/managedclusters", "ResourceGroup": "container", - "Description": "Azure Kubernetes Service (AKS) can be configured to use Azure Active Directory (AD) for user authentication. In this configuration, you sign in to an AKS cluster using an Azure AD authentication token. You can also configure Kubernetes role-based access control (Kubernetes RBAC) to limit access to cluster resources based a user's identity or group membership.", - "Risk": "Kubernetes RBAC and AKS help you secure your cluster access and provide only the minimum required permissions to developers and operators.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/aks/azure-ad-rbac?tabs=portal", + "Description": "**AKS clusters** with **Kubernetes RBAC** enforce authorization through roles and bindings mapped to identities and groups.\n\nThis evaluates whether the cluster has RBAC enabled to control access to namespaces and cluster-wide resources.", + "Risk": "Without **Kubernetes RBAC**, authorization becomes overly broad, weakening **least privilege**. Compromised credentials could read secrets, alter workloads, or delete services, impacting **confidentiality**, **integrity**, and **availability**, and enabling lateral movement across the cluster.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/security/benchmark/azure/security-controls-v2-privileged-access#pa-7-follow-just-enough-administration-least-privilege-principle", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AKS/enable-role-based-access-control-for-kubernetes-service.html#", + "https://learn.microsoft.com/en-us/azure/aks/azure-ad-rbac?tabs=portal" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AKS/enable-role-based-access-control-for-kubernetes-service.html#", - "Terraform": "https://docs.prowler.com/checks/azure/azure-kubernetes-policies/bc_azr_kubernetes_2#terraform" + "NativeIaC": "```bicep\n// Enable Kubernetes RBAC on AKS\nresource 'Microsoft.ContainerService/managedClusters@2024-05-01' = {\n name: ''\n location: ''\n properties: {\n enableRBAC: true // Critical: turns on Kubernetes RBAC to pass the check\n }\n}\n```", + "Other": "1. In Azure portal, go to Kubernetes services > Create (or edit your deployment template)\n2. On the Authentication tab, set Kubernetes RBAC to Enabled\n3. Review + Create to deploy (re-create the cluster if the setting can't be changed on an existing one)", + "Terraform": "```hcl\n# AKS with Kubernetes RBAC enabled\nresource \"azurerm_kubernetes_cluster\" \"\" {\n name = \"\"\n location = \"\"\n resource_group_name = \"\"\n dns_prefix = \"\"\n\n default_node_pool {\n name = \"default\"\n node_count = 1\n vm_size = \"Standard_DS2_v2\"\n }\n\n identity {\n type = \"SystemAssigned\"\n }\n\n role_based_access_control_enabled = true # Critical: enables Kubernetes RBAC to pass the check\n}\n```" }, "Recommendation": { - "Text": "", - "Url": "https://learn.microsoft.com/en-us/security/benchmark/azure/security-controls-v2-privileged-access#pa-7-follow-just-enough-administration-least-privilege-principle" + "Text": "Enable **Kubernetes RBAC** and design permissions with **least privilege**: scope roles to namespaces, grant access via groups, apply deny-by-default, and separate duties for admins and operators.\n\nIntegrate with **Microsoft Entra ID** and review/audit role bindings to maintain **defense in depth**.", + "Url": "https://hub.prowler.com/check/aks_cluster_rbac_enabled" } }, - "Categories": [], + "Categories": [ + "cluster-security", + "identity-access" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/aks/aks_clusters_created_with_private_nodes/aks_clusters_created_with_private_nodes.metadata.json b/prowler/providers/azure/services/aks/aks_clusters_created_with_private_nodes/aks_clusters_created_with_private_nodes.metadata.json index 38c5472bbd..c766ae8a70 100644 --- a/prowler/providers/azure/services/aks/aks_clusters_created_with_private_nodes/aks_clusters_created_with_private_nodes.metadata.json +++ b/prowler/providers/azure/services/aks/aks_clusters_created_with_private_nodes/aks_clusters_created_with_private_nodes.metadata.json @@ -1,30 +1,39 @@ { "Provider": "azure", "CheckID": "aks_clusters_created_with_private_nodes", - "CheckTitle": "Ensure clusters are created with Private Nodes", + "CheckTitle": "AKS cluster nodes do not have public IP addresses", "CheckType": [], "ServiceName": "aks", "SubServiceName": "", "ResourceIdTemplate": "", "Severity": "high", - "ResourceType": "Microsoft.ContainerService/ManagedClusters", + "ResourceType": "microsoft.containerservice/managedclusters", "ResourceGroup": "container", - "Description": "Disable public IP addresses for cluster nodes, so that they only have private IP addresses. Private Nodes are nodes with no public IP addresses.", - "Risk": "Disabling public IP addresses on cluster nodes restricts access to only internal networks, forcing attackers to obtain local network access before attempting to compromise the underlying Kubernetes hosts.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/aks/private-clusters", + "Description": "**AKS agent pools** use only private addressing, with node public IP assignment disabled (`enableNodePublicIP=false`). Clusters where any pool assigns a public IP to nodes are identified.", + "Risk": "**Public node IPs** expose worker VMs to Internet scanning and exploit attempts against OS or kubelet services. Successful compromise can lead to stolen secrets and images (**confidentiality**), workload tampering (**integrity**), and node/resource exhaustion via DDoS or cryptomining (**availability**).", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AKS/private-cluster-nodes.html", + "https://learn.microsoft.com/en-us/azure/aks/access-private-cluster", + "https://learn.microsoft.com/en-us/azure/aks/private-clusters" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "NativeIaC": "```bicep\n// AKS cluster with nodes not assigned public IPs\nresource mc '@Microsoft.ContainerService/managedClusters@2024-05-01' = {\n name: ''\n location: ''\n identity: {\n type: 'SystemAssigned'\n }\n properties: {\n dnsPrefix: ''\n agentPoolProfiles: [\n {\n name: 'nodepool1'\n count: 1\n vmSize: 'Standard_DS2_v2'\n enableNodePublicIP: false // CRITICAL: ensures nodes have no public IPs\n }\n ]\n }\n}\n```", + "Other": "1. In the Azure portal, go to Kubernetes services > > Node pools\n2. For any node pool showing Node public IP: Enabled, click Add node pool\n3. Create the new pool with the same size/count; set Node public IP to Disabled (or uncheck Enable node public IP)\n4. Wait until the new pool is Ready\n5. If replacing a system pool, set the new pool to Mode: System (or Set as default system pool)\n6. Delete the old node pool(s) that had Node public IP enabled\n7. Verify all node pools show Node public IP: Disabled", + "Terraform": "```hcl\n# AKS cluster with node public IPs disabled\nresource \"azurerm_kubernetes_cluster\" \"\" {\n name = \"\"\n location = \"\"\n resource_group_name = \"\"\n dns_prefix = \"\"\n\n default_node_pool {\n name = \"default\"\n node_count = 1\n vm_size = \"Standard_DS2_v2\"\n enable_node_public_ip = false # CRITICAL: ensures nodes have no public IPs\n }\n\n identity {\n type = \"SystemAssigned\"\n }\n}\n```" }, "Recommendation": { - "Text": "", - "Url": "https://learn.microsoft.com/en-us/azure/aks/access-private-cluster" + "Text": "Disable **public node IPs** on all agent pools (`enableNodePublicIP=false`) and route egress via a **NAT gateway** or **Azure Firewall**. Apply **least privilege** with NSGs blocking Internet ingress, use **private endpoints** and **bastion/VPN** for admin access, and adopt **defense in depth** with continuous hardening and monitoring.", + "Url": "https://hub.prowler.com/check/aks_clusters_created_with_private_nodes" } }, - "Categories": [], + "Categories": [ + "internet-exposed", + "trust-boundaries", + "cluster-security" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/aks/aks_clusters_public_access_disabled/aks_clusters_public_access_disabled.metadata.json b/prowler/providers/azure/services/aks/aks_clusters_public_access_disabled/aks_clusters_public_access_disabled.metadata.json index 908660055f..57c8f83600 100644 --- a/prowler/providers/azure/services/aks/aks_clusters_public_access_disabled/aks_clusters_public_access_disabled.metadata.json +++ b/prowler/providers/azure/services/aks/aks_clusters_public_access_disabled/aks_clusters_public_access_disabled.metadata.json @@ -1,30 +1,40 @@ { "Provider": "azure", "CheckID": "aks_clusters_public_access_disabled", - "CheckTitle": "Ensure clusters are created with Private Endpoint Enabled and Public Access Disabled", + "CheckTitle": "AKS cluster has a private endpoint and node public access is disabled", "CheckType": [], "ServiceName": "aks", "SubServiceName": "", "ResourceIdTemplate": "", "Severity": "high", - "ResourceType": "Microsoft.ContainerService/ManagedClusters", + "ResourceType": "microsoft.containerservice/managedclusters", "ResourceGroup": "container", - "Description": "Disable access to the Kubernetes API from outside the node network if it is not required.", - "Risk": "In a private cluster, the master node has two endpoints, a private and public endpoint. The private endpoint is the internal IP address of the master, behind an internal load balancer in the master's wirtual network. Nodes communicate with the master using the private endpoint. The public endpoint enables the Kubernetes API to be accessed from outside the master's virtual network. Although Kubernetes API requires an authorized token to perform sensitive actions, a vulnerability could potentially expose the Kubernetes publically with unrestricted access. Additionally, an attacker may be able to identify the current cluster and Kubernetes API version and determine whether it is vulnerable to an attack. Unless required, disabling public endpoint will help prevent such threats, and require the attacker to be on the master's virtual network to perform any attack on the Kubernetes API.", - "RelatedUrl": "https://learn.microsoft.com/en-us/azure/aks/private-clusters?tabs=azure-portal", + "Description": "**AKS clusters** expose a **private control plane FQDN** and agent pools have `enable_node_public_ip=false`.\n\nThe evaluation focuses on the presence of a private FQDN and the absence of public IPs on nodes.", + "Risk": "Exposed node IPs or a publicly reachable API increase attack surface, impacting **confidentiality** and **integrity**.\n- Internet scans reach kubelet, NodePort, or management agents\n- Exploits enable RCE and **lateral movement**\n- Metadata/secret theft leads to **credential compromise**\n\n**Availability** is at risk from DDoS on exposed endpoints.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/aks/private-clusters?tabs=azure-portal", + "https://learn.microsoft.com/en-us/azure/aks/access-private-cluster?tabs=azure-cli", + "https://support.icompaas.com/support/solutions/articles/62000234657-ensure-clusters-are-created-with-private-endpoint-enabled-and-public-access-disabled", + "https://docs.trendmicro.com/en-us/documentation/article/trend-vision-one-cis-aks17-542" + ], "Remediation": { "Code": { - "CLI": "az aks update -n -g --disable-public-fqdn", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "", + "NativeIaC": "```bicep\n// AKS cluster with private endpoint and nodes without public IPs\nresource aks 'Microsoft.ContainerService/managedClusters@2023-11-01' = {\n name: ''\n location: ''\n identity: {\n type: 'SystemAssigned'\n }\n properties: {\n dnsPrefix: 'dns'\n apiServerAccessProfile: {\n enablePrivateCluster: true // Critical: enables private cluster (private endpoint/FQDN)\n }\n agentPoolProfiles: [\n {\n name: 'nodepool1'\n count: 1\n vmSize: 'Standard_DS2_v2'\n enableNodePublicIP: false // Critical: disables public IPs on nodes\n }\n ]\n }\n}\n```", + "Other": "1. In the Azure portal, go to Azure Kubernetes Service and select your cluster\n2. Go to Networking > API server access\n3. Set Private cluster to Enabled and click Save\n4. Go to Node pools, open each pool, select Networking, set Public IP per node to Disabled, and Save\n5. Repeat step 4 for all node pools", + "Terraform": "```hcl\n# AKS cluster with private endpoint and nodes without public IPs\nresource \"azurerm_kubernetes_cluster\" \"\" {\n name = \"\"\n location = \"\"\n resource_group_name = \"\"\n dns_prefix = \"dns\"\n\n private_cluster_enabled = true # Critical: enables private cluster (private endpoint/FQDN)\n\n default_node_pool {\n name = \"nodepool1\"\n node_count = 1\n vm_size = \"Standard_DS2_v2\"\n enable_node_public_ip = false # Critical: disables public IPs on nodes\n }\n\n identity {\n type = \"SystemAssigned\"\n }\n}\n```" }, "Recommendation": { - "Text": "To use a private endpoint, create a new private endpoint in your virtual network then create a link between your virtual network and a new private DNS zone", - "Url": "https://learn.microsoft.com/en-us/azure/aks/access-private-cluster?tabs=azure-cli" + "Text": "Adopt **private clusters** and eliminate node public IPs:\n- Set `enable_node_public_ip=false` on all pools\n- Use **Private Link** or peered VNets with VPN/ExpressRoute for admin access\n- If public API is unavoidable, restrict with IP ranges and strong auth\n- Enforce NSGs/firewalls and **least privilege** for layered defense", + "Url": "https://hub.prowler.com/check/aks_clusters_public_access_disabled" } }, - "Categories": [], + "Categories": [ + "internet-exposed", + "trust-boundaries", + "cluster-security" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json b/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json index ee327a58db..edcc4c503f 100644 --- a/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json +++ b/prowler/providers/azure/services/aks/aks_network_policy_enabled/aks_network_policy_enabled.metadata.json @@ -1,30 +1,38 @@ { "Provider": "azure", "CheckID": "aks_network_policy_enabled", - "CheckTitle": "Ensure Network Policy is Enabled and set as appropriate", + "CheckTitle": "AKS cluster has network policy enabled", "CheckType": [], "ServiceName": "aks", "SubServiceName": "", "ResourceIdTemplate": "", "Severity": "medium", - "ResourceType": "Microsoft.ContainerService/managedClusters", + "ResourceType": "microsoft.containerservice/managedclusters", "ResourceGroup": "container", - "Description": "When you run modern, microservices-based applications in Kubernetes, you often want to control which components can communicate with each other. The principle of least privilege should be applied to how traffic can flow between pods in an Azure Kubernetes Service (AKS) cluster. Let's say you likely want to block traffic directly to back-end applications. The Network Policy feature in Kubernetes lets you define rules for ingress and egress traffic between pods in a cluster.", - "Risk": "All pods in an AKS cluster can send and receive traffic without limitations, by default. To improve security, you can define rules that control the flow of traffic. Back-end applications are often only exposed to required front-end services, for example. Or, database components are only accessible to the application tiers that connect to them. Network Policy is a Kubernetes specification that defines access policies for communication between Pods. Using Network Policies, you define an ordered set of rules to send and receive traffic and apply them to a collection of pods that match one or more label selectors. These network policy rules are defined as YAML manifests. Network policies can be included as part of a wider manifest that also creates a deployment or service.", - "RelatedUrl": "https://learn.microsoft.com/en-us/security/benchmark/azure/security-controls-v2-network-security#ns-2-connect-private-networks-together", + "Description": "**AKS clusters** enforce **Kubernetes network policies** so that pod-to-pod traffic is governed by explicit ingress and egress rules. The finding evaluates whether a cluster has network policy enforcement enabled to support fine-grained, label-based segmentation between workloads.", + "Risk": "Without network policy, pods can talk to any pod:\n- Easy lateral movement after a pod compromise\n- Unrestricted access to backend services and data\n- Covert exfiltration/C2 via East-West traffic\n\nThis harms **confidentiality** and **integrity** and amplifies the blast radius of runtime exploits.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://learn.microsoft.com/en-us/azure/aks/use-network-policies", + "https://learn.microsoft.com/en-us/security/benchmark/azure/security-controls-v2-network-security#ns-2-connect-private-networks-together", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/azure/AKS/enable-network-policy-support.html" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "https://docs.prowler.com/checks/azure/azure-kubernetes-policies/bc_azr_kubernetes_4#terraform" + "CLI": "az aks update --resource-group --name --network-policy calico", + "NativeIaC": "```bicep\n// Enable network policy on AKS\nparam location string = resourceGroup().location\n\nresource aks 'Microsoft.ContainerService/managedClusters@2024-05-01' = {\n name: ''\n location: location\n dnsPrefix: ''\n identity: { type: 'SystemAssigned' }\n agentPoolProfiles: [\n {\n name: 'systempool'\n vmSize: 'Standard_DS2_v2'\n count: 1\n }\n ]\n networkProfile: {\n networkPlugin: 'azure'\n networkPolicy: 'calico' // Critical: enables AKS network policy enforcement\n }\n}\n```", + "Other": "1. In Azure Portal, go to Kubernetes services and select your cluster\n2. Open Networking (or Settings > Networking)\n3. Set Network policy to Azure or Calico\n4. Click Save to apply", + "Terraform": "```hcl\n# Enable network policy on AKS\nresource \"azurerm_kubernetes_cluster\" \"\" {\n name = \"\"\n location = \"\"\n resource_group_name = \"\"\n dns_prefix = \"\"\n\n default_node_pool {\n name = \"system\"\n node_count = 1\n vm_size = \"Standard_DS2_v2\"\n }\n\n identity {\n type = \"SystemAssigned\"\n }\n\n network_profile {\n network_plugin = \"azure\"\n network_policy = \"calico\" # Critical: enables AKS network policy\n }\n}\n```" }, "Recommendation": { - "Text": "", - "Url": "https://learn.microsoft.com/en-us/azure/aks/use-network-policies" + "Text": "Enable **network policy enforcement** and apply **least privilege** segmentation.\n- Start with a `deny-all` baseline, allow only required flows\n- Define both ingress and egress policies\n- Use consistent labels/namespaces\n- Layer with **defense in depth** (RBAC, node isolation, private networking) for zero-trust East-West control.", + "Url": "https://hub.prowler.com/check/aks_network_policy_enabled" } }, - "Categories": [], + "Categories": [ + "trust-boundaries", + "cluster-security" + ], "DependsOn": [], "RelatedTo": [], "Notes": "Network Policy requires the Network Policy add-on. This add-on is included automatically when a cluster with Network Policy is created, but for an existing cluster, needs to be added prior to enabling Network Policy. Enabling/Disabling Network Policy causes a rolling update of all cluster nodes, similar to performing a cluster upgrade. This operation is long-running and will block other operations on the cluster (including delete) until it has run to completion. If Network Policy is used, a cluster must have at least 2 nodes of type n1-standard-1 or higher. The recommended minimum size cluster to run Network Policy enforcement is 3 n1-standard-1 instances. Enabling Network Policy enforcement consumes additional resources in nodes. Specifically, it increases the memory footprint of the kube-system process by approximately 128MB, and requires approximately 300 millicores of CPU."