How to identify unused secrets in Kubernetes?

9/25/2017

I want to rename my k8s Secrets and want to check if there are unused Secrets. Also I would like to know how many and which containers reference a Secret.

Is there a easier way to do this than search for the secret names in all deployments?

-- adebasi
kubectl
kubernetes

2 Answers

9/25/2017

Thanks Simon. Based on your answer I created a diff, which shows secrets that are not referenced in the containers env section. Secrets can also be referenced in:

  • TLS section of Ingresses
  • Pods Volumes spec, like Simon mentioned
  • ImagePullSecrets for private repositories

But for me it is enough to find secrets that are not referenced in environment variables:

diff \
<(kubectl get pods -o jsonpath='{.items[*].spec.containers[*].env[*].valueFrom.secretKeyRef.name}' | xargs -n1 | sort | uniq) \
<(kubectl get secrets -o jsonpath='{.items[*].metadata.name}' | xargs -n1 | sort | uniq)

Update 16.04.2018

I created a more advanced version to find also secrets referenced in volumes, ingress tls and imagePullSecrets. This snippet will show you all unused secrets for the current namespace:

envSecrets=$(kubectl get pods -o jsonpath='{.items[*].spec.containers[*].env[*].valueFrom.secretKeyRef.name}' | xargs -n1)
volumeSecrets=$(kubectl get pods -o jsonpath='{.items[*].spec.volumes[*].secret.secretName}' | xargs -n1)
pullSecrets=$(kubectl get pods -o jsonpath='{.items[*].spec.imagePullSecrets[*].name}' | xargs -n1)
tlsSecrets=$(kubectl get ingress -o jsonpath='{.items[*].spec.tls[*].secretName}' | xargs -n1)

diff \
<(echo "$envSecrets\n$volumeSecrets\n$pullSecrets\n$tlsSecrets" | sort | uniq) \
<(kubectl get secrets -o jsonpath='{.items[*].metadata.name}' | xargs -n1 | sort | uniq)
-- adebasi
Source: StackOverflow

9/25/2017

There is no intended way to list unused Secrets because Secrets themselves do not hold reference of usage. One solution would be to parse all Containers/Pods for usage of secrets as mounts and environment variables to match against your list of secrets. kubectl get supports JSONPath and makes that pretty easy:

Retrieve secrets used as mounts

kubectl get pods --all-namespaces -o jsonpath='{.items[*].spec.volumes[*].secret.secretName}' | xargs -n1 | uniq

Retrieve secrets used as environment variables

kubectl get pods --all-namespaces -o jsonpath='{.items[*].spec.containers[*].env[*].valueFrom.secretKeyRef.name}' | xargs -n1 | uniq
-- Simon Tesar
Source: StackOverflow