Secrets
| Operation | Description | Sample | Rule |
|---|---|---|---|
| get-secrets | Secret accessed (credential theft; service account tokens, TLS certs, API keys). | Y | Y |
| list-secrets | Secrets enumerated across a namespace or cluster. | Y | Y |
| watch-secrets | Opens a long-lived watch on Secret changes across a namespace. Elastic's new-terms rule flags a first-seen client streaming secrets instead of polling. | Y | Y |
| create-secrets | Creates a new Secret. Sigma covers create alongside update/patch/delete; attackers stage a token or key this way, smuggled in as ordinary config. | Y | Y |
| update-secrets | Replaces a Secret's data wholesale. Same Sigma/Elastic write coverage as patch; Secrets hold tokens, TLS keys, and API credentials, so this is credential access. | Y | Y |
| patch-secrets | Modifies an existing Secret's data. Sigma and Elastic's Azure Arc proxy rule both flag this write as credential-access activity on a stored credential. | Y | Y |
| delete-secrets | Deletes a Secret, destroying credentials in use or covering tracks after copying its contents beforehand. The same Sigma secrets-modified-or-deleted rule matches this verb. | Y | Y |
| deletecollection-secrets | Y | N | |
| any-secrets | Synthetic aggregation for rules that filter the secrets resource with no specific verb. Not a distinct audit record; hosts rule listings that key on objectRef.resource alone. | N | Y |
get secrets
#Description
Secret accessed (credential theft; service account tokens, TLS certs, API keys).
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "71e17297-aa99-4e08-9147-ee36753f7dbf",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/default/secrets/my-secret",
"verb": "get",
"user": {
"username": "kubernetes-admin",
"uid": "aws-iam-authenticator:591511147606:AIDAYTOGP2RLJGRCUIGJZ",
"groups": [
"system:masters",
"system:authenticated"
]
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.27.2 (darwin/arm64) kubernetes/7f6f68f",
"objectRef": {
"resource": "secrets",
"namespace": "default",
"name": "my-secret",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2023-12-05T15:10:15.127831Z",
"stageTimestamp": "2023-12-05T15:10:15.160004Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": ""
}
}
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
objectRef.resource | eq | secrets | 6 rules | falco, splunk |
verb | eq | get | 6 rules | falco, splunk |
ServiceName (elastic rule field) | eq | k8s.io | 5 rules | elastic |
src_ip (elastic rule field) | is_not_null | | 5 rules | elastic |
kubernetes.audit.verb (elastic rule field) | in | get | 4 rules | elastic |
kubernetes.audit.verb (elastic rule field) | in | list | 4 rules | elastic |
EventType (elastic rule field) | eq | io.k8s.core.v1.secrets.get | 3 rules | elastic |
EventType (elastic rule field) | in | io.k8s.core.v1.secrets.get | 3 rules | elastic |
EventType (elastic rule field) | in | io.k8s.core.v1.secrets.list | 3 rules | elastic |
client.user.email (elastic rule field) | is_not_null | | 2 rules | elastic |
client.user.email (elastic rule field) | starts_with | system:serviceaccount: | 2 rules | elastic |
jevt.rawtime (falco rule field) | is_not_null | | 2 rules | falco |
kubernetes.audit.objectRef.resource (elastic rule field) | eq | secrets | 2 rules | elastic |
kubernetes.audit.objectRef.resource (elastic rule field) | in | configmaps | 2 rules | elastic |
kubernetes.audit.objectRef.resource (elastic rule field) | in | secrets | 2 rules | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → AKS kube-audit events are carried under the flattened This rule surfaces clusters of The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule. This rule fires on two high-confidence patterns in GKE audit logs: Treat node-originated Secrets API calls as priority. For denied service-account gets, determine whether the identity is probing secrets outside its Role/ClusterRole or using an unexpected client from a compromised token.Elastic #
T1552, T1552.007↳ also matches list-secrets: list secrets Investigation guide
Triage and analysis#
Investigating Azure AKS Secret get or list with Suspicious User Agent#
azure.platformlogs.properties.log.* subtree and share the ARM operation event.action: Microsoft.ContainerService/managedClusters/diagnosticLogs/Read. This rule fires when a successful get or list against Kubernetes secrets is issued with a user agent that matches scripting runtimes (python, ruby, perl), command-line HTTP clients (curl, wget, HTTPie), or generic HTTP libraries (Go-http-client, okhttp, Apache-HttpClient, Guzzle, axios, undici) rather than typical kubectl or named controller traffic. The user agent is trivially spoofable (the telemetry shows offensive tooling masquerading as kubectl), so this is a corroborating indicator, not proof.Possible investigation steps#
azure.platformlogs.properties.log.user.username and its group memberships in azure.platformlogs.properties.log.user.groups. Control-plane and node identities (system:apiserver, aksService, system:node:*, system:serviceaccount:kube-system:*) are expected; a human or service-principal identity reading secrets with a scripted client is not.azure.platformlogs.properties.log.annotations.authorization.k8s.io/decision (allow vs forbid) and the azure.platformlogs.properties.log.responseStatus.code.azure.platformlogs.properties.log.objectRef.namespace and azure.platformlogs.properties.log.objectRef.name, and the exact API path in azure.platformlogs.properties.log.requestURI.azure.platformlogs.properties.log.sourceIPs. In-cluster control-plane traffic uses loopback (::1) or node subnet addresses; a public or pod-network source for a secret read is more suspicious. Pivot on the source for other API bursts, exec sessions, or RBAC changes.False positive analysis#
Go-http-client/2.0 user agent when no custom agent is set (see kubernetes/kubernetes#108726), so an operator or platform component reading secrets may match Go-http*. Exclude the specific benign identity (for example system:serviceaccount:kube-system:* or a validated operator service account) rather than removing the Go-http* pattern, which also catches default-user-agent offensive tooling.Response and remediation#
T1552, T1552.007Investigation guide
Triage and analysis#
Investigating GKE Rapid Secret GET Activity Against Multiple Objects#
get operations on secrets where the same identity and client path (client.user.email, source.ip, user_agent.original) touch several different secret resource paths within the lookback window. Allowed and denied outcomes are included: successful reads may indicate harvesting; repeated failure responses can still signal reconnaissance or RBAC probing. System service accounts and core controllers are excluded only for successful secret reads, failed attempts from those identities still alert.Investigation steps#
Esql.event_outcome_values for a mix of success vs failure and whether failures cluster on sensitive namespaces.Esql.gcp_audit_resource_name_values for high-value targets (tokens, registry credentials, TLS bundles, application secrets).source.ip and user for follow-on API activity (exec, pod create, role changes, broad list on secrets).False positives#
Setup#
T1552, T1552.007↳ also matches list-secrets: list secrets Investigation guide
Triage and analysis#
Investigating GKE Secret Access from Node or Denied Service Account#
system:node:* successfully or unsuccessfully calling secrets.get or secrets.listsystem:serviceaccount:* receiving event.outcome:failure on secrets.getPossible investigation steps#
client.user.email to the node or workload and review RBAC bindings for secret get/list scope.gcp.audit.resource_name, source.ip, and user_agent.original for anomalous clients or cross-namespace targets.False positive analysis#
Response and remediation#
Splunk #
T1552, T1552.007T1552, T1552.007T1552, T1552.007Panther #
T1552.007, T1613T1552.007↳ also matches list-secrets: list secrets, watch-secrets: watch secrets Falco #
References #
list secrets
#Description
Secrets enumerated across a namespace or cluster.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/dw-harn/secrets?limit=500&timeout=3s",
"verb": "list",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "secrets",
"namespace": "dw-harn",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2026-07-02T04:46:46.821160Z",
"stageTimestamp": "2026-07-02T04:46:46.822669Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
ServiceName (elastic rule field) | eq | k8s.io | 4 rules | elastic |
kubernetes.audit.verb (elastic rule field) | in | get | 4 rules | elastic |
kubernetes.audit.verb (elastic rule field) | in | list | 4 rules | elastic |
EventType (elastic rule field) | eq | getsecretvalue | 1 rule | elastic |
EventType (elastic rule field) | eq | io.k8s.core.v1.secrets.get | 1 rule | elastic |
EventType (elastic rule field) | in | io.k8s.core.v1.secrets.get | 3 rules | elastic |
EventType (elastic rule field) | in | io.k8s.core.v1.secrets.list | 3 rules | elastic |
EventType (elastic rule field) | in | keyget | 1 rule | elastic |
kubernetes.audit.objectRef.resource (elastic rule field) | eq | secrets | 2 rules | elastic |
kubernetes.audit.objectRef.resource (elastic rule field) | in | configmaps | 2 rules | elastic |
kubernetes.audit.objectRef.resource (elastic rule field) | in | secrets | 2 rules | elastic |
username (panther rule field) | contains | serviceaccount | 2 rules | panther |
verb (panther rule field) | in | get | 2 rules | panther |
verb (panther rule field) | in | list | 2 rules | panther |
verb (panther rule field) | in | watch | 2 rules | panther |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → New-terms rule on The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule. This alert identifies a single source IP address accessing secret-management APIs across multiple cloud providers (e.g., AWS Secrets Manager, Google Secret Manager, Azure Key Vault) within a short timeframe. This behavior is strongly associated with credential theft, session hijacking, or token replay, where an adversary uses stolen authenticated sessions to harvest secrets across cloud environments. Unexpected cross-cloud secret retrieval is uncommon and typically indicates automation misuse or malicious activity. Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.Sigma #
T1552, T1552.007Elastic #
T1552, T1552.007, T1613Investigation guide
Triage and analysis#
Investigating GKE Secrets List from Unusual Source AS Organization#
user.email and source.as.number for cluster-wide or sensitive namespace secret list operations.Investigation steps#
gcp.audit.resource_name and whether listing was authorized.source.ip, source.as.organization.name, and follow-on secret get or exec activity.False positives#
Setup#
T1555, T1555.006↳ also matches get-secrets: get secrets Investigation guide
Triage and analysis#
Multiple Cloud Secrets Accessed by Source Address#
Possible investigation steps#
user_agent.original or equivalent fields against expected SDKs or automation tools.False positive analysis#
Response and remediation#
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-secrets: get secrets, watch-secrets: watch secrets, create-secrets: create secrets, update-secrets: update secrets, patch-secrets: patch secrets Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
Panther #
T1530, T1552.007T1552.007↳ also matches get-secrets: get secrets, watch-secrets: watch secrets
References #
watch secrets
#Description
Opens a long-lived watch on Secret changes across a namespace. Elastic's new-terms rule flags a first-seen client streaming secrets instead of polling.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/dw-harn/secrets?resourceVersion=1360&timeout=3s&watch=true",
"verb": "watch",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "secrets",
"namespace": "dw-harn",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestReceivedTimestamp": "2026-07-02T04:46:46.823738Z",
"stageTimestamp": "2026-07-02T04:46:49.827914Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
verb (panther rule field) | in | get | 2 rules | panther |
verb (panther rule field) | in | list | 2 rules | panther |
verb (panther rule field) | in | watch | 2 rules | panther |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload.Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-secrets: get secrets, list-secrets: list secrets, create-secrets: create secrets, update-secrets: update secrets, patch-secrets: patch secrets Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
Panther #
T1552.007↳ also matches get-secrets: get secrets, list-secrets: list secrets
References #
create secrets
#Description
Creates a new Secret. Sigma covers create alongside update/patch/delete; attackers stage a token or key this way, smuggled in as ordinary config.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/dw-harn/secrets?fieldManager=kubectl-create&fieldValidation=Strict",
"verb": "create",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "secrets",
"namespace": "dw-harn",
"name": "dw-harn-secrets",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 201
},
"requestObject": {
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "dw-harn-secrets",
"namespace": "dw-harn"
},
"data": {
"key": "dmFsdWU="
},
"type": "Opaque"
},
"responseObject": {
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "dw-harn-secrets",
"namespace": "dw-harn",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1360",
"creationTimestamp": "2026-07-02T04:46:46Z"
},
"data": {
"key": "dmFsdWU="
},
"type": "Opaque"
},
"requestReceivedTimestamp": "2026-07-02T04:46:46.628343Z",
"stageTimestamp": "2026-07-02T04:46:46.631258Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
kubernetes.audit.objectRef.resource (elastic rule field) | in | configmaps | 2 rules | elastic |
kubernetes.audit.objectRef.resource (elastic rule field) | in | secrets | 2 rules | elastic |
kubernetes.audit.verb (elastic rule field) | in | list | 2 rules | elastic |
objectRef.resource | eq | secrets | 2 rules | falco, sigma |
objectRef.namespace (falco rule field) | ne | kube-system | 1 rule | falco |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload. When Kubernetes operations are performed through Azure Arc Cluster Connect, the K8s audit log shows the Arc AAD proxy service account as the authenticated user, with the actual Azure AD identity in the Sigma #
Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-secrets: get secrets, list-secrets: list secrets, watch-secrets: watch secrets, update-secrets: update secrets, patch-secrets: patch secrets Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
system:serviceaccount:azure-arc:azure-arc-kube-aad-proxy-sa with the actual caller identity in the impersonatedUser field. This pattern indicates that someone is accessing the cluster through the Azure ARM API rather than directly via kubectl against the API server. While legitimate for Arc-managed workflows, adversaries with stolen service principal credentials can abuse Arc Cluster Connect to read, exfiltrate, or modify secrets and configmaps while appearing as the Arc proxy service account in K8s audit logs.T1213, T1530, T1552, T1552.007, T1565, T1565.001↳ also matches get-secrets: get secrets, list-secrets: list secrets, update-secrets: update secrets, patch-secrets: patch secrets, delete-secrets: delete secrets Investigation guide
Triage and analysis#
Investigating Kubernetes Secret or ConfigMap Access via Azure Arc Proxy#
impersonatedUser field. This rule detects non-system secret and configmap access — including reads, writes, and deletions — routed through this proxy path. Read operations (get, list) are particularly important to detect as they represent the most common adversary action: exfiltrating secrets without leaving obvious modification traces.Possible investigation steps#
kubernetes.audit.impersonatedUser.username field — this contains the Azure AD object ID of the actual caller. Cross-reference with Azure AD to identify the service principal or user.kubernetes.audit.impersonatedUser.extra.oid field for the Azure AD object ID.default or application namespaces are more suspicious than azure-arc or kube-system.kubernetes.audit.objectRef.name — look for suspicious secret/configmap names that don't match known application resources.LISTCLUSTERUSERCREDENTIAL operation that initiated the Arc proxy session.Response and remediation#
Falco #
References #
update secrets
#Description
Replaces a Secret's data wholesale. Same Sigma/Elastic write coverage as patch; Secrets hold tokens, TLS keys, and API credentials, so this is credential access.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/dw-harn/secrets/dw-harn-secrets?fieldManager=kubectl-replace&fieldValidation=Strict",
"verb": "update",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=4cf95d11cbd90036bab41cdc6b88cc8f91550e9135ed4bb61495b02f647812ff"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "secrets",
"namespace": "dw-harn",
"name": "dw-harn-secrets",
"uid": "00000000-0000-0000-0000-000000000000",
"apiVersion": "v1",
"resourceVersion": "508"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestObject": {
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "dw-harn-secrets",
"namespace": "dw-harn",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "508",
"creationTimestamp": "2026-07-02T21:30:08Z",
"labels": {
"dw-harn-patched": "1"
}
},
"data": {
"key": "dmFsdWU="
},
"type": "Opaque"
},
"responseObject": {
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "dw-harn-secrets",
"namespace": "dw-harn",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "508",
"creationTimestamp": "2026-07-02T21:30:08Z",
"labels": {
"dw-harn-patched": "1"
}
},
"data": {
"key": "dmFsdWU="
},
"type": "Opaque"
},
"requestReceivedTimestamp": "2026-07-02T21:30:11.768133Z",
"stageTimestamp": "2026-07-02T21:30:11.770730Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
objectRef.resource (sigma rule field) | eq | secrets | 1 rule | sigma |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload. When Kubernetes operations are performed through Azure Arc Cluster Connect, the K8s audit log shows the Arc AAD proxy service account as the authenticated user, with the actual Azure AD identity in the Sigma #
Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-secrets: get secrets, list-secrets: list secrets, watch-secrets: watch secrets, create-secrets: create secrets, patch-secrets: patch secrets Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
system:serviceaccount:azure-arc:azure-arc-kube-aad-proxy-sa with the actual caller identity in the impersonatedUser field. This pattern indicates that someone is accessing the cluster through the Azure ARM API rather than directly via kubectl against the API server. While legitimate for Arc-managed workflows, adversaries with stolen service principal credentials can abuse Arc Cluster Connect to read, exfiltrate, or modify secrets and configmaps while appearing as the Arc proxy service account in K8s audit logs.T1213, T1530, T1552, T1552.007, T1565, T1565.001↳ also matches get-secrets: get secrets, list-secrets: list secrets, create-secrets: create secrets, patch-secrets: patch secrets, delete-secrets: delete secrets Investigation guide
Triage and analysis#
Investigating Kubernetes Secret or ConfigMap Access via Azure Arc Proxy#
impersonatedUser field. This rule detects non-system secret and configmap access — including reads, writes, and deletions — routed through this proxy path. Read operations (get, list) are particularly important to detect as they represent the most common adversary action: exfiltrating secrets without leaving obvious modification traces.Possible investigation steps#
kubernetes.audit.impersonatedUser.username field — this contains the Azure AD object ID of the actual caller. Cross-reference with Azure AD to identify the service principal or user.kubernetes.audit.impersonatedUser.extra.oid field for the Azure AD object ID.default or application namespaces are more suspicious than azure-arc or kube-system.kubernetes.audit.objectRef.name — look for suspicious secret/configmap names that don't match known application resources.LISTCLUSTERUSERCREDENTIAL operation that initiated the Arc proxy session.Response and remediation#
References #
patch secrets
#Description
Modifies an existing Secret's data. Sigma and Elastic's Azure Arc proxy rule both flag this write as credential-access activity on a stored credential.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/dw-harn/secrets/dw-harn-secrets?fieldManager=kubectl-patch",
"verb": "patch",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "secrets",
"namespace": "dw-harn",
"name": "dw-harn-secrets",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestObject": {
"metadata": {
"labels": {
"dw-harn-patched": "1"
}
}
},
"responseObject": {
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "dw-harn-secrets",
"namespace": "dw-harn",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "1366",
"creationTimestamp": "2026-07-02T04:46:46Z",
"labels": {
"dw-harn-patched": "1"
}
},
"data": {
"key": "dmFsdWU="
},
"type": "Opaque"
},
"requestReceivedTimestamp": "2026-07-02T04:46:49.903267Z",
"stageTimestamp": "2026-07-02T04:46:49.907362Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
objectRef.resource (sigma rule field) | eq | secrets | 1 rule | sigma |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs. This rule detects interactive commands executed inside containers that use atypical utilities to hit the Kubernetes API, paired with near-simultaneous API activity on pods, secrets, service accounts, roles/bindings, or pod exec/attach/log/portforward. It surfaces hands-on-keyboard discovery and lateral movement using custom scripts that evade common tool allowlists; for example, an intruder opens a shell in a pod, uses Python to query the in-cluster API to list secrets, then triggers pods/exec to pivot into another workload. When Kubernetes operations are performed through Azure Arc Cluster Connect, the K8s audit log shows the Arc AAD proxy service account as the authenticated user, with the actual Azure AD identity in the Sigma #
Elastic #
T1059, T1059.004, T1069, T1087, T1609, T1610↳ also matches get-secrets: get secrets, list-secrets: list secrets, watch-secrets: watch secrets, create-secrets: create secrets, update-secrets: update secrets Investigation guide
Triage and analysis#
Investigating Direct Interactive Kubernetes API Request by Unusual Utilities#
Possible investigation steps#
False positive analysis#
Response and remediation#
system:serviceaccount:azure-arc:azure-arc-kube-aad-proxy-sa with the actual caller identity in the impersonatedUser field. This pattern indicates that someone is accessing the cluster through the Azure ARM API rather than directly via kubectl against the API server. While legitimate for Arc-managed workflows, adversaries with stolen service principal credentials can abuse Arc Cluster Connect to read, exfiltrate, or modify secrets and configmaps while appearing as the Arc proxy service account in K8s audit logs.T1213, T1530, T1552, T1552.007, T1565, T1565.001↳ also matches get-secrets: get secrets, list-secrets: list secrets, create-secrets: create secrets, update-secrets: update secrets, delete-secrets: delete secrets Investigation guide
Triage and analysis#
Investigating Kubernetes Secret or ConfigMap Access via Azure Arc Proxy#
impersonatedUser field. This rule detects non-system secret and configmap access — including reads, writes, and deletions — routed through this proxy path. Read operations (get, list) are particularly important to detect as they represent the most common adversary action: exfiltrating secrets without leaving obvious modification traces.Possible investigation steps#
kubernetes.audit.impersonatedUser.username field — this contains the Azure AD object ID of the actual caller. Cross-reference with Azure AD to identify the service principal or user.kubernetes.audit.impersonatedUser.extra.oid field for the Azure AD object ID.default or application namespaces are more suspicious than azure-arc or kube-system.kubernetes.audit.objectRef.name — look for suspicious secret/configmap names that don't match known application resources.LISTCLUSTERUSERCREDENTIAL operation that initiated the Arc proxy session.Response and remediation#
References #
delete secrets
#Description
Deletes a Secret, destroying credentials in use or covering tracks after copying its contents beforehand. The same Sigma secrets-modified-or-deleted rule matches this verb.
Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/dw-harn/secrets/dw-harn-secrets",
"verb": "delete",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=9bb0383c49b319fbf6b5ed61ab944378956d4292c784d32244ce2fa4dd846a3c"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "secrets",
"namespace": "dw-harn",
"name": "dw-harn-secrets",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"status": "Success",
"details": {
"name": "dw-harn-secrets",
"kind": "secrets",
"uid": "00000000-0000-0000-0000-000000000000"
},
"code": 200
},
"requestObject": {
"kind": "DeleteOptions",
"apiVersion": "meta.k8s.io/__internal",
"propagationPolicy": "Background"
},
"responseObject": {
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Success",
"details": {
"name": "dw-harn-secrets",
"kind": "secrets",
"uid": "00000000-0000-0000-0000-000000000000"
}
},
"requestReceivedTimestamp": "2026-07-02T04:46:49.968365Z",
"stageTimestamp": "2026-07-02T04:46:49.972561Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
objectRef.resource | eq | secrets | 2 rules | falco, sigma |
verb | eq | delete | 2 rules | falco, sigma |
objectRef.namespace (falco rule field) | ne | kube-system | 1 rule | falco |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries → When Kubernetes operations are performed through Azure Arc Cluster Connect, the K8s audit log shows the Arc AAD proxy service account as the authenticated user, with the actual Azure AD identity in the Sigma #
Elastic #
system:serviceaccount:azure-arc:azure-arc-kube-aad-proxy-sa with the actual caller identity in the impersonatedUser field. This pattern indicates that someone is accessing the cluster through the Azure ARM API rather than directly via kubectl against the API server. While legitimate for Arc-managed workflows, adversaries with stolen service principal credentials can abuse Arc Cluster Connect to read, exfiltrate, or modify secrets and configmaps while appearing as the Arc proxy service account in K8s audit logs.T1213, T1530, T1552, T1552.007, T1565, T1565.001↳ also matches get-secrets: get secrets, list-secrets: list secrets, create-secrets: create secrets, update-secrets: update secrets, patch-secrets: patch secrets Investigation guide
Triage and analysis#
Investigating Kubernetes Secret or ConfigMap Access via Azure Arc Proxy#
impersonatedUser field. This rule detects non-system secret and configmap access — including reads, writes, and deletions — routed through this proxy path. Read operations (get, list) are particularly important to detect as they represent the most common adversary action: exfiltrating secrets without leaving obvious modification traces.Possible investigation steps#
kubernetes.audit.impersonatedUser.username field — this contains the Azure AD object ID of the actual caller. Cross-reference with Azure AD to identify the service principal or user.kubernetes.audit.impersonatedUser.extra.oid field for the Azure AD object ID.default or application namespaces are more suspicious than azure-arc or kube-system.kubernetes.audit.objectRef.name — look for suspicious secret/configmap names that don't match known application resources.LISTCLUSTERUSERCREDENTIAL operation that initiated the Arc proxy session.Response and remediation#
Falco #
References #
deletecollection secrets
#Example Audit Event #
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "00000000-0000-0000-0000-000000000000",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/dw-harn/secrets?labelSelector=dw-harn-patched",
"verb": "deletecollection",
"user": {
"username": "kubernetes-admin",
"groups": [
"kubeadm:cluster-admins",
"system:authenticated"
],
"extra": {
"authentication.kubernetes.io/credential-id": [
"X509SHA256=3ffde68ef687218e01296d94b0aa59c81cc98de2bd73ab70e21510c8cd4b9cec"
]
}
},
"sourceIPs": [
"203.0.113.10"
],
"userAgent": "kubectl/v1.36.2 (linux/amd64) kubernetes/24e2b02",
"objectRef": {
"resource": "secrets",
"namespace": "dw-harn",
"apiVersion": "v1"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"responseObject": {
"kind": "SecretList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "571"
},
"items": [
{
"metadata": {
"name": "dw-harn-secrets",
"namespace": "dw-harn",
"uid": "00000000-0000-0000-0000-000000000000",
"resourceVersion": "571",
"creationTimestamp": "2026-07-02T23:12:08Z",
"labels": {
"dw-harn-patched": "1"
}
},
"data": {
"key": "dmFsdWU="
},
"type": "Opaque"
}
]
},
"requestReceivedTimestamp": "2026-07-02T23:12:12.545713Z",
"stageTimestamp": "2026-07-02T23:12:12.551013Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"kubeadm:cluster-admins\" of ClusterRole \"cluster-admin\" to Group \"kubeadm:cluster-admins\""
}
}
References #
any verb on secrets (synthetic aggregation)
#Description
Synthetic aggregation for rules that filter the secrets resource with no specific verb. Not a distinct audit record; hosts rule listings that key on objectRef.resource alone.
Common Indicators #
Field/value combinations most frequently checked by detection rules targeting this event, derived from cross-vendor predicate analysis.
| Field | Kind | Value | Rules | Vendors |
|---|---|---|---|---|
kubernetes.audit.objectRef.resource (elastic rule field) | eq | secrets | 4 rules | elastic |
EventType (elastic rule field) | in | get | 2 rules | elastic |
EventType (elastic rule field) | in | list | 2 rules | elastic |
user (elastic rule field) | is_not_null | | 1 rule | elastic |
user (elastic rule field) | starts_with | system:serviceaccount: | 1 rule | elastic |
Detection Rules #
Full rule details for this event, including ATT&CK technique mappings and native queries →Elastic #
T1552, T1552.007get/list) with a user agent matching a curated set of non-standard or attacker-leaning clients, for example minimal HTTP tooling, common scripting stacks, default library fingerprints, or distribution-tagged strings associated with offensive-security Linux images. Legitimate in-cluster automation usually presents stable, purpose-specific user agents (for example controller or client-go variants used by known components).T1552, T1552.007system:node:*) and workloads (system:serviceaccount:*) are meant to operate with tight, predictable API usage. Direct get or list on the Secrets API from those principals is often a sign of credential access. Attackers who stole a pod service-account token or node credentials sweep Secret objects for tokens, registry credentials, TLS keys, or application configuration. Even denied attempts still reveal intent to reach sensitive material. Legitimate controllers do read secrets they mount or manage, so this signal is most valuable when paired with triage (namespace scope, user agent, RBAC, and whether the identity should touch those secret names at all).T1552, T1552.007