Edit

Use Microsoft Entra ID authorization for the Kubernetes API in Azure Kubernetes Service (AKS)

Applies to: ✔️ AKS Automatic ✔️ AKS Standard

This article shows how to authorize calls to the Kubernetes API in Azure Kubernetes Service (AKS) by using Microsoft Entra ID identities. Microsoft Entra ID authorization for the Kubernetes API uses Azure RBAC role assignments to grant access to Kubernetes resources. For built-in Kubernetes resources, assign one of the AKS built-in roles (such as Azure Kubernetes Service RBAC Reader) at the cluster or namespace scope. For custom resources (CRDs), assign a custom role with Azure ABAC conditions that specify which CRD groups or kinds the assignee can access. The two role assignments compose: one grants access to standard Kubernetes resources, and the other grants conditional access to specific custom resources.

For most production workloads, AKS Automatic is the recommended production-ready default for AKS. AKS Automatic clusters are preconfigured with Azure RBAC for Kubernetes authorization, so you can focus on assigning the right Microsoft Entra role assignments to users, groups, and service principals.

For a conceptual overview of the available Kubernetes API authorization options in AKS, see Cluster authorization concepts.

Note

When you use integrated authentication between Microsoft Entra ID and AKS, you can use Microsoft Entra users, groups, or service principals as subjects in Kubernetes role-based access control (Kubernetes RBAC). By using Microsoft Entra ID authorization, you don't need to separately manage user identities and credentials for Kubernetes. However, you still need to set up and manage Microsoft Entra ID role assignments and any Kubernetes RBAC bindings separately.

Note

AKS Automatic clusters are preconfigured to use Azure RBAC for Kubernetes authorization. You don't need to enable --enable-azure-rbac on AKS Automatic clusters. In AKS Standard, you can enable or disable Azure RBAC based on your cluster configuration.

Prerequisites

  • You need the Azure CLI version 2.24.0 or later installed and configured. Run az --version to find the version. If you need to install or upgrade, see Install Azure CLI.
  • You need kubectl, with a minimum version of 1.18.3.
  • You need managed Microsoft Entra integration enabled on your cluster before you can add Microsoft Entra ID authorization for the Kubernetes API. If you need to enable managed Microsoft Entra integration, see Use Microsoft Entra ID in AKS.
  • New role assignments can take up to five minutes to propagate and be updated by the authorization server.
  • Microsoft Entra ID authorization for the Kubernetes API requires that the Microsoft Entra tenant configured for authentication is the same as the tenant for the subscription that holds your AKS cluster.

AKS cluster mode behavior

Cluster mode Azure RBAC for Kubernetes authorization
AKS Automatic Preconfigured (enabled by default)
AKS Standard Optional (enable with --enable-azure-rbac)

Create a new AKS cluster with managed Microsoft Entra integration and Microsoft Entra ID authorization

For new production workloads, use AKS Automatic. Azure RBAC for Kubernetes authorization is preconfigured on AKS Automatic clusters.

  1. Create an AKS Automatic cluster by following Create an Azure Kubernetes Service (AKS) Automatic cluster.

  2. Optional: verify that Azure RBAC for Kubernetes authorization is enabled on your cluster using the az aks show command.

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    az aks show \
      --resource-group $RESOURCE_GROUP \
      --name $CLUSTER_NAME \
      --query "aadProfile.enableAzureRbac" \
      --output tsv
    

AKS Standard

  1. Create an Azure resource group using the az group create command.

    export RESOURCE_GROUP=<resource-group-name>
    export LOCATION=<azure-region>
    
    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  2. Create an AKS Standard cluster with managed Microsoft Entra integration and Microsoft Entra ID authorization using the az aks create command.

    export CLUSTER_NAME=<cluster-name>
    
    az aks create \
        --resource-group $RESOURCE_GROUP \
        --name $CLUSTER_NAME \
        --enable-aad \
        --enable-azure-rbac \
        --generate-ssh-keys
    

    Your output should look similar to the following example output:

    "AADProfile": {
        "adminGroupObjectIds": null,
        "clientAppId": null,
        "enableAzureRbac": true,
        "managed": true,
        "serverAppId": null,
        "serverAppSecret": null,
        "tenantId": "****-****-****-****-****"
    }
    

Enable Microsoft Entra ID authorization on an existing AKS cluster

For existing AKS Standard clusters, enable Microsoft Entra ID authorization for the Kubernetes API using the az aks update command with the --enable-azure-rbac flag.

# Set environment variables
export RESOURCE_GROUP=<resource-group-name>
export CLUSTER_NAME=<cluster-name>

# Enable Microsoft Entra ID authorization for the Kubernetes API
az aks update --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --enable-azure-rbac

AKS Automatic clusters already have Azure RBAC for Kubernetes authorization preconfigured. You don't need to run --enable-azure-rbac for AKS Automatic.

AKS built-in roles

AKS provides the following built-in roles:

Role Description
Azure Kubernetes Service RBAC Reader Allows read-only access to see most objects in a namespace. It doesn't allow viewing roles or role bindings. This role doesn't allow viewing Secrets, since reading the contents of Secrets enables access to ServiceAccount credentials in the namespace, which would allow API access as any ServiceAccount in the namespace (a form of privilege escalation).
Azure Kubernetes Service RBAC Writer Allows read/write access to most objects in a namespace. This role doesn't allow viewing or modifying roles or role bindings. However, this role allows accessing Secrets and running Pods as any ServiceAccount in the namespace, so it can be used to gain the API access levels of any ServiceAccount in the namespace.
Azure Kubernetes Service RBAC Admin Allows admin access, intended to be granted within a namespace. Allows read/write access to most resources in a namespace (or cluster scope), including the ability to create roles and role bindings within the namespace. This role doesn't allow write access to resource quota or to the namespace itself.
Azure Kubernetes Service RBAC Cluster Admin Allows super-user access to perform any action on any resource. It gives full control over every resource in the cluster and in all namespaces.

Create role assignments for cluster access

  1. Get your AKS resource ID using the az aks show command.

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
  2. Create a role assignment using the az role assignment create command. <AAD-ENTITY-ID> can be a username or the client ID of a service principal. The following example creates a role assignment for the Azure Kubernetes Service RBAC Admin role.

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # Create a role assignment for the Azure Kubernetes Service RBAC Admin role
    az role assignment create --role "Azure Kubernetes Service RBAC Admin" --assignee <AAD-ENTITY-ID> --scope $AKS_ID
    

    Note

    You can create the Azure Kubernetes Service RBAC Reader and Azure Kubernetes Service RBAC Writer role assignments scoped to a specific namespace within the cluster using the az role assignment create command and setting the scope to the desired namespace.

    az role assignment create --role "Azure Kubernetes Service RBAC Reader" --assignee <AAD-ENTITY-ID> --scope $AKS_ID/namespaces/<namespace-name>
    

Create custom roles definitions

For built-in Kubernetes resources, custom role definitions reference the corresponding API group action under Microsoft.ContainerService/managedClusters/. The following example allows a user to only read deployments and nothing else. For the full list of possible actions, see Microsoft.ContainerService operations. To filter access to specific custom resource (CRD) groups or kinds, see Restrict custom resource access using ABAC conditions later in this article.

  1. To create your own custom role definitions, copy the following file, replace <YOUR-SUBSCRIPTION-ID> with your own subscription ID, and then save it as deploy-view.json.

    {
        "Name": "AKS Deployment Reader",
        "Description": "Lets you view all deployments in cluster/namespace.",
        "Actions": [],
        "NotActions": [],
        "DataActions": [
            "Microsoft.ContainerService/managedClusters/apps/deployments/read"
        ],
        "NotDataActions": [],
        "assignableScopes": [
            "/subscriptions/<YOUR-SUBSCRIPTION-ID>"
        ]
    }
    
  2. Create the role definition using the az role definition create command, setting the --role-definition to the deploy-view.json file you created in the previous step.

    az role definition create --role-definition @deploy-view.json 
    
  3. Assign the role definition to a user or other identity using the az role assignment create command.

        # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # Create a role assignment for the AKS Deployment Reader role
    az role assignment create --role "AKS Deployment Reader" --assignee <AAD-ENTITY-ID> --scope $AKS_ID
    

Restrict custom resource access using ABAC conditions (preview)

Important

AKS preview features are available on a self-service, opt-in basis. Previews are provided "as is" and "as available," and they're excluded from the service-level agreements and limited warranty. AKS previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use. For more information, see the following support articles:

ABAC conditions let you filter Microsoft Entra ID role assignments to specific custom resource (CRD) groups and kinds - centrally, from Microsoft Entra ID, without writing per-cluster Kubernetes RBAC Role and RoleBinding manifests. For background on Azure ABAC, see What are Azure role assignment conditions?

When to use ABAC conditions

Use this feature when you want to:

  • Restrict which CRD groups or kinds an assignee can list or get.
  • Centrally enforce custom resource access boundaries from Microsoft Entra ID without managing Kubernetes RBAC Role and RoleBinding objects on every cluster.
  • Distinguish between CRDs published by different operators (for example, allow secrets-store.csi.x-k8s.io while blocking security.istio.io).

Available condition attributes

The following request attributes are available when authoring conditions for the Kubernetes API on an AKS cluster:

Attribute Description
Microsoft.ContainerService/managedClusters/customResources:group The API group of the custom resource being accessed (for example, secrets-store.csi.x-k8s.io).
Microsoft.ContainerService/managedClusters/customResources:kind The kind of the custom resource being accessed (for example, secretproviderclasses).

Add an ABAC condition to a role assignment

The following example creates an AKS CRD Reader custom role that grants read access to custom resources. Then it assigns the role with a condition that only allows access to secretproviderclasses in the secrets-store.csi.x-k8s.io group (the CRD used by the Azure Key Vault provider for the Secrets Store CSI Driver).

  1. Save the following role definition to a file named crd-reader.json, replacing <YOUR-SUBSCRIPTION-ID> with your own subscription ID.

    {
        "Name": "AKS CRD Reader",
        "Description": "Lets you read custom resources in the cluster.",
        "Actions": [],
        "NotActions": [],
        "DataActions": [
            "Microsoft.ContainerService/managedClusters/customresources/read"
        ],
        "NotDataActions": [],
        "assignableScopes": [
            "/subscriptions/<YOUR-SUBSCRIPTION-ID>"
        ]
    }
    
  2. Create the role definition using the az role definition create command.

    az role definition create --role-definition @crd-reader.json
    
  3. Save the following condition to a file named abac-condition.txt. The condition allows non-custom-resource reads to pass through unchanged, and restricts custom resource reads to a specific group and kind.

    (
     (
      !(ActionMatches{'Microsoft.ContainerService/managedClusters/customresources/read'})
     )
     OR
     (
      @Request[Microsoft.ContainerService/managedClusters/customResources:group] StringEqualsIgnoreCase 'secrets-store.csi.x-k8s.io'
      AND
      @Request[Microsoft.ContainerService/managedClusters/customResources:kind] StringEqualsIgnoreCase 'secretproviderclasses'
     )
    )
    
  4. Create the role assignment with the condition using the az role assignment create command.

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # Create a role assignment for the AKS CRD Reader role with an ABAC condition
    az role assignment create \
        --role "AKS CRD Reader" \
        --assignee <AAD-ENTITY-ID> \
        --scope $AKS_ID \
        --condition "$(cat abac-condition.txt)" \
        --condition-version "2.0" \
        --description "Allow reads on SecretProviderClass resources only"
    

You can also add a condition through the Azure portal. On the Add role assignment page, select the Conditions tab, then select Add condition and use the visual editor to build the expression.

Verify the condition

After the role assignment propagates (up to five minutes), sign in as the assignee and confirm they can read the allowed CRD but not other CRDs.

  1. Get the cluster credentials using the az aks get-credentials command.

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the cluster credentials
    az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
    
  2. List secretproviderclasses from the secrets-store.csi.x-k8s.io group, which the condition allows. The command should succeed and return either the existing resources or an empty list (or a not-found error if the CRD isn't installed on the cluster).

    kubectl get secretproviderclasses.secrets-store.csi.x-k8s.io --all-namespaces
    
  3. List authorizationpolicies from the Istio security.istio.io group, which the condition blocks. The command should fail with a Forbidden error from the Microsoft Entra ID authorization webhook (assuming the Istio CRD is installed on the cluster; otherwise kubectl returns a not-found error before the API server reaches the authorization webhook).

    kubectl get authorizationpolicies.security.istio.io --all-namespaces
    

Clean up resources

Disable Microsoft Entra ID authorization

Remove Microsoft Entra ID authorization using the az aks update command with the --disable-azure-rbac flag.

# Set environment variables
export RESOURCE_GROUP=<resource-group-name>
export CLUSTER_NAME=<cluster-name>

# Disable Microsoft Entra ID authorization for the Kubernetes API
az aks update --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --disable-azure-rbac

Delete role assignment

  1. List role assignments using the az role assignment list command.

    # Set environment variables
    export RESOURCE_GROUP=<resource-group-name>
    export CLUSTER_NAME=<cluster-name>
    
    # Get the AKS resource ID
    AKS_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query id --output tsv)
    
    # List role assignments for the AKS cluster
    az role assignment list --scope $AKS_ID --query [].id --output tsv
    
  2. Delete the role assignments using the az role assignment delete command.

    az role assignment delete --ids <LIST OF ASSIGNMENT IDS>
    

Delete role definition

Delete a custom role definition using the az role definition delete command.

az role definition delete --name "AKS Deployment Reader"

Delete resource group and AKS cluster

Delete the resource group (and the AKS cluster it contains) using the az group delete command.

# Set environment variables
export RESOURCE_GROUP=<resource-group-name>

# Delete the resource group and all resources in it
az group delete --name $RESOURCE_GROUP --yes --no-wait

To learn more about AKS, see the following articles: