Detect Kubernetes Secret Exfiltration in Audit Logs
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.