AKS Security
Security on AKS involves multiple layers: authentication and authorization, network security, encryption, secrets management, and compliance. AKS integrates deeply with Azure security services like Azure Active Directory, Azure Key Vault, and Azure Policy to provide enterprise-grade security for Kubernetes workloads.
Security Architecture
AKS security operates at multiple levels:
Azure Active Directory Integration
Azure AD integration allows you to use Azure AD for Kubernetes authentication and authorization.
Enabling Azure AD Integration
# Enable Azure AD integration
az aks update \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-aad \
--enable-azure-rbac
Azure AD Benefits:
- Use Azure AD for Kubernetes authentication
- RBAC with Azure AD groups
- Multi-factor authentication support
- Centralized identity management
Azure RBAC Integration
Azure RBAC provides Azure-native authorization:
# Grant Azure RBAC permissions
az role assignment create \
--assignee <user-or-group-id> \
--role "Azure Kubernetes Service Cluster User Role" \
--scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.ContainerService/managedClusters/<cluster-name>
Azure RBAC Roles:
Azure Kubernetes Service Cluster Admin Role- Full cluster administrationAzure Kubernetes Service Cluster User Role- Cluster accessAzure Kubernetes Service Cluster Monitoring User Role- Monitoring access
Workload Identity
Workload Identity allows pods to assume Azure identities, eliminating the need to store service principal keys in pods.
How Workload Identity Works
Setting Up Workload Identity
Step 1: Enable Workload Identity on Cluster
# Enable Workload Identity
az aks update \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-oidc-issuer \
--enable-workload-identity
Step 2: Create Azure Managed Identity
# Create user-assigned managed identity
az identity create \
--resource-group myResourceGroup \
--name my-app-identity
# Grant permissions
az role assignment create \
--assignee <identity-client-id> \
--role "Storage Blob Data Reader" \
--scope /subscriptions/.../resourceGroups/.../providers/Microsoft.Storage/storageAccounts/myStorageAccount
Step 3: Create Kubernetes Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: default
annotations:
azure.workload.identity/client-id: <identity-client-id>
Step 4: Establish Federated Credential
# Get OIDC issuer URL
OIDC_ISSUER=$(az aks show \
--resource-group myResourceGroup \
--name myAKSCluster \
--query "oidcIssuerProfile.issuerUrl" -o tsv)
# Create federated credential
az identity federated-credential create \
--name my-federated-credential \
--identity-name my-app-identity \
--resource-group myResourceGroup \
--issuer $OIDC_ISSUER \
--subject system:serviceaccount:default:my-app-sa \
--audience api://AzureADTokenExchange
Step 5: Use in Pod
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
serviceAccountName: my-app-sa
containers:
- name: app
image: my-app:latest
# Pod automatically gets Azure identity credentials
Pod Identity (Legacy)
AAD Pod Identity is the legacy approach (being replaced by Workload Identity):
# Install AAD Pod Identity
kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
Note: Workload Identity is the recommended approach for new deployments.
Network Security
Network Security Groups
Network Security Groups provide network-level access control:
Default NSG Rules:
- Allow ingress from other nodes in cluster
- Allow egress to internet
- Allow ingress from load balancers
Custom NSG Rules:
# Create NSG rule
az network nsg rule create \
--resource-group myResourceGroup \
--nsg-name myNSG \
--name allow-internal \
--priority 1000 \
--source-address-prefixes 10.0.2.0/24 \
--destination-port-ranges 8080 \
--access Allow \
--protocol Tcp
Network Policies
Network policies provide pod-to-pod firewall rules:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-policy
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
Azure Key Vault Integration
Azure Key Vault provides secure secrets management:
Using Azure Key Vault Provider for Secrets Store CSI Driver
# Install Secrets Store CSI Driver
helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver \
--namespace kube-system
# Install Azure Key Vault Provider
kubectl apply -f https://raw.githubusercontent.com/Azure/secrets-store-csi-driver-provider-azure/master/deployment/provider-azure-installer.yaml
SecretProviderClass:
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-keyvault
spec:
provider: azure
parameters:
usePodIdentity: "false"
useVMManagedIdentity: "true"
userAssignedIdentityID: <identity-client-id>
keyvaultName: my-keyvault
objects: |
array:
- |
objectName: my-secret
objectType: secret
objectVersion: ""
tenantId: <tenant-id>
Using in Pod:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
serviceAccountName: my-app-sa # With Workload Identity
containers:
- name: app
image: my-app:latest
volumeMounts:
- name: secrets-store
mountPath: /mnt/secrets-store
readOnly: true
volumes:
- name: secrets-store
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: azure-keyvault
Encryption
Control Plane Encryption
AKS control plane encryption is enabled by default:
- Encryption at Rest - etcd data encrypted with Azure-managed keys
- Encryption in Transit - TLS for API server communication
- Customer-Managed Keys - Option to use Azure Key Vault keys
Enable Customer-Managed Keys:
# Create Key Vault key
az keyvault key create \
--vault-name my-keyvault \
--name my-key \
--kty RSA \
--size 2048
# Create cluster with customer-managed key
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--enable-encryption-at-host \
--enable-azure-keyvault-kms \
--azure-keyvault-kms-key-vault-resource-id /subscriptions/.../resourceGroups/.../providers/Microsoft.KeyVault/vaults/my-keyvault \
--azure-keyvault-kms-key-id /subscriptions/.../resourceGroups/.../providers/Microsoft.KeyVault/vaults/my-keyvault/keys/my-key
Azure Disk Encryption
Enable encryption in storage class:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-premium-encrypted
provisioner: disk.csi.azure.com
parameters:
skuname: Premium_LRS
encryptionAtHost: "true"
Azure Policy Integration
Azure Policy provides governance and compliance:
# Enable Azure Policy
az aks enable-addons \
--resource-group myResourceGroup \
--name myAKSCluster \
--addons azure-policy
Policy Examples:
- Enforce resource limits
- Require specific labels
- Restrict container images
- Enforce network policies
RBAC with Azure AD Integration
Mapping Azure AD to Kubernetes Users
Azure AD integration automatically maps Azure AD users to Kubernetes users:
# Grant Azure AD user cluster access
az aks get-credentials \
--resource-group myResourceGroup \
--name myAKSCluster \
--admin
Kubernetes RBAC:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
namespace: default
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "create", "update", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: default
subjects:
- kind: User
name: [email protected]
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
Compliance and Audit Logging
Azure Monitor Logs
AKS API calls are logged to Azure Monitor:
# Enable diagnostic settings
az monitor diagnostic-settings create \
--name aks-diagnostics \
--resource /subscriptions/.../resourceGroups/.../providers/Microsoft.ContainerService/managedClusters/myAKSCluster \
--workspace /subscriptions/.../resourceGroups/.../providers/Microsoft.OperationalInsights/workspaces/myWorkspace \
--logs '[{"category":"kube-audit","enabled":true}]'
Logged Events:
- Cluster creation/deletion
- Node pool operations
- Configuration changes
- API calls
Security Best Practices
Enable Azure AD Integration - Use Azure AD for authentication
Use Workload Identity - For pod-to-Azure authentication
Enable Network Policies - Pod-to-pod network isolation
Use Azure Key Vault - For secrets management
Enable Encryption - Use customer-managed keys for sensitive workloads
Use Private Clusters - For enhanced security
Enable Azure Policy - For governance and compliance
Use Minimal Permissions - Follow least privilege principle
Enable Audit Logging - Monitor all cluster operations
Regular Updates - Keep cluster and nodes updated
Multi-Factor Authentication - Require MFA for Azure AD users
Separate Environments - Use different clusters for dev/staging/prod
Common Security Issues
Workload Identity Not Working
Problem: Pod can’t assume Azure identity
Solutions:
- Verify Workload Identity is enabled on cluster
- Check service account annotation
- Verify federated credential
- Check Azure identity permissions
- Review pod logs for credential errors
Access Denied Errors
Problem: kubectl access denied
Solutions:
- Verify Azure AD permissions
- Check RBAC permissions
- Verify cluster endpoint access
- Check Azure AD user permissions
Network Policy Not Enforcing
Problem: Network policies not working
Solutions:
- Verify network policy is enabled on cluster
- Check network policy syntax
- Verify pod selectors
- Review network policy logs
See Also
- Cluster Setup - Initial security configuration
- Networking - Network security
- Troubleshooting - Security issues