Decoding Kubernetes Ingress auth Secrets

Update: In the comments, the following one-liner is suggested by Matt T if you have jq installed (a handy utility if there ever was one!):

kubectl get secret my-secret -o json | jq '.data | map_values(@base64d)'

I figured it would be handy to have a quick reference for this, since I'll probably forget certain secrets many, many times in the future (I'm like that, I guess):

I have a Kubernetes Secret used for Traefik ingress basic HTTP authentication (using annotation ingress.kubernetes.io/auth-secret), and as an admin with kubectl access, I want to see (or potentially modify) its structure.

Let's say the Secret is in namespace testing, and is named test-credentials. To get the value of the basic auth credentials I do:

kubectl get secret test-credentials -n testing -o yaml

This spits out the Kubernetes object definition, including a field like:

data:
  auth: [redacted base64-encoded string]

So then I copy out that string and decode it:

echo '[redacted base64-encoded string]' | base64 --decode

And now I have a set of one or more basic HTTP auth credentials; in my case they were encrypted with MD5 encryption, since they were prefixed by $apr1$ (see Apache password encryptions docs). If I want to update the secret with a new password, I can add it by generating the string with htpasswd, then adding it to the data, then base64 encoding it, then modifying the Secret with the new value!

(For production clusters, though, I store all my Kubernetes objects as YAML manifest files in code, so I would make the appropriate changes there then apply the changes using (at least, in my case) Ansible. So this would be a lot less complicated.)

Comments

You could also use a newer feature added to the jq cli to retrieve the base64 decoded values a bit quicker:

kubectl get secret my-secret -o json | jq '.data | map_values(@base64d)'

If you need jq: https://stedolan.github.io/jq

Or if you really want to get crazy like I do, you can create an alias so that you can just do ds my-secret:

function decode_kubernetes_secret {
  kubectl get secret $@ -o json | jq '.data | map_values(@base64d)'
}
alias ds="decode_kubernetes_secret"

Even newer:

kubectl get secret test-credentials -n testing -o go-template='{{.data.whatever | base64decode}}'

Note that you need to have jq version 1.6+ to use the `base64d` function.

```
$ jq --version
jq-1.6

$ echo '{"foo": "Ym9iIGxpa2VzIGFsaWNlCg=="}' | jq '{encoded: .foo, decoded: .foo | @base64d}'
{
"encoded": "Ym9iIGxpa2VzIGFsaWNlCg==",
"decoded": "bob likes alice\n"
}
```