AnalysisType: rule
Filename: azure_kubernetes_rolebinding_created.py
RuleID: "Azure.MonitorActivity.Kubernetes.RoleBindingCreated"
DisplayName: "Azure Kubernetes RoleBinding or ClusterRoleBinding Created"
Enabled: true
LogTypes:
- Azure.MonitorActivity
Severity: Medium
Description: >
Detects when a RoleBinding or ClusterRoleBinding is created in Azure Kubernetes Service (AKS)
or Arc-enabled Kubernetes clusters. Role bindings grant permissions to Kubernetes subjects
(users, groups, or service accounts) by binding them to roles with specific permissions.
Adversaries with appropriate access may create malicious role bindings to escalate privileges,
assign cluster-admin roles, or maintain persistent access to the Kubernetes cluster. This
detection applies to both AKS managed clusters and Arc-enabled connected clusters.
Reports:
MITRE ATT&CK:
- TA0004:T1078.004 # Privilege Escalation: Valid Accounts - Cloud Accounts
- TA0003:T1098 # Persistence: Account Manipulation
Tags:
- Privilege Escalation
- Persistence
- Valid Accounts
- Cloud Accounts
- Account Manipulation
Runbook: |
1. Query Azure Monitor Activity logs for all Kubernetes RBAC operations (rolebinding creation, clusterrolebinding creation, role modifications) by the callerIpAddress in the 24 hours before and after the alert
2. Find all rolebinding and clusterrolebinding creations across all Kubernetes clusters in the past 6 hours to identify if this is part of a privilege escalation campaign
3. Check if the callerIpAddress has created role bindings in the past 90 days to determine if this is typical cluster administration activity
Reference: https://github.com/elastic/detection-rules/blob/main/rules/integrations/azure/privilege_escalation_kubernetes_aks_rolebinding_created.toml
SummaryAttributes:
- resourceId
- callerIpAddress
- correlationId
- location
Tests:
- Name: Arc-enabled Cluster RoleBinding Created
ExpectedResult: true
Log:
{
"time": "2025-12-22T10:30:00.0000000Z",
"resourceId": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/kubernetes-rg/providers/Microsoft.Kubernetes/connectedClusters/arc-cluster-01/rbac.authorization.k8s.io/rolebindings/malicious-binding",
"operationName": "MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/ROLEBINDINGS/WRITE",
"operationVersion": "2021-10-01",
"category": "Administrative",
"resultType": "Success",
"resultSignature": "200",
"callerIpAddress": "1.1.1.1",
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"level": "Informational",
"location": "eastus",
"tenantId": "87654321-4321-4321-4321-111111111111"
}
- Name: Arc-enabled Cluster ClusterRoleBinding Created
ExpectedResult: true
Log:
{
"time": "2025-12-22T11:15:00.0000000Z",
"resourceId": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/k8s-arc-rg/providers/Microsoft.Kubernetes/connectedClusters/production-arc/rbac.authorization.k8s.io/clusterrolebindings/cluster-admin-binding",
"operationName": "MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/CLUSTERROLEBINDINGS/WRITE",
"category": "Administrative",
"resultType": "Succeeded",
"callerIpAddress": "2.2.2.2",
"correlationId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"level": "Information",
"location": "westeurope",
"tenantId": "22222222-2222-2222-2222-222222222222"
}
- Name: AKS Managed Cluster RoleBinding Created
ExpectedResult: true
Log:
{
"time": "2025-12-22T12:00:00.0000000Z",
"resourceId": "/subscriptions/33333333-3333-3333-3333-333333333333/resourceGroups/aks-prod/providers/Microsoft.ContainerService/managedClusters/aks-prod-01/rbac.authorization.k8s.io/rolebindings/dev-binding",
"operationName": "MICROSOFT.CONTAINERSERVICE/MANAGEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/ROLEBINDINGS/WRITE",
"category": "Administrative",
"resultType": "Success",
"callerIpAddress": "3.3.3.3",
"correlationId": "c3d4e5f6-a7b8-9012-cdef-333333333333",
"level": "Informational",
"location": "centralus",
"tenantId": "33333333-3333-3333-3333-333333333333"
}
- Name: AKS Managed Cluster ClusterRoleBinding Created Case Insensitive
ExpectedResult: true
Log:
{
"time": "2025-12-22T13:00:00.0000000Z",
"resourceId": "/subscriptions/44444444-4444-4444-4444-444444444444/resourceGroups/aks-dev/providers/Microsoft.ContainerService/managedClusters/aks-dev-cluster/rbac.authorization.k8s.io/clusterrolebindings/escalation-binding",
"operationName": "microsoft.containerservice/managedclusters/rbac.authorization.k8s.io/clusterrolebindings/write",
"category": "Administrative",
"resultType": "Success",
"callerIpAddress": "4.4.4.4",
"correlationId": "d4e5f6a7-b8c9-0123-def0-222222222222",
"level": "Information",
"location": "westus",
"tenantId": "44444444-4444-4444-4444-444444444444"
}
- Name: Different Operation
ExpectedResult: false
Log:
{
"time": "2025-12-22T15:00:00.0000000Z",
"resourceId": "/subscriptions/66666666-6666-6666-6666-666666666666/resourceGroups/aks-prod/providers/Microsoft.ContainerService/managedClusters/aks-prod-01/rbac.authorization.k8s.io/roles/custom-role",
"operationName": "MICROSOFT.CONTAINERSERVICE/MANAGEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/ROLES/WRITE",
"category": "Administrative",
"resultType": "Success",
"callerIpAddress": "6.6.6.6",
"correlationId": "f6a7b8c9-d0e1-2345-f012-678901234567",
"tenantId": "66666666-6666-6666-6666-666666666666"
}
# ------ paired body: azure_kubernetes_rolebinding_created.py ------
from panther_azureactivity_helpers import (
azure_activity_alert_context,
azure_activity_success,
extract_resource_name_from_id,
)
ROLEBINDING_OPERATIONS = [
# Arc-enabled Kubernetes clusters
"MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/ROLEBINDINGS/WRITE",
"MICROSOFT.KUBERNETES/CONNECTEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/CLUSTERROLEBINDINGS/WRITE",
# AKS managed clusters
"MICROSOFT.CONTAINERSERVICE/MANAGEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/ROLEBINDINGS/WRITE",
(
"MICROSOFT.CONTAINERSERVICE/MANAGEDCLUSTERS/RBAC.AUTHORIZATION.K8S.IO/"
"CLUSTERROLEBINDINGS/WRITE"
),
]
def rule(event):
return event.get(
"operationName", ""
).upper() in ROLEBINDING_OPERATIONS and azure_activity_success(event)
def title(event):
operation = event.get("operationName", "").upper()
binding_type = "ClusterRoleBinding" if "CLUSTERROLEBINDINGS" in operation else "RoleBinding"
resource_id = event.get("resourceId", "<UNKNOWN_RESOURCE>")
cluster_name = extract_resource_name_from_id(resource_id, "connectedClusters", default="")
if not cluster_name:
cluster_name = extract_resource_name_from_id(
resource_id, "managedClusters", default="<UNKNOWN_CLUSTER>"
)
title_str = f"Azure Kubernetes {binding_type} Created in [{cluster_name}]"
return title_str
def alert_context(event):
context = azure_activity_alert_context(event)
operation = event.get("operationName", "").upper()
context["binding_type"] = (
"cluster_role_binding" if "CLUSTERROLEBINDINGS" in operation else "role_binding"
)
resource_id = event.get("resourceId", "")
cluster_name = extract_resource_name_from_id(resource_id, "connectedClusters", default="")
if cluster_name:
context["cluster_name"] = cluster_name
context["cluster_type"] = "arc_enabled"
else:
cluster_name = extract_resource_name_from_id(resource_id, "managedClusters", default="")
if cluster_name:
context["cluster_name"] = cluster_name
context["cluster_type"] = "aks_managed"
return context