Use Kubernetes role-based access control with Microsoft Entra ID in Azure Kubernetes Service
Azure Kubernetes Service (AKS) can be configured to use Microsoft Entra ID for user authentication. In this configuration, you sign in to an AKS cluster using a Microsoft Entra authentication token. Once authenticated, you can use the built-in Kubernetes role-based access control (Kubernetes RBAC) to manage access to namespaces and cluster resources based on a user's identity or group membership.
This article shows you how to:
- Control access using Kubernetes RBAC in an AKS cluster based on Microsoft Entra group membership.
- Create example groups and users in Microsoft Entra ID.
- Create Roles and RoleBindings in an AKS cluster to grant the appropriate permissions to create and view resources.
Before you begin
- You have an existing AKS cluster with Microsoft Entra integration enabled. If you need an AKS cluster with this configuration, see Integrate Microsoft Entra ID with AKS.
- Kubernetes RBAC is enabled by default during AKS cluster creation. To upgrade your cluster with Microsoft Entra integration and Kubernetes RBAC, Enable Microsoft Entra integration on your existing AKS cluster.
- Make sure that Azure CLI version 2.0.61 or later is installed and configured. Run
az --version
to find the version. If you need to install or upgrade, see Install Azure CLI. - If using Terraform, install Terraform version 2.99.0 or later.
Use the Azure portal or Azure CLI to verify Microsoft Entra integration with Kubernetes RBAC is enabled.
To verify using the Azure portal:
- Sign in to the Azure portal and navigate to your AKS cluster resource.
- In the service menu, under Settings, select Cluster configuration.
- Under the Authentication and Authorization section, verify the Microsoft Entra authentication with Kubernetes RBAC option is selected.
Create demo groups in Microsoft Entra ID
In this article, we'll create two user roles to show how Kubernetes RBAC and Microsoft Entra ID control access to cluster resources. The following two example roles are used:
- Application developer
- A user named aksdev that's part of the appdev group.
- Site reliability engineer
- A user named akssre that's part of the opssre group.
In production environments, you can use existing users and groups within a Microsoft Entra tenant.
First, get the resource ID of your AKS cluster using the
az aks show
command. Then, assign the resource ID to a variable named AKS_ID so it can be referenced in other commands.AKS_ID=$(az aks show \ --resource-group myResourceGroup \ --name myAKSCluster \ --query id -o tsv)
Create the first example group in Microsoft Entra ID for the application developers using the
az ad group create
command. The following example creates a group named appdev:APPDEV_ID=$(az ad group create --display-name appdev --mail-nickname appdev --query id -o tsv)
Create an Azure role assignment for the appdev group using the
az role assignment create
command. This assignment lets any member of the group usekubectl
to interact with an AKS cluster by granting them the Azure Kubernetes Service Cluster User Role.az role assignment create \ --assignee $APPDEV_ID \ --role "Azure Kubernetes Service Cluster User Role" \ --scope $AKS_ID
Tip
If you receive an error such as Principal 35bfec9328bd4d8d9b54dea6dac57b82 doesn't exist in the directory a5443dcd-cd0e-494d-a387-3039b419f0d5.
, wait a few seconds for the Microsoft Entra group object ID to propagate through the directory then try the az role assignment create
command again.
Create a second example group for SREs named opssre.
OPSSRE_ID=$(az ad group create --display-name opssre --mail-nickname opssre --query id -o tsv)
Create an Azure role assignment to grant members of the group the Azure Kubernetes Service Cluster User Role.
az role assignment create \ --assignee $OPSSRE_ID \ --role "Azure Kubernetes Service Cluster User Role" \ --scope $AKS_ID
Create demo users in Microsoft Entra ID
Now that we have two example groups created in Microsoft Entra ID for our application developers and SREs, we'll create two example users. To test the Kubernetes RBAC integration at the end of the article, you'll sign in to the AKS cluster with these accounts.
Set the user principal name and password for application developers
Set the user principal name (UPN) and password for the application developers. The UPN must include the verified domain name of your tenant, for example aksdev@contoso.com
.
The following command prompts you for the UPN and sets it to AAD_DEV_UPN so it can be used in a later command:
echo "Please enter the UPN for application developers: " && read AAD_DEV_UPN
The following command prompts you for the password and sets it to AAD_DEV_PW for use in a later command:
echo "Please enter the secure password for application developers: " && read AAD_DEV_PW
Create the user accounts
- Create the first user account in Microsoft Entra ID using the
az ad user create
command. The following example creates a user with the display name AKS Dev and the UPN and secure password using the values in AAD_DEV_UPN and AAD_DEV_PW:
AKSDEV_ID=$(az ad user create \
--display-name "AKS Dev" \
--user-principal-name $AAD_DEV_UPN \
--password $AAD_DEV_PW \
--query id -o tsv)
- Add the user to the appdev group created in the previous section using the
az ad group member add
command.
az ad group member add --group appdev --member-id $AKSDEV_ID
- Set the UPN and password for SREs. The UPN must include the verified domain name of your tenant, for example
akssre@contoso.com
. The following command prompts you for the UPN and sets it to AAD_SRE_UPN for use in a later command:
echo "Please enter the UPN for SREs: " && read AAD_SRE_UPN
- The following command prompts you for the password and sets it to AAD_SRE_PW for use in a later command:
echo "Please enter the secure password for SREs: " && read AAD_SRE_PW
- Create a second user account. The following example creates a user with the display name AKS SRE and the UPN and secure password using the values in AAD_SRE_UPN and AAD_SRE_PW:
# Create a user for the SRE role
AKSSRE_ID=$(az ad user create \
--display-name "AKS SRE" \
--user-principal-name $AAD_SRE_UPN \
--password $AAD_SRE_PW \
--query id -o tsv)
# Add the user to the opssre Azure AD group
az ad group member add --group opssre --member-id $AKSSRE_ID
Create AKS cluster resources for app devs
We have our Microsoft Entra groups, users, and Azure role assignments created. Now, we'll configure the AKS cluster to allow these different groups access to specific resources.
- Get the cluster admin credentials using the
az aks get-credentials
command. In one of the following sections, you get the regular user cluster credentials to see the Microsoft Entra authentication flow in action.
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --admin
- Create a namespace in the AKS cluster using the
kubectl create namespace
command. The following example creates a namespace name dev:
kubectl create namespace dev
Note
In Kubernetes, Roles define the permissions to grant, and RoleBindings apply them to desired users or groups. These assignments can be applied to a given namespace, or across the entire cluster. For more information, see Using Kubernetes RBAC authorization.
If the user you grant the Kubernetes RBAC binding for is in the same Microsoft Entra tenant, assign permissions based on the userPrincipalName (UPN). If the user is in a different Microsoft Entra tenant, query for and use the objectId property instead.
- Create a Role for the dev namespace, which grants full permissions to the namespace. In production environments, you can specify more granular permissions for different users or groups. Create a file named
role-dev-namespace.yaml
and paste the following YAML manifest:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dev-user-full-access
namespace: dev
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
- Create the Role using the
kubectl apply
command and specify the filename of your YAML manifest.
kubectl apply -f role-dev-namespace.yaml
- Get the resource ID for the appdev group using the
az ad group show
command. This group is set as the subject of a RoleBinding in the next step.
az ad group show --group appdev --query id -o tsv
- Create a RoleBinding for the appdev group to use the previously created Role for namespace access. Create a file named
rolebinding-dev-namespace.yaml
and paste the following YAML manifest. On the last line, replace groupObjectId with the group object ID output from the previous command.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dev-user-access
namespace: dev
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dev-user-full-access
subjects:
- kind: Group
namespace: dev
name: groupObjectId
Tip
If you want to create the RoleBinding for a single user, specify kind: User and replace groupObjectId with the user principal name (UPN) in the above sample.
- Create the RoleBinding using the
kubectl apply
command and specify the filename of your YAML manifest:
kubectl apply -f rolebinding-dev-namespace.yaml
Create the AKS cluster resources for SREs
Now, we'll repeat the previous steps to create a namespace, Role, and RoleBinding for the SREs.
- Create a namespace for sre using the
kubectl create namespace
command.
kubectl create namespace sre
- Create a file named
role-sre-namespace.yaml
and paste the following YAML manifest:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sre-user-full-access
namespace: sre
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
- Create the Role using the
kubectl apply
command and specify the filename of your YAML manifest.
kubectl apply -f role-sre-namespace.yaml
- Get the resource ID for the opssre group using the az ad group show command.
az ad group show --group opssre --query id -o tsv
- Create a RoleBinding for the opssre group to use the previously created Role for namespace access. Create a file named
rolebinding-sre-namespace.yaml
and paste the following YAML manifest. On the last line, replace groupObjectId with the group object ID output from the previous command.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sre-user-access
namespace: sre
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: sre-user-full-access
subjects:
- kind: Group
namespace: sre
name: groupObjectId
- Create the RoleBinding using the
kubectl apply
command and specify the filename of your YAML manifest.
kubectl apply -f rolebinding-sre-namespace.yaml
Interact with cluster resources using Microsoft Entra identities
Now, we'll test that the expected permissions work when you create and manage resources in an AKS cluster. In these examples, we'll schedule and view pods in the user's assigned namespace, and try to schedule and view pods outside of the assigned namespace.
- Reset the kubeconfig context using the
az aks get-credentials
command. In a previous section, you set the context using the cluster admin credentials. The admin user bypasses Microsoft Entra sign-in prompts. Without the--admin
parameter, the user context is applied that requires all requests to be authenticated using Microsoft Entra ID.
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing
- Schedule a basic NGINX pod using the
kubectl run
command in the dev namespace.
kubectl run nginx-dev --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
- Enter the credentials for your own
appdev@contoso.com
account created at the start of the article as the sign-in prompt. Once you're successfully signed in, the account token is cached for futurekubectl
commands. The NGINX is successfully schedule, as shown in the following example output:
$ kubectl run nginx-dev --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
To sign in, use a web browser to open the page https://microsoft.com/deviceloginchina and enter the code B24ZD6FP8 to authenticate.
pod/nginx-dev created
- Use the
kubectl get pods
command to view pods in the dev namespace.
kubectl get pods --namespace dev
- Ensure the status of the NGINX pod is Running. The output will look similar to the following output:
$ kubectl get pods --namespace dev
NAME READY STATUS RESTARTS AGE
nginx-dev 1/1 Running 0 4m
Create and view cluster resources outside of the assigned namespace
Try to view pods outside of the dev namespace. Use the kubectl get pods
command again, this time to see --all-namespaces
.
kubectl get pods --all-namespaces
The user's group membership doesn't have a Kubernetes Role that allows this action, as shown in the following example output:
Error from server (Forbidden): pods is forbidden: User "aksdev@contoso.com" cannot list resource "pods" in API group "" at the cluster scope
In the same way, try to schedule a pod in a different namespace, such as the sre namespace. The user's group membership doesn't align with a Kubernetes Role and RoleBinding to grant these permissions, as shown in the following example output:
$ kubectl run nginx-dev --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace sre
Error from server (Forbidden): pods is forbidden: User "aksdev@contoso.com" cannot create resource "pods" in API group "" in the namespace "sre"
Test the SRE access to the AKS cluster resources
To confirm that our Microsoft Entra group membership and Kubernetes RBAC work correctly between different users and groups, try the previous commands when signed in as the opssre user.
- Reset the kubeconfig context using the
az aks get-credentials
command that clears the previously cached authentication token for the aksdev user.
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --overwrite-existing
- Try to schedule and view pods in the assigned sre namespace. When prompted, sign in with your own
opssre@contoso.com
credentials created at the start of the article.
kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace sre
kubectl get pods --namespace sre
As shown in the following example output, you can successfully create and view the pods:
$ kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace sre
3. To sign in, use a web browser to open the page https://microsoft.com/deviceloginchina and enter the code BM4RHP3FD to authenticate.
pod/nginx-sre created
$ kubectl get pods --namespace sre
NAME READY STATUS RESTARTS AGE
nginx-sre 1/1 Running 0
- Try to view or schedule pods outside of assigned SRE namespace.
kubectl get pods --all-namespaces
kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
These kubectl
commands fail, as shown in the following example output. The user's group membership and Kubernetes Role and RoleBindings don't grant permissions to create or manager resources in other namespaces.
$ kubectl get pods --all-namespaces
Error from server (Forbidden): pods is forbidden: User "akssre@contoso.com" cannot list pods at the cluster scope
$ kubectl run nginx-sre --image=mcr.azk8s.cn/oss/nginx/nginx:1.15.5-alpine --namespace dev
Error from server (Forbidden): pods is forbidden: User "akssre@contoso.com" cannot create pods in the namespace "dev"
Clean up resources
In this article, you created resources in the AKS cluster and users and groups in Microsoft Entra ID. To clean up all of the resources, run the following commands:
# Get the admin kubeconfig context to delete the necessary cluster resources.
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster --admin
# Delete the dev and sre namespaces. This also deletes the pods, Roles, and RoleBindings.
kubectl delete namespace dev
kubectl delete namespace sre
# Delete the Azure AD user accounts for aksdev and akssre.
az ad user delete --upn-or-object-id $AKSDEV_ID
az ad user delete --upn-or-object-id $AKSSRE_ID
# Delete the Azure AD groups for appdev and opssre. This also deletes the Azure role assignments.
az ad group delete --group appdev
az ad group delete --group opssre
Next steps
For more information about how to secure Kubernetes clusters, see Access and identity options for AKS.
For best practices on identity and resource control, see Best practices for authentication and authorization in AKS.