> ## Content Index
> Fetch the complete content index at: https://devopscube.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to Create Kubernetes Service Account and Long Lived Token
- URL: https://devopscube.com/kubernetes-api-access-service-account/
- Published: 2025-01-09T04:59:08.000Z
- Updated: 2025-03-15T06:46:21.000Z
- Author: Bibin Wilson
- Tags: Kubernetes, #Migrated-1741795015845, #wp, #wp-post, #Import 2025-03-12 15:57, #blog

This tutorial will guide you through the process of creating the service account, role, role binding and secret to have API access to the Kubernetes cluster using long lived token.

The best and recommended way to allow API access to the [Kubernetes cluster](https://devopscube.com/setup-kubernetes-cluster-kubeadm/) is through service accounts with long lived tokens following the **principle of least privilege** (PoLP).

## Use Cases

Following are the example use cases of Kubernetes service account for external API access.

1. Allowing third-party [monitoring tools](https://devopscube.com/best-opensource-monitoring-tools/) to access Kubernetes data
2. External applications to access kubernetes resources.

Now, why would you need this access?

Lets take an example of [Prometheus monitoring](https://devopscube.com/setup-prometheus-monitoring-on-kubernetes/) stack.

Prometheus **needs read access to cluster API** to get information from metrics server, read pods, etc.

When you deploy Prometheus, you add cluster read permissions to the default service account where the Prometheus pods are deployed. This way, Prometheus pods get read access to cluster resources.

## Setup Kubernetes API Access Using Service Account Token

Follow the steps given below to create a [service account](https://devopscube.com/create-kubernetes-role/) token for API access.

### Step 1: Create service account in a namespace

We will create a service account in a custom namespace rather than the default namespace for demonstration purposes.

Create a `devops-tools` namespace.

```
kubectl create namespace devops-tools
```

Create a service account named "`api-service-account`" in `devops-tools` namespace

kubectl create serviceaccount api-service-account -n devops-tools

or use the following manifest.

```
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: api-service-account
  namespace: devops-tools
EOF
```

### Step 2: Create a Cluster Role

Assuming that the service account needs access to the entire cluster resources, we will create a cluster role with a list of allowed access.

Create a clusterRole named `api-cluster-role` with the following manifest file.

```
cat <<EOF | kubectl apply -f -
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: api-cluster-role
  namespace: devops-tools
rules:
  - apiGroups:
        - ""
        - apps
        - autoscaling
        - batch
        - extensions
        - policy
        - rbac.authorization.k8s.io
    resources:
      - pods
      - componentstatuses
      - configmaps
      - daemonsets
      - deployments
      - events
      - endpoints
      - horizontalpodautoscalers
      - ingress
      - jobs
      - limitranges
      - namespaces
      - nodes
      - pods
      - persistentvolumes
      - persistentvolumeclaims
      - resourcequotas
      - replicasets
      - replicationcontrollers
      - serviceaccounts
      - services
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
EOF
```

The above YAML declaration has a `ClusterRole` with full access to all cluster resources and a role binding to "`api-service-account`".

It is not recommended to create a service account with all cluster component access without any requirement.

To get the list of available API resources execute the following command.

```
kubectl api-resources
```

### Step 3: Create a CluserRole Binding

Now that we have the ClusterRole and service account, it needs to be mapped together.

Bind the `cluster-api-role` to `api-service-account` using a `RoleBinding`

```
cat <<EOF | kubectl apply -f -
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: api-cluster-role-binding
subjects:
- namespace: devops-tools 
  kind: ServiceAccount
  name: api-service-account 
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: api-cluster-role 
EOF
```

### Step 4: Validate Service Account Access Using kubectl

To validate the clusterrole binding, we can use `can-i` commands to validate the API access assuming a service account in a specific namespace.

For example, the following command checks if the `api-service-account` in the `devops-tools` namespace can list the pods.

```
kubectl auth can-i get pods --as=system:serviceaccount:devops-tools:api-service-account
```

Here is another example, to check if the service account has permissions to delete deployments.

```
kubectl auth can-i delete deployments --as=system:serviceaccount:devops-tools:api-service-account
```

### Step 5: Associate a Secret With Service Account

To use a service account with an HTTP call, you need to have the **long lived token** associated with the service account. A **long-lived token** in Kubernetes is an authentication token that does not expire quickly, allowing continuous access to the Kubernetes API for an extended period.

For that, you **need to create a secret** for the service account.

Create a file named `sa-token.yaml`, and copy the following content.

```
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: api-service-account-token
  namespace: devops-tools
  annotations:
    kubernetes.io/service-account.name: api-service-account
```

Then, create the secret by running the following command.

```
kubectl apply -f sa-token.yaml
```

Once the secret is created, use the following command to get the base64 decoded token. It will be used as a bearer token in the API call.

```
kubectl get secret api-service-account-token -o=jsonpath='{.data.token}' -n devops-tools | base64 --decode
```

Get the cluster endpoint to validate the API access. The following command will display the cluster endpoint (IP, DNS).

```
kubectl get endpoints | grep kubernetes
```

### Step 6: Validate Service Account Access Using API call

Now that you have the cluster endpoint and the service account token, you can test the API connectivity using the CURL or the Postman app.

For example, list all the namespaces in the cluster using curl. Use the token after `Authorization: Bearer` section.

```
curl -k  https://35.226.193.217/api/v1/namespaces -H "Authorization: Bearer eyJhbGcisdfsdfsdfiJ9.eyJpc3MiOisdfsdfVhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3sdf3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImFwaS1zZXJ2aWNlsdfglkjoer876Y3BmNWYiLsdfsdfRlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmFwaS1zZXJ2aWNlLWFjY291bnQifQ.u5jgk2px_lEs3f5e5lh_UfS40fndtDKMTY5UvsdfrtsuhtgjrUj-ezrRXeLS8SLOae4DuOGGGbInSg_gIo6oO7bLHhCixWOBJNOA5gzrLVioof_kHDR8gH5crrsWoR-GSSsdfgsdfg6fA_LDOqdxzqMC0WlXt6tgHfrwIHerPPvkI6NWLyCqX9tn_akpcihd-bL6GwOKlph17l_ND710FnTkE7kBfdXtQWWxaPPe06UEmoKK9t-0gsOCBxJxViwhHkvwqetr987q9enkadfgd_2cY_CA"
```

You can also try that same API call in Postman.

![Testing Kubernetes Service account token for Cluster API access.](https://storage.ghost.io/c/5f/2f/5f2f4d20-2abf-4534-8d40-7aa233aedd43/content/images/2025/03/image-150.png)

The `ClusterRole` we created can be attached to pods/deployments as well.

You can also use the token to login to the Kubernetes dashboard.

## Conclusion

When using Kubernetes service account for API access from third party applications, ensure you add only required roles to the service account.

Also, never attach a clusterRole to a default service account because the pods get the default service account by default. Meaning all the pods in the namespace have access to the clusterRole.

Also, use a secret management tool like [Hashicorp vault](https://devopscube.com/setup-hashicorp-vault-beginners-guide/) to store, retrieve, and share secret tokens.