37

Why does k8s secrets need to be base64 encoded when configmaps does not?

When creating a configmap you simply do somthing like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  SOME_KEY: a string value

But when you want to create a secret you have to echo -n "some secret string" | base64 and then put the result of that in a file looking something like this:

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  SOME_KEY: c29tZSBzZWNyZXQgc3RyaW5n

I really wonder why there is this difference? Are kubernetes secrets simply base64 encoded strings? I would expect that secrets were stored encrypted in kubernetes.

3 Answers3

41

Secrets can contain binary data (the type is map[string][]byte), and byte arrays are base64-encoded in JSON serialization.

ConfigMaps only contain string data (the type is map[string]string), so the JSON serialization just outputs the string.

In 1.10, ConfigMaps have a new binaryData field that allows storing binary data, which is base64-encoded, just like secrets. https://github.com/kubernetes/kubernetes/pull/57938

Jordan Liggitt
  • 16,933
  • 2
  • 56
  • 44
  • 1
    what do you mean "byte arrays are base64 encoded", please have a look at this https://stackoverflow.com/a/12178544/2704032, how can you say secrets can contain binary data isn't everything can be represented in binary? – Vishrant Jun 26 '19 at 14:54
18

Why does k8s secrets need to be base64 encoded

This allows you to provide binary data (certificates etc.) as secret, and also escape any tricky characters such as " ' \ etc.

Are kubernetes secrets simply base64 encoded strings?

Yes, kubernetes secrets are not encrypted by default. You have to set up encryption at rest on your own, see https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/

Victor Wong
  • 3,457
  • 1
  • 18
  • 31
7

According to ConfigMap's docs, a ConfigMap object can have 'data' and 'binaryData' fields.The data field is designed to contain UTF-8 strings while the binaryData field is designed to contain binary data as base64-encoded strings. Therefore, ConfigMaps also can have base64 data in it. But this option is positioned as secondary I would say, 'data' field is used much frequently.

According to Secret's docs, a Secret object can specify the 'data' and/or the 'stringData'. The values for all keys in the data field have to be base64-encoded strings. If the conversion to base64 string is not desirable, you can choose to specify the stringData field instead, which accepts arbitrary strings as values. So, here, in contrary to ConfigMaps, binary approach is considered as primary, as used more frequently.

But we should understand that base64 encoding is not a an encryption, it does not protect your secrets from being used. All who have access to Pods/Deployments in namespace X, can access Secret objects in this namespace. So, these people can simply decode these base64 string to plain ones.

I haven't found any official explanation why the primary way for storing Secrets data is base64, but I have a hypothesis that it is made at least for visual defense, in order to make to see and remember them buy eyes complex maybe.

  • Not saying that your hypothesis is wrong. When using base64 encoding to obscure secrets from beeing seen, these secrets are not really secure to begin with. E,g, a secret which is just a word that is easy to read and remember can be obscured with base64. On the other side a secret with 32 random chars is already obscure enough to not be remembered when seen by someone. Of course this does not apply to screen recordings but then again base64 would also not help. – chronicc Dec 22 '22 at 14:13
  • The `stringData` here is the answer I think the OP (and myself) was looking for. Thank you so much Bohdan! – TopherGopher Apr 19 '23 at 19:52