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:

graph TB subgraph authentication[Authentication] USER[User/Application] --> AAD[Azure AD] AAD --> AKS[AKS API Server] end subgraph authorization[Authorization] AKS --> RBAC[Kubernetes RBAC] RBAC --> POD[Pod Access] end subgraph network[Network Security] POD --> NSG[Network Security Groups] POD --> NP[Network Policies] POD --> VNET[VNet Isolation] end subgraph encryption[Encryption] POD --> KV[Azure Key Vault] KV --> DISK[Encrypted Azure Disk] KV --> SECRETS[Encrypted Secrets] end style USER fill:#e1f5ff style AKS fill:#fff4e1 style POD fill:#e8f5e9 style KV fill:#f3e5f5

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 administration
  • Azure Kubernetes Service Cluster User Role - Cluster access
  • Azure 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

graph LR POD[Pod] --> SA[Service Account] SA --> ANNOTATION[Annotation:<br/>azure.workload.identity/client-id] ANNOTATION --> WI[Workload Identity] WI --> AAD[Azure AD] AAD --> AZURE_IDENTITY[Azure Managed Identity] AZURE_IDENTITY --> AZURE_SERVICE[Azure Service] style POD fill:#e1f5ff style AZURE_IDENTITY fill:#fff4e1 style AZURE_SERVICE fill:#e8f5e9

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

  1. Enable Azure AD Integration - Use Azure AD for authentication

  2. Use Workload Identity - For pod-to-Azure authentication

  3. Enable Network Policies - Pod-to-pod network isolation

  4. Use Azure Key Vault - For secrets management

  5. Enable Encryption - Use customer-managed keys for sensitive workloads

  6. Use Private Clusters - For enhanced security

  7. Enable Azure Policy - For governance and compliance

  8. Use Minimal Permissions - Follow least privilege principle

  9. Enable Audit Logging - Monitor all cluster operations

  10. Regular Updates - Keep cluster and nodes updated

  11. Multi-Factor Authentication - Require MFA for Azure AD users

  12. 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