Kubernetes authentication: Access control stages, service accounts and how to authenticate

Understand how Kubernetes authentication works. Covers the three access control stages, service accounts vs users, authentication plugins, and a hands-on API authentication example.

4 lessons · 10 min · Advanced

4 minutes reading time

Written by

Civo Team
Civo Team

Marketing Team at Civo

Every request to the Kubernetes API, whether from kubectl, an application running in a pod, or an external tool, goes through a three-stage access control pipeline before it is allowed to proceed. Understanding how this pipeline works is the foundation for understanding both authentication and RBAC in Kubernetes.

api-access-control-stages

The three access control stages

Stage 1: Authentication

Authentication answers the question: who are you? When a request arrives at the API server, Kubernetes checks the credentials embedded in the request against one of its configured authentication plugins. If the credentials are missing or invalid, the request is rejected immediately with a 401 Unauthorized response.

Stage 2: Authorization

Authorization answers the question: are you allowed to do this? Once the identity is confirmed, Kubernetes checks whether that identity has permission to perform the requested action on the requested resource. If the identity lacks the required permissions, the request is rejected with a 403 Forbidden response. RBAC is the most common authorization mode in use today.

Stage 3: Admission control

Admission control is the final stage. Admission controllers are a set of rules and policies applied cluster-wide. They can validate requests (rejecting anything that violates policy) or mutate them (modifying the request before it is stored). Examples include enforcing resource limits, injecting sidecar containers, and validating image sources. A request that passes authentication and authorization can still be rejected at the admission stage.

Who authenticates: users and service accounts

Kubernetes recognises two categories of identity.

Regular users are human users managed externally. Kubernetes does not have a user object or a user management system. Instead it delegates to external systems: X.509 client certificates issued by the cluster's certificate authority, OIDC tokens from an identity provider like Google or Okta, or bearer tokens from a webhook authenticator. The most common approach in managed clusters like Civo is a kubeconfig file containing a certificate or token.

Service accounts are Kubernetes objects that provide an identity for processes running inside pods. Unlike regular users, service accounts are managed natively by Kubernetes. Every pod runs with a service account. If you do not specify one, the pod uses the default service account in its namespace. Service accounts are the right choice when an application running inside the cluster needs to interact with the Kubernetes API.

After authentication succeeds, Kubernetes appends user information to the request: username, UID, groups, and extra fields. This information is passed to the authorisation stage.

Authentication plugins

Kubernetes supports several authentication mechanisms:

  • X.509 client certificates — the cluster CA signs a certificate containing the username and group. Used in most kubeconfig files.
  • Service account tokens — JWT tokens associated with a service account. From Kubernetes 1.24 onwards, bound service account tokens are used by default. These are short-lived and tied to a specific pod, rather than long-lived tokens stored in a Secret.
  • OIDC tokens — tokens from an external OpenID Connect provider. The most common approach for human user authentication in production clusters.
  • Webhook token authentication — delegates token validation to an external service.
  • Bootstrap tokens — short-lived tokens used during cluster setup (for example during kubeadm node joining). Not used for regular authentication.

Hands-on: authenticating against the Kubernetes API

This example shows how to authenticate directly against the Kubernetes API using a service account token and curl. This is useful for understanding how applications inside the cluster communicate with the API.

View your cluster configuration:

kubectl config view

Set the cluster name and fetch the API server endpoint:

export CLUSTER_NAME="kubernetes"
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")
echo $APISERVER

Expected output:

https://your-cluster-api-endpoint:6443

Fetch and decode the service account token.

Note: the command below uses the legacy approach of reading a token from a Secret. In Kubernetes 1.24 and later, tokens are no longer automatically stored in Secrets by default. For clusters running 1.24 or later, use kubectl create token <service-account-name> to generate a bound token instead.

TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}" | base64 -d)

What this command does: kubectl get secrets fetches all secrets, -o jsonpath filters to find the secret annotated with the default service account name, .data.token extracts the base64-encoded token value, and base64 -d decodes it.

Make an authenticated request to the API server:

curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

Expected output:

{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "your-cluster-api-endpoint:6443"
}
]
}

A successful response confirms that the token was accepted and the request was authenticated. The --insecure flag skips certificate verification for the purposes of this demo. In production, pass the cluster CA certificate instead.

Civo Team
Civo Team

Marketing Team at Civo

Civo is the Sovereign Cloud and AI platform designed to help developers and enterprises build without limits. We bridge the gap between the openness of the public cloud and the rigorous security of private environments, delivering full cloud parity across every deployment. As a team, we are dedicated to providing scalable compute, lightning-fast Kubernetes, and managed services that are ready in minutes. Through CivoStack Enterprise and our FlexCore appliance, we empower organizations to maintain total data sovereignty on their own hardware.

Our mission is to make the cloud faster, simpler, and fairer. By providing enterprise-grade NVIDIA GPUs and streamlined model management, we ensure that high-performance AI and machine learning are accessible to everyone. Built for transparency and performance, the Civo Team is here to give you total control over your infrastructure, your data, and your spend.

View author profile