HIGH Kubernetes Audit Log Secret / Credential Exfiltration LTR-0009 ✓ validated

Detect Kubernetes Secret Exfiltration in Audit Logs

MITRE ATT&CK: T1552.007T1078

Sigma Rule

title: Kubernetes Secret Access / Exfiltration
id: 3d9c1f75-6b48-4a29-8e17-5f2b7c4a1e09
status: experimental
description: >
  Detects read access (get/list/watch) to Kubernetes Secrets by users or service
  accounts outside the known controller allowlist — the core action in credential
  exfiltration from a compromised cluster. Pair with clusterrolebinding creation
  for a full escalate-then-loot signal.
references:
  - https://attack.mitre.org/techniques/T1552/007/
author: LogTriage
date: 2026/07/01
logsource:
  product: kubernetes
  service: audit
detection:
  selection:
    objectRef.resource: 'secrets'
    verb:
      - 'get'
      - 'list'
      - 'watch'
  filter_controllers:
    user.username|startswith:
      - 'system:serviceaccount:kube-system:'
      - 'system:serviceaccount:cert-manager:'
      - 'system:serviceaccount:external-secrets:'
  condition: selection and not filter_controllers
falsepositives:
  - Legit secret-consuming controllers/operators (allowlist their SAs)
  - Documented, time-boxed platform debugging
level: high
tags:
  - attack.credential_access
  - attack.t1552.007

What this rule detects

Kubernetes Secrets hold database passwords, cloud credentials, and API tokens. Exfiltrating them is a top post-compromise objective, and in the audit log it’s a clean signal: get/list/watch on objectRef.resource: secrets by a user or service account that isn’t a known secret-consuming controller.

This rule fires on Secret reads outside the filter_controllers allowlist.

Detection logic

Everything hinges on the allowlist. Legit controllers (cert-manager, external-secrets, CSI, core kube-system SAs) read Secrets constantly — allowlist them, and what remains is suspicious by default: a human kubectl get secret, or an unexpected SA enumerating Secrets. Bulk list and access right after a clusterrolebindings create (escalation) are the strongest confirmations.

LogTriage’s K8s exfiltration detection correlates the escalate-then-loot sequence so it reads as one incident.

Validated against a real sample

Validated against k8s_exec_secret_exfil.json (shipped with LogTriage): a new clusterrolebindings create for attacker-admin, then get on Secrets named aws-credentials and db-credentials, plus a pods/exec. The rule fires on that sample and stays silent on the matching benign operations log.

False positives

Secret-consuming controllers/operators are the main source — that’s what filter_controllers handles. A platform engineer debugging is a real (documented, time-boxed) exception. Anything else reading Secrets deserves a look.

Frequently Asked Questions

Won't this fire constantly — lots of things read Secrets?
That's why the rule allowlists the known secret-consuming service accounts (kube-system, cert-manager, external-secrets, CSI drivers). What's left is a human user or an unexpected service account reading Secrets — which is exactly the signal you want. Tune filter_controllers to your cluster.
What makes this exfiltration versus normal access?
Context: a get/list on Secrets from a user or SA that never normally touches them, especially bulk (list all secrets) or right after a privilege-escalation event (a new clusterrolebinding). LogTriage correlates the escalate-then-read sequence into one incident.
Should I also watch pods/exec?
Yes — attackers often exec into a pod to read mounted secrets or the service-account token, bypassing the Secrets API. A companion rule on verb=create against objectRef.resource=pods/exec is worth adding; this sample includes that pattern too.

Related Resources

See this detection run on a real report

Try the live demo with a pre-loaded malicious log set — no signup required — or upload your own log file and get a full AI-reviewed threat report in minutes.