Dónde viven los registros de auditoría de Kubernetes depende de quién maneje tu plano de control. En un clúster autogestionado, son un archivo de líneas JSON en el nodo del plano de control, en la ruta a la que apunta –audit-log-path. En EKS, van a CloudWatch Logs, en AKS a un espacio de trabajo de Log Analytics o cuenta de almacenamiento, y en GKE a Cloud Audit Logs. Algo se mantiene en todas partes: el registro de auditoría debe estar activado. En clústeres autogestionados y EKS está desactivado hasta que alguien lo habilita.
El registro de auditoría registra cada solicitud al API de Kubernetes: quién ejecutó kubectl exec en qué pod, quién leyó qué secreto, quién se unió al cluster-admin. Prime Core tiene 93 reglas de detección para datos de auditoría de Kubernetes, mapeadas a 220 técnicas de MITRE ATT&CK. Entre ellas: exec en contenedores en ejecución (T1609), despliegue de contenedores no autorizados (T1610) y lectura de credenciales a través del API del contenedor (T1552.007).
Antes de comenzar
¿Está habilitado?
| Plataforma | Dónde comprobar |
|---|---|
| Autogestionado (kubeadm y similar) | –audit-policy-file y –audit-log-path en el servidor API; con kubeadm, en /etc/kubernetes/manifests/kube-apiserver.yaml |
| EKS | Clúster → Observabilidad → registro del plano de control, tipo de registro “audit” |
| AKS | Configuraciones de diagnóstico en el clúster, categorías kube-audit o kube-audit-admin |
| GKE | Activado por defecto para actividad administrativa; el registro de acceso a datos para Kubernetes es opcional |
Si no estaba activado, no hay nada que exportar del pasado, y el resto de esta guía es para la próxima vez.
El detalle depende de la política. A nivel de Metadata verás quién hizo qué a qué objeto. En el nivel Request o RequestResponse también verás los cuerpos, por ejemplo, el espec del pod que pidió privileged: true. Conoce cuál tienes antes de buscar.
Espera volumen. Los controladores y cuentas de servicio hablan con el API constantemente. En AKS, kube-audit-admin excluye las llamadas get y list de solo lectura, manteniendo el tamaño sensato pero también ocultando lecturas secretas.
Expórtalo
Clúster autogestionado, en un nodo del plano de control:
# confirma primero la ruta
sudo grep -- '--audit-log-path' /etc/kubernetes/manifests/kube-apiserver.yaml
sudo cat /var/log/kubernetes/audit/audit.log > k8s_audit.jsonl
Los archivos rotados (de –audit-log-maxbackup) se colocan al lado con una marca de tiempo en el nombre. Inclúyelos si la ventana se extiende hacia atrás.
EKS, de CloudWatch Logs:
aws logs filter-log-events --log-group-name /aws/eks/my-cluster/cluster
--log-stream-name-prefix kube-apiserver-audit
--start-time $(date -d '2026-10-19T00:00:00Z' +%s000) --end-time $(date -d '2026-10-20T00:00:00Z' +%s000)
--output json | jq -c '.events[].message | fromjson' > eks_audit_1019.jsonl
Cada evento de CloudWatch envuelve la entrada de auditoría como una cadena; fromjson la desenvuelve. La sintaxis date -d es GNU; en macOS, calcula las marcas de tiempo en milisegundos de otra manera.
AKS, de Log Analytics (tablas específicas del recurso):
az monitor log-analytics query -w
--analytics-query "AKSAuditAdmin | where TimeGenerated between (datetime(2026-10-19) .. datetime(2026-10-20))"
--output json > aks_audit_1019.json
GKE, de Cloud Audit Logs:
gcloud logging read 'resource.type="k8s_cluster" AND logName:"cloudaudit.googleapis.com" AND timestamp>="2026-10-19T00:00:00Z" AND timestamp<"2026-10-20T00:00:00Z"'
--project=my-project --format=json | jq -c '.[]' > gke_audit_1019.jsonl
Qué buscar
| Solicitud | Por qué importa |
|---|---|
| create on pods/exec (objectRef.subresource: exec) | Alguien abrió un shell dentro de un contenedor en ejecución |
| create of a ClusterRoleBinding to cluster-admin | Escalamiento de privilegios a control total |
| get or list on secrets by an unusual identity | Recolección de credenciales |
| Pods creados con privileged, hostPath o hostNetwork | Un paso hacia escapar al nodo |
| user.username: system:anonymous with a 2xx response | Acceso anónimo que no debería funcionar |
| Explosiones de 403 de una cuenta de servicio | Un token robado probando sus permisos |
Sube, sanitiza y revisa en LogTotal
- Subir. Abre logtotal.com y carga el archivo .jsonl.
- Sanitiza. [what gets masked: usernames, service account names, source IPs, namespaces, object names]. Look it over before you continue.
- Revisa.
Cuando algo sale mal
| Síntoma | Causa probable | Fix |
|---|---|---|
| No hay archivo de auditoría en el plano de control | El servidor de API no tiene una política de auditoría configurada | Esperado; configúralo para el futuro |
| Falta el grupo de registros de EKS o corrientes de auditoría | El tipo de registro del plano de control “audit” no está activado | Habilítalo para el futuro |
| Cada línea es una larga cadena escapada | Envolvimiento de CloudWatch | Desenvuelve con fromjson, como arriba |
| Puedes ver quién cambió un pod, pero no cómo | La política está a nivel de Metadata | Eleva el nivel para recursos sensibles |
| No hay lecturas secretas en los datos de AKS | kube-audit-admin excluye get y list | Recopila kube-audit si los necesitas |
FAQ
¿No son suficientes los registros de contenedores?
No. Los registros de contenedores muestran lo que una aplicación imprimió. El registro de auditoría muestra lo que personas y cuentas de servicio hicieron al clúster. Preguntas diferentes, registros diferentes.
¿Puedo leer el archivo de auditoría en un clúster gestionado?
No. En EKS, AKS y GKE, no tienes acceso a los nodos del plano de control. El servicio de registro del proveedor es la única ruta.