Kubernetes namespace default service account
Asked Answered
T

4

33

If not specified, pods are run under a default service account.

  • How can I check what the default service account is authorized to do?
  • Do we need it to be mounted there with every pod?
  • If not, how can we disable this behavior on the namespace level or cluster level.
  • What other use cases the default service account should be handling?
  • Can we use it as a service account to create and manage the Kubernetes deployments in a namespace? For example we will not use real user accounts to create things in the cluster because users come and go.

Environment: Kubernetes 1.12 , with RBAC

Teat answered 25/10, 2018 at 18:34 Comment(0)
C
79
  1. A default service account is automatically created for each namespace.

    $ kubectl get serviceaccount
    NAME    SECRETS   AGE
    default   1       1d
    
  2. Service accounts can be added when required. Each pod is associated with exactly one service account but multiple pods can use the same service account.

  3. A pod can only use one service account from the same namespace.

  4. Service account are assigned to a pod by specifying the account’s name in the pod manifest. If you don’t assign it explicitly the pod will use the default service account.

  5. The default permissions for a service account don't allow it to list or modify any resources. The default service account isn't allowed to view cluster state let alone modify it in any way.

  6. By default, the default service account in a namespace has no permissions other than those of an unauthenticated user.

  7. Therefore pods by default can’t even view cluster state. Its up to you to grant them appropriate permissions to do that.

    $ kubectl exec -it test -n foo sh / # curl
    localhost:8001/api/v1/namespaces/foo/services {   "kind": "Status",  
    "apiVersion": "v1",   "metadata": {
    
        },   "status": "Failure",   "message": "services is forbidden: User
    \"system:serviceaccount:foo:default\" cannot list resource
    \"services\" in API group \"\" in the namespace \"foo\"",   "reason":
    "Forbidden",   "details": {
        "kind": "services"   },   "code": 403
    

    as can be seen above the default service account cannot list services

    but when given proper role and role binding like below

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: foo-role
      namespace: foo
    rules:
    - apiGroups:
      - ""
      resources:
      - services
      verbs:
      - get
      - list
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      creationTimestamp: null
      name: test-foo
      namespace: foo
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: foo-role
    subjects:
    - kind: ServiceAccount
      name: default
      namespace: foo
    

    now I am able to list the resource service

    $ kubectl exec -it test -n foo sh
    / # curl localhost:8001/api/v1/namespaces/foo/services
    {
      "kind": "ServiceList",
      "apiVersion": "v1",
      "metadata": {
        "selfLink": "/api/v1/namespaces/bar/services",
        "resourceVersion": "457324"
      },
      "items": []
    
  8. Giving all your service accounts the clusteradmin ClusterRole is a bad idea. It is best to give everyone only the permissions they need to do their job and not a single permission more.

  9. It’s a good idea to create a specific service account for each pod and then associate it with a tailor-made role or a ClusterRole through a RoleBinding.

  10. If one of your pods only needs to read pods while the other also needs to modify them then create two different service accounts and make those pods use them by specifying the serviceaccountName property in the pod spec.

You can refer the below link for an in-depth explanation.

Service account example with roles

You can check kubectl explain serviceaccount.automountServiceAccountToken and edit the service account

kubectl edit serviceaccount default -o yaml

apiVersion: v1
automountServiceAccountToken: false
kind: ServiceAccount
metadata:
  creationTimestamp: 2018-10-14T08:26:37Z
  name: default
  namespace: default
  resourceVersion: "459688"
  selfLink: /api/v1/namespaces/default/serviceaccounts/default
  uid: de71e624-cf8a-11e8-abce-0642c77524e8
secrets:
- name: default-token-q66j4

Once this change is done whichever pod you spawn doesn't have a serviceaccount token as can be seen below.

kubectl exec tp -it bash
root@tp:/# cd /var/run/secrets/kubernetes.io/serviceaccount
bash: cd: /var/run/secrets/kubernetes.io/serviceaccount: No such file or directory
Counterpunch answered 25/10, 2018 at 21:38 Comment(6)
Thanks , the question still remains , how can I list what verbs are allowed to default service account in a namespace , and how can we disable mounting the default service account token into the pod by defualt , on namepsace or cluster level , and is it mandatory to run pod with default service accountTeat
No verbs are allowed for default service account as i explained with an example above. You need to associate service account with a role or clusterrole as explained in point no 9. You can check "kubectl explain serviceaccount.automountServiceAccountToken" this allows you to give boolean values . setting it to false wont mount service account token. Every pod comes with a service account with no access this is for securityCounterpunch
kubectl edit serviceaccount default -o yaml apiVersion: v1 automountServiceAccountToken: false kind: ServiceAccount metadata: creationTimestamp: 2018-10-14T08:26:37Z name: default namespace: default resourceVersion: "459688" selfLink: /api/v1/namespaces/default/serviceaccounts/default uid: de71e624-cf8a-11e8-abce-0642c77524e8 secrets: - name: default-token-q66j4Counterpunch
> "By default, the default service account in a namespace has no permissions other than those of an unauthenticated user." ------ Thank you!!! I really wish that statement is in the Kubernetes official documentation. I've spent a whole day reading the product docs of Kubernetes, Istio, people's blogs, etc., trying to hunt down that fact. None of them would simply say what you just said, or give a tutorial-style sequence of commands (like yours) so that I'd learn how to experiment myself. Your answer is great -- it leaves no lingering doubts of what the default functionality is.Exotic
I really like this answer except that it doesn't provide any references. I haven't found any official docs yet that confirm what this post says. Eg this other post says "... the default service account permissions are effectively read-write within the namespace and global read for most resource types." It is not clear how the author gets to that conclusion, and whether it still applies. I experimented by using kubectl auth can-i, see my answer on this page.Watertight
Reference: as a cluster admin do this: kubectl --as=system:serviceaccounts:some_namespace:some_service_account auth can-i get pods -n some_namespaceDesberg
G
4

An application/deployment can run with a service account other than default by specifying it in the serviceAccountName field of a deployment configuration.

What I service account, or any other user, can do is determined by the roles it is given (bound to) - see roleBindings or clusterRoleBindings; the verbs are per a role's apiGroups and resources under the rules definitions.

The default service account doesn't seem to be given any roles by default. It is possible to grant a role to the default service account as described in #2 here.

According to this, "...In version 1.6+, you can opt out of automounting API credentials for a service account by setting automountServiceAccountToken: false on the service account".

HTH

Glaydsglaze answered 26/10, 2018 at 2:13 Comment(1)
what are the use cases for default service account , can and should we use it as a service account to create and manage the k8s deployments in a namsepace? , for example we will not use real user accounts to create things in the cluster becuase users come and go in teamTeat
W
3
  • How can I check what the default service account is authorized to do?

There isn't an easy way, but auth can-i may be helpful. Eg

$ kubectl auth can-i get pods --as=system:serviceaccount:default:default
no

For users there is auth can-i --list but this does not seem to work with --as which I suspect is a bug. In any case, you can run the above commands on a few verbs and the answer will be no in all cases, but I only tried a few. Conclusion: it seems that the default service account has no permissions by default (since in the cluster where I checked, we have not configured it, AFAICT).

  • Do we need it to be mounted there with every pod?

Not sure what the question means.

  • If not, how can we disable this behavior on the namespace level or cluster level.

You can set automountServiceAccountToken: false on a service or an individual pod. Service accounts are per namespace, so when done on a service account, any pods in that namespace that use this account will be affected by that setting.

  • What other use cases the default service account should be handling?

The default service account is a fallback, it is the SA that gets used if a pod does not specify one. So the default service account should have no privileges whatsoever. Why would a pod need to talk to the kube API by default?

  • Can we use it as a service account to create and manage the Kubernetes deployments in a namespace?

I don't recommend that, see previous answer. Instead, you should create a service account (bound to appropriate role/clusterrole) for each pod type that needs access to the API, following principle of least privileges. All other pod types can use default service account, which should not mount SA token automatically and should not be bound to any role.

Watertight answered 24/11, 2021 at 18:25 Comment(1)
> kubectl auth can-i --list --as=system:serviceaccount:<namespace>:<serviceaccount> -n <namespace> i.e. kubectl auth can-i --list --as=system:serviceaccount:testns:default -n testnsLoom
L
1
kubectl auth can-i --list --as=system:serviceaccount:<namespace>:<serviceaccount> -n <namespace>

as a simple example. to check the default service account in the testns namespace

kubectl auth can-i --list --as=system:serviceaccount:testns:default -n testns 

Resources                                       Non-Resource URLs                     Resource Names     Verbs
selfsubjectaccessreviews.authorization.k8s.io   []                                    []                 [create]
selfsubjectrulesreviews.authorization.k8s.io    []                                    []                 [create]
                                                [/.well-known/openid-configuration]   []                 [get]
                                                [/api/*]                              []                 [get]
                                                [/api]                                []                 [get]
                                                
                                                [ ... ]
                                                
                                                [/readyz]                             []                 [get]
                                                [/version/]                           []                 [get]
                                                [/version/]                           []                 [get]
                                                [/version]                            []                 [get]
                                                [/version]                            []                 [get]
Loom answered 2/12, 2021 at 15:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.