'What does adding a secret to a ServiceAccount in Kubernetes do?

I am reading the tekton docs on authentication it explains that two things are needed to do authentication

Create a secret docs give example below

apiVersion: v1
kind: Secret
metadata:
 name: basic-user-pass
 annotations:
   tekton.dev/git-0: https://github.com # Described below
type: kubernetes.io/basic-auth
stringData:
 username: <username>
 password: <password>

Add secret object to the service account

apiVersion: v1
kind: ServiceAccount
metadata:
 name: build-bot
secrets:
 - name: basic-user-pass

My mental model of a service account in k8s is that it is a JWT used to access the k8s API server. I don't understand what's point of adding a secret to the ServiceAccount, how and why it is used.

Questions:

  • what does it mean for a service account to have secrets added to it?
  • Why is it useful to add a secret to a service account?
  • Why does tekton require the secret to be added to the service account?
  • who/what looks at the service account secrets list?


Solution 1:[1]

hope you are enjoying your kubernetes journey !

1) what does it mean for a service account to have secrets added to it? / Why is it useful to add a secret to a service account?

Fist of all, a little remider:

As you may know, you have to see the serviceAccount as a user for a machine/an application/a script (and not only in kubernetes) in short, everything that is not human. As a human a service account, in order to authenticate to things (Git repository/docker registry or API that require authentication, needs to have credentials (username+password).

In Kubernetes this credentials and especially the password are stored in "secrets".

Now, you should be aware that each namespace in kubernetes has a native service account named "default" that is associated with every running pod and that service account is linked to a native "default" kubernetes secret that is also present in all namespaces. This "default" secret contains the ca.crt and a token that let the pod to make calls to the internal Kubernetes API Server endpoint among other things.

Since the secrets that contains the "credentials" is linked to a service account that is mounted to a pod, this pod can then be able to authenticate to things that require authentication.

For example if someday you'll have to use a private docker registry to pull your images, you can do this in two ways, In each of them you have to create a secret first that will contain your sensitive data (crendentials):

  • The first way consist of adding your secret name,that contains the registry credentials directly in the default serviceAccount (that, as a reminder, is mounted by default in the pod, or in a new created serviceAccount (like tekton is doing in your case) that will be added to the kubernetes deployment manifest in the field serviceAccountName:.
  • The second way consist of adding the field imagePullSecret in your kubernetes deployment manifest.

This way, when kubernetes comes to pull your private docker image, it will check if the needed credentials that are in the serviceAccount secrets works, if not it will check the secret you have added in the imagePullSecret field (or the opposite) and it will be able to connect to the registry and pull the image to run it as a container in a pod !

2) who/what looks at the service account secrets list?

For example in a brand new namespace:

? k get sa
NAME      SECRETS   AGE
default   1         30m

This default serviceAccount is linked to a secret named "default-token-r4vrb":

? k get sa default -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2022-05-06T08:48:38Z"
  name: default
  namespace: so-tests
  resourceVersion: "1771"
  uid: c3598708-ad14-4806-af31-5c54d60e29b7
secrets:
- name: default-token-r4vrb

This default-token secret contains what is needed to authenticate the Kubernetes APi endpoint (certificate + token):

? k get secret default-token-r4vrb -o yaml
apiVersion: v1
data:
  ca.crt: base64encodedCaCertificate
  namespace: base64encodedNamespace
  token: base64encodedToken
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: default
    kubernetes.io/service-account.uid: c3598708-ad14-4806-af31-5c54d60e29b7
  creationTimestamp: "2022-05-06T08:48:38Z"
  name: default-token-r4vrb
  namespace: so-tests
  resourceVersion: "1770"
  uid: d342a372-66d1-4c92-b520-23c23babc798
type: kubernetes.io/service-account-token

3) Why does tekton require the secret to be added to the service account? who/what looks at the service account secrets list?

Now I hope you know why, they choose to use a serviceAccount to do this but they could have just mounted the secret into the pod directly also :)

Hope this has helped you. Here is some docs to be more familiar with K8S SA: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

bguess/

Solution 2:[2]

  • what does it mean for a service account to have secrets added to it?

secret store its jwt token for auth.

  • Why is it useful to add a secret to a service account?

Actually, kubernetes will create the token by default, you don't need to add the secret. Unless you want to manually create token. But your secret is wrong. Right one should be

apiVersion: v1
kind: Secret
metadata:
  name: build-robot-secret
  annotations:
    kubernetes.io/service-account.name: build-robot
type: kubernetes.io/service-account-token

Notice the type.

  • Why does token require the secret to be added to the service account?

As I said, k8s need jwt token for api server auth. check this

  • who/what looks at the service account secrets list?

You can login the pod and cat /run/secrets/kubernetes.io/serviceaccount/token

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 bguess
Solution 2 T.R