Search code examples
kuberneteskubernetes-podkubernetes-secretsk3skubernetes-security

How can I remove dependency of secrets from application pod in K3s cluster


I am having a k3s cluster with my application pods running. In all the pods when I login ( with kubectl exec <pod_name> -n <ns> -it /bin/bash command ) there is kubernetes.io directory which contain secret token that anyone can get if they do cat token :

root@Ubuntu-VM: kubectl exec app-test-pod -n app-system -it /bin/bash
root@app-test-pod:/var/run/secrets/kubernetes.io/serviceaccount# ls -lhrt
total 0
lrwxrwxrwx 1 root root 12 Oct 11 12:07 token -> ..data/token
lrwxrwxrwx 1 root root 16 Oct 11 12:07 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 13 Oct 11 12:07 ca.crt -> ..data/ca.crt

This seems a security threat (or vulnerability). Can someone let me know if there is a way to remove this dependency from pod so that I can restrict users (even root users also) to access this secret if they login to pod ? Also If this is possible then how will pods do communicate with the API Server ?


Solution

  • To clarify a couple of things:

    This seems a security threat (or vulnerability).

    It actually isn't a vulnerability unless you configured it to be one. The ServiceAccount you are talking about is the deafult one which exists in every namespace. By default that ServiceAccount does not have any permissions that make it unsafe. If you want to you can add certain rights to the default ServiceAccount using RBAC. For example you can configure it to be able to list all Pods in the same namespace but unless you do that, the ServiceAccount is not considered a vulnerability at all and will not be able to retrieve any useful information. This applies to all ServiceAccounts, not only the default one.

    Can someone let me know if there is a way to remove this dependency from pod so that I can restrict users (even root users also) to access this secret if they login to pod ?

    Yes it is possible, actually there are two options:

    Firstly there is a field called automountServiceAccountToken for the spec section in Pods which you can set to false if you do not want the default ServiceAccount to be mounted at all.

    Here is an example:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    spec:
      automountServiceAccountToken: false
      [...]
    

    Other than that you can create/edit a ServiceAccount and assign it the automountServiceAccountToken: false field:

    apiVersion: v1
    kind: ServiceAccount
    automountServiceAccountToken: false
    metadata:
      namespace: default
    [...]
    

    Also If this is possible then how will pods do communicate with the API Server ?

    Pods actually do not need to communicate with the API server at all. Even when using features like a livenessProbe it is not necessary for Pods to communicate with the API server at all. As a matter of fact most Pods never communicate with the API server. The only reason a Pod would need to communicate with the API server is if it is planning on directly interacting with the cluster. Usually this is never required unless you want to write a custom operator or something similar. You will still be able to use all the functionality a Pod has to offer you even if you do not mount the ServiceAccount because all those features are based around a Kubernetes communicating with your Pod not the other way around (a livenessProbe for example is being evaluated by kubelet, there is no need at all for the Pod to communicate with the API).