When working with Azure Kubernetes Service (AKS), one of the first things that hits you—especially in enterprise environments—is the need to get access control right. But here’s the tricky bit: while Authentication and Authorization often come bundled in conversation, they are two distinct pieces in the AKS puzzle.
Let’s break it down in a no-nonsense, real-world way.

🔐 AKS Authentication : Let Azure AD Do the Heavy Lifting
In AKS, the most widely accepted and secure authentication method is via Azure AD (now Microsoft Entra). Instead of managing individual users, we integrate AKS with Azure AD and assign access via AD Groups.
✅ Why AD Groups over individual users?
-
-
-
-
Easier to manage at scale.
-
Aligned with enterprise IAM practices.
-
Avoids clutter and reduces access sprawl.
-
-
-
💡 When you run az aks get-credentials, the kubeconfig is populated based on your Azure AD identity. This is the first gate — if you’re not authenticated via Azure AD, you don’t get through the door.
🛡️ Authorization in AKS : Where the Real Confusion Begins
Once authenticated, what can you do inside the cluster depends on how authorization is handled. And this is where things split into two paths:
🔸 Option 1 : Azure AD + Kubernetes RBAC
Azure Kubernetes Service Cluster User role to the Azure AD user or group.Without this role, the user will not be able to download cluster credentials using
az aks get-credentials.
Kubernetes RBAC is the native Kubernetes and flexible approach to manage Kubernetes authorization.
While Azure RBAC is only applicable for AKS, Kubernetes RBAC can be applied in any Kubernetes platform; AKS, EKS, GKE and even on-premises Kubernetes clusters.
You use Kubernetes native constructs like:
-
-
-
Roles / RoleBindings → for namespace-specific permissions using namespace specific roles
-
ClusterRoles / ClusterRoleBindings → for cluster-wide permissions using cluster wide roles
- ClusterRoles / RoleBindings → for namespace-specific permissions using cluster wide roles
-
-
In AKS, we typically bind Azure AD users or groups using their object ID (azuread_user_object_id or group_object_id) directly in the RBAC YAML.
Custom Kubernetes RBAC: Grant Scoped Access to an Azure AD Group
Let’s now discuss Kubernets RBAC in the context of a use case. Let’s say you want to grant an Azure AD group full access to specific resources — Pods, Deployments, Services, and Secrets — within a single namespace called test. No other permissions should be granted.
✅ Why Use a ClusterRole Instead of a Role?
Although the access is namespace-specific, we use a ClusterRole instead of a Role so that the same role definition can be reused across multiple namespaces using different RoleBinding objects. This avoids duplication and makes access control more scalable.
📄 Step 1 : Define the ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: namespace-workload-admin rules: - apiGroups: [""] resources: ["pods", "services", "secrets"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
📄 Step 2 : Create a RoleBinding in the test Namespace
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: workload-admin-binding namespace: test subjects: - kind: Group name: <Azure_AD_Group_Object_ID> apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: namespace-workload-admin apiGroup: rbac.authorization.k8s.io
Note: Replace <Azure_AD_Group_Object_ID> with the actual object ID of your Azure AD group.
💡 Note on Using ["*"] in verbs
We could have used ["*"] in the verbs section to allow all actions on the specified resources. For example:
verbs: ["*"]
This is perfectly valid and functionally equivalent to listing all verbs like get, list, watch, create, update, patch, and delete.
However, in this example, we chose to explicitly list each verb to ensure clarity and tighter control — especially important in production-grade RBAC policies.
While ["*"] can simplify configurations, it should be used with caution, only when you fully understand the implications of granting unrestricted access to the resource type in question. It’s best reserved for tightly scoped and trusted service accounts, not for broad user or group permissions.
🔍 Step 3 : Validate Permissions Using kubectl auth can-i
You can validate access by impersonating a user who is a member of the Azure AD group. kubectl auth can-i does not support checking directly against group object IDs.
kubectl auth can-i create pods --as=<user-UPN> -n test kubectl auth can-i get secrets --as=<user-UPN> -n test kubectl auth can-i delete deployments --as=<user-UPN> -n test kubectl auth can-i get configmaps --as=<user-UPN> -n test # Should return "no"
✅ Summary
-
-
- A
ClusterRolewas used for flexibility and reusability across namespaces. - Access is scoped to the
testnamespace via aRoleBinding. - Only specific resources are included (Pods, Services, Secrets, Deployments).
- Access was verified using
kubectl auth can-iwith a valid user identity.
- A
-
🔸Option 2 : Azure RBAC for AKS: Centralized Cluster Access Management
Azure RBAC is designed for broad, centralized access control across AKS clusters. It shines in two key scenarios:
-
- Platform teams managing multiple clusters who need consistent permissions
- Subscription-wide access patterns that should automatically apply to new clusters
When using Azure RBAC for Kubernetes authorization in AKS, it’s important to distinguish between two planes of access: roles that operate inside the cluster (Kubernetes-aware), and roles that manage the AKS infrastructure from the outside.
1️⃣ Cluster-Interior Azure RBAC Roles (Kubernetes-Aware)
These are Azure RBAC roles that directly interact with the Kubernetes API within the cluster:
-
-
-
RBAC Viewer: Read-only access to most Kubernetes resources, except Secrets. Cannot run cluster-wide commands like
kubectl get pods -Aunless scoped at the cluster level. -
RBAC Writer: Allows creating and modifying most resources, but still cannot access Secrets or RBAC policies.
-
RBAC Admin: Grants admin-level permissions within a given namespace, including RoleBindings, but cannot perform cluster-level actions like viewing nodes or storage classes.
-
RBAC Cluster Admin: Full access to everything inside the cluster — Secrets, RBAC, and all cluster-scoped operations.
-
-
📌 Scoping Options:
Azure RBAC roles for AKS can be scoped at either the cluster level or the namespace level.
-
-
-
Cluster-level scope allows access across all namespaces in the cluster. This is ideal for platform or operations teams who need broad visibility and control.
-
Namespace-level scope narrows down the access to a single namespace, making it suitable for application teams or CI/CD pipelines.
-
-
Note: RBAC Cluster Admin is the only role that must be scoped at the cluster level — it cannot be limited to a namespace.
The following cluster-wide commands require elevated privileges and will only succeed if the user has the RBAC Cluster Admin role:
kubectl get nodes kubectl get pods -A kubectl get storageclass kubectl get clusterroles kubectl describe clusterrole cluster-admin kubectl get secrets -A
Users with namespace-scoped roles like RBAC Admin or RBAC Writer will receive “forbidden” errors when attempting these operations.
2️⃣ Cluster-Exterior Azure RBAC Roles (Azure Resource-Level)
These roles manage the AKS resource itself — for example, performing upgrades, scaling, or viewing cluster configuration in Azure — but they do not grant any access to Kubernetes workloads:
-
-
-
AKS Contributor: Full control of AKS resource (infra-level), but no Kubernetes API access.
-
AKS Reader: View-only access to the AKS resource metadata.
-
-
🧭 Key Observations on Azure RBAC Roles
-
-
-
Access Hierarchy: Permissions increase from Viewer → Writer → Admin → Cluster Admin.
-
Scope Awareness: Cluster-scoped assignments provide broader visibility (like
kubectl get pods -A), but even they can’t access Secrets unless it’s RBAC Cluster Admin. -
Secrets and RBAC: No Azure RBAC role except RBAC Cluster Admin can access Secrets or Kubernetes RBAC settings. Use Kubernetes-native RBAC if you need that control at a finer level.
-
No Custom Namespace Roles: Azure RBAC does not allow custom roles scoped to namespaces. For precise control, fall back to Kubernetes RBAC.
-
-
🛑 Mandatory Gateway Role: Cluster User
No matter which Azure RBAC role you assign for in-cluster permissions, users must have the Azure Kubernetes Service Cluster User role to:
-
-
-
Run
az aks get-credentials -
Reach the Kubernetes API server
-
-
Without this role, even users with correct Kubernetes RBAC won’t be able to connect to the cluster.
Subscription-Wide Azure RBAC: Access Across All AKS Clusters
There are scenarios—especially in large organizations—where certain Azure AD groups (like platform or security admins) need consistent access to all AKS clusters within a subscription, including:
-
-
-
-
✅ Existing AKS clusters
-
✅ Any newly created AKS clusters in the future
-
-
-
This is where Azure RBAC for Kubernetes Authorization shines.
By assigning Azure RBAC roles (like Azure Kubernetes Service RBAC Cluster Admin) at the subscription level, the access automatically propagates to:
-
-
-
All AKS clusters in that subscription
-
Without the need to manually configure access on each cluster
-
-
🛑 Kubernetes RBAC cannot do this — it is cluster-specific. Any role bindings you define via Kubernetes YAML apply only within that particular AKS cluster.
🔑 Use Case: Granting a central admin group cluster-admin rights on all current and future AKS clusters without touching each one.
Kubernetes RBAC vs Azure RBAC : Which One to Pick?
In real-world AKS environments, this isn’t always a matter of choosing one over the other — it’s about using both strategically to get the best of both worlds.
Let’s break it down:
✅ When to Use Azure RBAC for Kubernetes Authorization
-
-
-
-
You want to manage access centrally from Azure Portal, CLI, or ARM.
-
You need to assign access to all AKS clusters within a subscription or management group. This kind of access is more suitable for platform team / infrastructure team who manage all AKS clusters within the subscription.
-
You want to ensure future AKS clusters automatically inherit access permissions (e.g., for platform teams or auditors).
-
You’re okay using built-in or custom (limited) Azure roles.
-
-
-
✅ When to Use Kubernetes RBAC
-
-
-
-
You need fine-grained, namespace-specific access control. This is more suitable for application developers, who needs cluster specific and namespace specific access.
-
You want to define custom access rules using Kubernetes-native constructs.
-
You’re operating in a multi-tenant cluster or managing access per workload team.
-
You want full flexibility beyond what Azure’s predefined roles can offer.
-
-
-
💡 Combine Both for Best Results
A common pattern is:
-
-
-
Use Azure RBAC for broad, subscription-wide or management-group-wide access (e.g., cluster-admin for a central admin group).
-
Use Kubernetes RBAC for scoped, per-cluster or per-namespace roles (e.g., developers, DevOps teams, service accounts).
- In both the cases, you need to grant
Azure Kubernetes Service Cluster Userrole , so that user can download cluster credential.
-
-
🧠 What Happens If You Mix Both?
Here’s where things can get tricky. If a user is granted some access via Azure RBAC and other access via Kubernetes RBAC:
-
-
- The permissions are additive.
- The user gets the union of all access rights granted via both methods.
-
So , a user could be:
-
-
- A cluster admin via Azure RBAC, and
- Scoped to only one namespace via Kubernetes RBAC — and still do both.
-
No override, no conflict — just union.
👑 The AKS Admin Group : The Hidden Master Key
When you enable Azure AD integration in AKS, you can (and should) specify an Admin Group Object ID. Members of this group:
-
-
- Can access the cluster with full rights, irrespective of Kubernetes RBAC rules.
- Bypass the usual Kubernetes RBAC restrictions.
-
So, if a user is in this admin group but you’ve tried to restrict them using Kubernetes RBAC — it won’t work. The admin group takes precedence.
Only selected Kubernetes administrators should be members of this group, and membership should be reviewed periodically to maintain security and governance.
🔑 What About AKS Local Admin?
When you create an AKS cluster, you get a local Kubernetes admin context in your kubeconfig — often via the --admin flag:
az aks get-credentials --admin ...
This local admin:
-
-
- Bypasses Azure AD entirely.
- Can access everything, always.
- Should not be used regularly, only for break-glass or setup purposes.
-
Any access via this account is generic and untraceable to an individual.
Use this account strictly for break-glass scenarios.
Once Azure AD integration is in place, it is recommended to disable the local admin account and re-enable it only when required.
CI/CD Pipeline Access for kubectl apply
Problem Statement :
For CI/CD pipeline, we generally use service principle, but we often grant them “Cluster Admin” access, to avoid access headaches. This creates security risk.
Recommended Approach :
For pipelines deploying via kubectl apply, follow this balanced strategy:
-
Azure AD Integration (Not Cluster Admin)
- Assign the pipeline’s service principal the
Azure Kubernetes Service Cluster Userrole -
Add granular Kubernetes RBAC roles scoped to target namespaces:
kubectl create role pipeline-deployer \ --verb=create,update,patch,get,list,watch \ --resource='*' \ -n target-namespace kubectl create rolebinding pipeline-binding \ --role=pipeline-deployer \ --serviceaccount=azure-ad:pipeline-sp \ -n target-namespace
- Assign the pipeline’s service principal the
- Practical Security Balance
- ✅ Do: Restrict to specific namespaces and avoid cluster-scoped permissions
- ❌ Don’t: Grant cluster-admin unless absolutely necessary
- 🔄 Compromise: Create a custom cluster role with broad but safe permissions:
# clusterrole-pipeline.yaml rules: - apiGroups: ["apps", ""] # Core + apps group resources: ["*"] verbs: ["get", "list", "watch", "create", "update", "patch"] - apiGroups: ["rbac.authorization.k8s.io"] resources: ["*"] verbs: ["get", "list", "watch"] # Read-only for RBAC
Maintenance Tip :
Use audit logs to identify missing permissions, then incrementally add them rather than starting with full access.
GitOps Tools Access – The Security-Functionality Balance
The Default Risk Most Teams Overlook
When installing Flux or ArgoCD using standard methods, both tools configure themselves with unrestricted cluster-admin privileges. This common practice creates a dangerous paradox: while GitOps promises better change control, the tools themselves often operate with dangerously broad access. The controller pods can modify any resource across all namespaces, including critical cluster components and secrets.
⚠️ The Forgotten Attack Path :
GitOps tools with cluster-admin can :
1. Modify their own RBAC permissions
2. Create new cluster-admin ServiceAccounts
3. Disable audit logging
Mitigation :
– Use OPA/Gatekeeper to block privilege escalations
– Enable Kubernetes audit logging
– Regularly review controller permissions
GitOps Access Strategy: Keep It Tight, Keep It Safe
When configuring GitOps tools like Flux or ArgoCD, the goal is simple :
✅ Just enough access to deploy — nothing more.
💡 Key Principles
-
-
-
- Start with Deny → Grant only what’s necessary as errors surface.
- Use namespace-scoped RBAC whenever possible.
- Restrict sensitive actions like managing Secrets or modifying RBAC.
-
-
🔁 Environment-Based Strategy
| Environment | Access Strategy |
|---|---|
| Production | Namespace-scoped + deny-lists for safety |
| Staging | Cluster-read + namespace-write access |
| Development | Broader access with monitoring enabled |
🛠 Practical Steps
-
-
-
New Setups: Begin narrow, expand only if needed.
-
Existing Setups:
- Audit with
kubectl auth can-i --list - Monitor actual usage
- Gradually restrict and validate
- Audit with
-
-
⚠️ When Exceptions Make Sense
-
-
-
- During GitOps rollout
- When managing cluster-wide CRDs
- In dev clusters prioritizing speed
-
-
📌 Always document and review elevated access quarterly.
Recommendation:
“Give GitOps tools enough rope to deploy effectively — but tie knots at critical endpoints like secrets and RBAC.”
🚦 Rule of Thumb for AKS Access Management
-
-
- ✅ Use Azure AD Groups for authentication — scalable and secure
- ✅ Use Azure RBAC for broad, centralized access across clusters
- ✅ Use Kubernetes RBAC for fine-grained, per-cluster or per-namespace control
- ✅ Always assign the
Azure Kubernetes Service Cluster Userrole — it’s required to access the cluster, regardless of whether you use Azure or Kubernetes RBAC - ✅ Prefer ClusterRoles (even for namespace-level access) — they can be reused across multiple namespaces via RoleBindings
- ✅ While using Kubernetes RBAC, be cautious with
["*"]in verbs — it grants full permissions and should be used only when truly necessary - ✅ Grant limited but sufficient access to GitOps tools — enough to deploy workloads, but restrict sensitive operations
- 🔄 Combine Azure RBAC and Kubernetes RBAC where it makes sense — they’re complementary, not conflicting
- ⚠️ Use the AKS Admin Group to assign delegated cluster-wide access for trusted administrators, and review the members of this group time to time.
- ⚠️ Reserve the Kubernetes Admin Local Account (
--admin) strictly for break-glass or initial setup scenarios. The Local Admin account can be disabled after Azure AD integration, and can be re-enabled again when required.
-
One thought on “Demystifying AKS Authentication and Authorization”