Kubernetes Authentication - There Are No Users
Kubernetes Authentication
There Is No User Object
Here is the thing nobody tells you first, and it is the thing that
makes everything else make sense: Kubernetes has no user object. You
cannot kubectl create user. There is no table of accounts, no
password store, nothing inside the cluster that represents a human.
The API server does not manage identities. It verifies a credential
that came from outside, reads a username off it, and hands that name
to the authorization layer. Authentication in Kubernetes is entirely
"prove who you are with something external," never "look me up in the
cluster."
Once that clicks, the rest is simple.
Two Kinds of Identity
Kubernetes splits identity in two, and the split matters.
Normal users are humans. They are the ones with no object in the
cluster. A human is whoever an external system says they are: a
client certificate signed by the cluster CA, or a token from an
identity provider. The cluster trusts the issuer and takes the name
on faith.
Service accounts are for workloads, and these do exist as objects in
the cluster. A pod runs as a service account, gets a token mounted in,
and uses it to talk to the API. This is the identity your code carries.
It is a real thing you can create, list, and delete, unlike a human
user.
The rule of thumb: humans authenticate from outside, workloads
authenticate from inside with a service account.
How a Human Actually Authenticates
Two mechanisms cover almost everything.
Client certificates. The cluster CA signs a certificate, the username
is the certificate's subject, and the group is a field in it. Simple,
built in, and awkward in one specific way: a certificate cannot be
revoked without rotating the CA. That makes raw client certs fine for
break-glass admin access and a bad fit for a team that changes.
OIDC. The cluster trusts an external identity provider, your Google
Workspace, your Entra, your Keycloak, and the user logs in there and
presents the resulting token. This is how real teams do it, because
offboarding happens in one place, the identity provider, instead of
across the cluster. Disable the account upstream and their cluster
access ends with it.
The pattern is the same one worth reaching for everywhere: do not
store the identity in the thing being protected. Let a system built
for identity own it, and have the cluster trust that system.
Authentication Is Not Authorization
The step people collapse: proving who you are and being allowed to do
anything are two separate stages, and Kubernetes keeps them strictly
apart.
Authentication answers "who is this." It produces a username and some
groups, and then it is done. It grants nothing. A perfectly valid,
correctly authenticated identity can be allowed to do exactly nothing.
Authorization, which is RBAC, answers "is this name allowed to do this
action." It runs after authentication, against the name authentication
produced, and it is where every actual permission lives.
This is why a working credential can still get "forbidden" on every
command. Authentication succeeded, authorization said no. The two
being separate is a feature: the cluster can be certain who you are
and still, correctly, let you do nothing.
The Point
Kubernetes never stores your identity. It verifies a credential from
outside and reads a name off it, and that name is all it carries into
the permission check. Humans come from certificates or an identity
provider, workloads come from service accounts, and being
authenticated is not the same as being allowed.
Store human identity in a real identity provider and let the cluster
trust it. Use service accounts for workloads and nothing else. And
remember the name on the credential grants nothing on its own, which
is exactly how it should be.