GKE Certificate Signing Request Self-Approved
Description
Detects when the same non-system GKE identity creates a CertificateSigningRequest (CSR) and then approves that same CSR within five minutes, consistent with self-approval abuse. Attackers who gain CSR create and approval RBAC can submit a certificate request and approve it themselves to obtain a long-lived client certificate without involving cluster operators, a pattern documented in Kubernetes persistence research and adversary emulation.
Query · esql
from logs-gcp.audit-* metadata _id, _index, _version
| where data_stream.dataset == "gcp.audit"
and service.name == "k8s.io"
and event.outcome == "success"
and event.action in (
"io.k8s.certificates.v1.certificatesigningrequests.create",
"io.k8s.certificates.v1.certificatesigningrequests.approval.update"
)
and client.user.email is not null
and gcp.audit.resource_name is not null
and not client.user.email in (
"system:gcp-controller-manager",
"system:kube-controller-manager",
"system:serviceaccount:kube-system:certificate-controller",
"kubelet-bootstrap",
"kubelet-nodepool-bootstrap"
)
and not client.user.email like "system:node:*"
| eval Esql.csr_name = replace(gcp.audit.resource_name, "/approval", "")
| stats
Esql.create_count = count(*) where event.action == "io.k8s.certificates.v1.certificatesigningrequests.create",
Esql.approval_count = count(*) where event.action == "io.k8s.certificates.v1.certificatesigningrequests.approval.update",
Esql.event_action_values = values(event.action),
Esql.timestamp_first_seen = min(@timestamp),
Esql.timestamp_last_seen = max(@timestamp),
Esql.source_ip_values = values(source.ip),
Esql.user_agent_original_values = values(user_agent.original),
Esql.data_stream_namespace_values = values(data_stream.namespace)
by client.user.email, Esql.csr_name
| where Esql.create_count >= 1
and Esql.approval_count >= 1
and date_diff("seconds", Esql.timestamp_first_seen, Esql.timestamp_last_seen) <= 300
| keep client.user.email, Esql.*
Investigation fields
Pivot points the source recommends for triage.
client.user.emailEsql.csr_nameEsql.create_countEsql.approval_countEsql.event_action_valuesEsql.timestamp_first_seenEsql.timestamp_last_seenEsql.source_ip_valuesEsql.user_agent_original_valuesEsql.data_stream_namespace_values
Implementation guide
The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule.
Known false positives
- Automation that both submits and approves CSRs in one workflow may trigger this rule. Baseline cert-manager or internal PKI pipelines and tune exclusions for known service accounts.
Analyst notes
Investigating GKE Certificate Signing Request Self-Approved
This rule groups CSR create and approval events by client.user.email and normalized CSR name (Esql.csr_name).
GKE logs approval on subresource paths (.../csr-name/approval), so the query strips /approval suffixes before
correlating. An alert means the same identity both submitted and approved the same CSR within five minutes, a strong
indicator of manual self-approval rather than normal system:gcp-controller-manager auto-approval of node
certificates.
Possible investigation steps
- Review
Esql.event_action_valuesfor the sequence of create followed byapproval.update. - Inspect
gcp.audit.request.spec.signerNameand decodegcp.audit.request.spec.requeston create events for the requested identity. - Validate whether the actor should hold both CSR create and approval permissions.
- Hunt for subsequent API activity authenticated as the minted certificate identity.
False positive analysis
- cert-manager or internal PKI automation that creates and approves CSRs under the same service account in one workflow.
- GitOps or bootstrap tooling that submits and signs CSRs programmatically. Baseline known automation and tune exclusions for those principals.
- Two unrelated CSR events from the same user within five minutes should not match because the query requires at least one create and one approval-class action on the same normalized CSR name.
Related rules
- GKE Certificate Signing Request API Client Signer Requested - 1e344fba-a2f7-462b-aaec-d6c8f80d5a28
- GKE Certificate Signing Request Privileged Identity Requested - 4159bec9-76ad-4cdc-a797-4a8572073bbe
- GKE Client Certificate Signing Request Created or Approved - ec67ab57-945a-4edb-84f8-1d7a51f46544
Response and remediation
- Revoke or deny the CSR, remove approval RBAC from untrusted principals, and rotate cluster signing credentials if abuse is confirmed.