A Kubernetes Secret stores the values your workloads read at runtime: database passwords, API keys, TLS private keys and registry credentials. Anyone who reads the manifest or the Secret object gets those values, and the file format does not protect them, because the values are only encoded. Rotate every value the Secret held, not just the file, since the manifest is the copy you can see and the cluster may hold others.
Check your GitHub account for leaked secrets — free
- Provider
- Other
- Severity
- Critical
- Impact
- Cloud infrastructure access
- Checked live by LeakWatch
- No
What a Kubernetes Secret YAML looks like
A Secret manifest is a YAML file with kind: Secret near the top and a data block below it. Each entry in data is a name followed by an encoded value:
apiVersion: v1
kind: Secret
metadata:
name: app-credentials
type: Opaque
data:
password: …XXXX
The values are base64 strings. Base64 is an encoding, not encryption, so anyone who has the string has the secret. A manifest that uses stringData instead holds the values in plain text, and the cluster encodes them when it stores the object. Either way, kubectl get secret -o yaml prints the same encoded values, so a leaked kubeconfig with read access to Secrets exposes them too. The kind: Secret line and the data block together are what identify the file. A base64 string on its own says nothing.
How Kubernetes Secret YAML files get leaked
- Manifests committed with values filled in. A Secret written by hand and saved in the repository, instead of being generated at deploy time.
- Helm values and Kustomize overlays. Real passwords stored in values files next to the templates.
- Debug output. A
kubectl get secret -o yamlresult pasted into an issue, a chat thread or a ticket to troubleshoot a deployment. - Namespace backups. Exports saved to a shared drive or to a storage bucket with open access.
- Broad kubeconfig files. Configuration with wide read rights copied onto laptops and CI runners, which lets whoever holds it read every Secret in scope.
What to do in the first hour
- Identify the Secret. Read the
nameandnamespacein the manifest, then check which workloads mount it or read its values. Only then do you know which systems need new credentials. - Rotate the credentials at their source first. A new value in the cluster does nothing if the old password still works in the database or the old key still works at the vendor. Create the new credential where the value belongs.
- Update the Secret in the cluster. Apply the new value through your deployment tool, not with a command that leaves the value in shell history. Pods that read the value as environment variables must be restarted. Mounted files update on their own, but confirm that in your setup.
- Remove the old value from the source. Delete the file with real values or replace them with placeholders, and stop committing generated manifests.
- Check who read it. If your cluster has audit logging, search for
getandlistrequests against Secrets in that namespace during the exposure window. Without audit logs, assume the values were read. - Review access. Check which service accounts and users can read Secrets in that namespace, and remove rights they do not need.
- Clean the repository. See I accidentally pushed an API key to GitHub for the history rewrite steps, and deep scan your whole git history to find older copies.
Not sure what else leaked? Run a free scan.
Revoke it at Kubernetes
Kubernetes has no single key to revoke. The fix is to rotate each value in the Secret and to rotate the credential behind it at its own provider. Start from the list of keys in the manifest and follow each one to its source, such as the database, the cloud account, or the vendor’s API keys page. Once the old credential is disabled, the value in the leaked file is worthless. Keep the old Secret only until the new one is confirmed in production, then delete it.
How LeakWatch detects it
The rule is called Kubernetes Secret YAML. It looks for a kind: Secret line and, within a couple of hundred characters, a data: block whose entry holds a base64-looking value of at least ten characters, an empty value, or a template placeholder. The order can be reversed, with the data: block first and kind: Secret after it. Matching is not case-sensitive. Plain manifests without a Secret kind, and Secrets whose data entries are too short to look like encoded values, are not reported. The severity is critical. This type is not checked live: LeakWatch does not contact your cluster or any provider with the values it finds.
LeakWatch detects this format but does not check it live: it can tell you the key is exposed, not whether it still works. Assume it does until you have revoked it.
FAQ
Is a base64 Secret value encrypted?
No. Base64 is a reversible text encoding. Unless your cluster enables encryption at rest for Secrets, the values are stored in a form that anyone with API access can read, and a leaked manifest gives them away at once.
If I delete the Secret object, is the leak fixed?
No. Deleting it stops workloads from getting new values, but the value in the leaked file still works until you rotate it at its source. Deletion is part of the cleanup, not the fix.
Do I have to rotate everything in the namespace?
Rotate every value that was in the leaked Secret. If you cannot tell whether other Secrets in the same namespace were read, rotate those too.