0 0 Share PDF

How to impersonate a Kubernetes ServiceAccount with kubectl

Article ID: KB000999

Issue

When troubleshooting ServiceAccount permissions, it may be helpful to impersonate a given ServiceAccount with kubectl. We can use a Service Account Token with kubectl --token to authenticate as a given ServiceAccount.

Prerequisites

  • You are operating a Docker Enterprise Edition cluster >= Docker EE 2.1
  • Note that there is no support for native Kubernetes RBAC in Docker EE 2.0, RBAC is provided by an Authorization Plugin that uses UCP Collections & Grants instead.
  • You have deployed at least 1 ServiceAccount with associated ClusterRoleBinding or RoleBinding

Resolution

  1. Load a UCP Client bundle

    $ unzip ucp-admin-bundle.zip
    $ source env.sh
    
  2. First, look up the ServiceAccount's secret token; in our example, we know that traefik-ingress-controller is already deployed in the kube-system namespace:

    $ kubectl get serviceaccounts -n kube-system traefik-ingress-controller -o yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"traefik-ingress-controller","namespace":"kube-system"}}
      creationTimestamp: "2019-06-28T16:06:40Z"
      name: traefik-ingress-controller
      namespace: kube-system
      resourceVersion: "7805461"
      selfLink: /api/v1/namespaces/kube-system/serviceaccounts/traefik-ingress-controller
      uid: b7138590-99be-11e9-956e-0242ac110007
    secrets:
    - name: traefik-ingress-controller-token-c49zc
    

    In this case, traefik-ingress-controller-token-c49zc.

  3. Next, determine the value of the secret token:

    $ kubectl get secret -n kube-system traefik-ingress-controller-token-c49zc -o yaml
    apiVersion: v1
    data:
      ca.crt: [redacted]
      namespace: a3ViZS1zeXN0ZW0=
      token: ZXlKaGJ...[redacted]
    kind: Secret
    metadata:
      annotations:
        kubernetes.io/service-account.name: traefik-ingress-controller
        kubernetes.io/service-account.uid: b7138590-99be-11e9-956e-0242ac110007
      creationTimestamp: "2019-06-28T16:06:40Z"
      name: traefik-ingress-controller-token-c49zc
      namespace: kube-system
      resourceVersion: "7805460"
      selfLink: /api/v1/namespaces/kube-system/secrets/traefik-ingress-controller-token-c49zc
      uid: b71ebe41-99be-11e9-956e-0242ac110007
    type: kubernetes.io/service-account-token
    
  4. Decode the base64-encoded token string:

    $ TOKEN=$(echo ZXlKaGJ...[redacted] | base64 --decode)
    $ echo ${TOKEN}
    eyJhb...[redacted]
    
  5. Finally, use the plaintext token to authenticate as that ServiceAccount with kubectl: kubectl --token ${TOKEN} get svc --all-namespaces kubectl --token ${TOKEN} get pods --all-namespaces kubectl --token ${TOKEN} describe svc -n kube-system traefik-ingress-service