Authentication and Authorization
Video: Day 22/40 — Kubernetes Authentication and Authorization Simply Explained • https://www.youtube.com/watch?v=P0bogYEyfeI • Duration: ~18 min
Key terms
| Term | Meaning |
|---|---|
| Authentication (AuthN) | Proving who you are |
| Authorization (AuthZ) | Deciding what you may do |
| RBAC | Role-based access control authorizer |
| ServiceAccount | Identity for in-cluster workloads |
| Bearer token | Credential that proves an identity |
kubectl auth can-i | Checks whether an action is allowed |
| Admission | Post-authz request validation/mutation |
Problem & solution
An API that anyone could call and do anything on would be catastrophic. Every request must prove who it is (authentication) and be checked for what it's allowed to do (authorization) before it takes effect.
Solution: Make every request pass authentication (certs/tokens), then authorization (RBAC), then admission control before it is stored.
The analogy
At the port gate a guard does two separate jobs in order. First they check your ID to confirm you really are who you claim to be, that step is authentication. Then they check which doors your badge is allowed to open, that step is authorization, and you can clear the first check yet still be turned back at a locked door. Kubernetes runs the same two gates on every request: AuthN establishes your identity from a cert or token, then AuthZ asks RBAC which actions that identity may actually perform.
Where this fits in the cluster
The same cluster entities appear in every day's notes; the diagram below shows where this day's topic fits.
Two gates every request passes
Every API call runs a fixed gauntlet: it is first authenticated, then authorized, then checked by admission control before being stored.
Graph legend — each node maps to a concrete api-server stage:
| Graph node | Maps to | What it does |
|---|---|---|
| request | a kubectl/client call over TLS | Carries a client cert or bearer token (e.g. OIDC from Dex) |
| Authentication | authn plugins (x509, OIDC, SA token) | Resolves the caller to a username + groups, or rejects (401) |
| Authorization | the RBAC authorizer | Checks the identity against Role/ClusterRole bindings (allow/deny) |
| Admission | mutating + validating admission webhooks | Defaults, validates, or rejects the object (quotas, policies) |
| Persisted in etcd | the storage layer | Writes the accepted object to etcd |
AuthN = identity. AuthZ = permission. You can be authenticated and still get a
Forbiddenbecause you are not authorized.
Authentication: proving WHO you are
The API server has no user database. Identity comes from:
- client CERTIFICATES (CN = user, O = group) <- common
- bearer TOKENS (service accounts, or OIDC via Dex / Keycloak / Okta)
- static token / basic auth files (rarely, legacy)
Your kubeconfig is basically your keycard: it holds the server address,
the CA to trust, and your client cert/key (or token).
kubectl get pods --kubeconfig config # use a specific kubeconfig
kubectl get pods # defaults to ~/.kube/config
Raw API call with explicit creds (what kubeconfig does under the hood):
kubectl get --raw /api/v1/namespaces/default/pods \
--server https://localhost:64418 \
--client-key adam.key \
--client-certificate adam.crt \
--certificate-authority ca.crt
Check your own access
These commands let you ask the API server who you are and whether a given action is permitted, optionally impersonating another user.
kubectl auth whoami # who the API server thinks you are
kubectl auth can-i create pods # for yourself
kubectl auth can-i delete nodes --as adam # impersonate to test
kubectl auth can-i '*' '*' # am I admin?
The mental model
Putting it together, a request flows from your kubeconfig credentials through authentication, authorization, and admission before the action runs.
End-to-end example: a kubectl request from laptop to etcd
Follow one kubectl apply through every gate the API server runs.
Graph legend — each step maps to a concrete api-server action:
| Graph step | Maps to | What it does |
|---|---|---|
| kubectl apply -f pod.yaml | kubectl POST with kubeconfig creds | Sends the Pod object plus the client cert (or OIDC token) |
| AuthN cert CN adam O devs | the x509 authn plugin | Resolves identity to user adam, group devs |
| AuthZ RBAC may adam create pods | the RBAC authorizer | Looks for a binding granting create pods in default |
| Admission quotas policies defaulting | admission webhooks | Applies ResourceQuota, LimitRange, and defaulting |
| persist the Pod object | etcd write | Stores the accepted object and returns a resourceVersion |
| 201 Created | api-server response | Confirms the object was created (or 403 if AuthZ denied) |
End-to-end flow
Every API request runs the same gauntlet of gates before anything is stored.
Graph legend — each node maps to a concrete request stage:
| Graph node | Maps to | What it does |
|---|---|---|
| kubectl apply with client cert or token | the client call | Presents a kubeconfig credential (x509 or OIDC bearer token) |
| AuthN: identify user and groups | authn plugins | Returns username + groups, or 401 if unauthenticated |
| AuthZ: RBAC allow or deny | the RBAC authorizer | Matches the identity against Role/ClusterRole bindings |
| 403 Forbidden, nothing written | the deny path | Authenticated but not permitted; object is never stored |
| Admission: validate and mutate | admission webhooks | Enforces quotas/policies and applies defaults |
| Persist object in etcd | the storage layer | Writes the accepted object and returns 201 Created |
Key takeaways
- Every request is authenticated then authorized (then admission).
- API server has no user store — identity comes from certs or tokens.
kubeconfigcarries server + CA + your credentials.- Authorization order: Node -> RBAC -> Webhook; RBAC is what you'll use.
- Use
kubectl auth can-i ... --as <user>to test permissions.
Checklist
- [ ] Can explain AuthN vs AuthZ in one sentence each
- [ ] Inspected
~/.kube/configand identified server/CA/credentials - [ ] Made a
--rawAPI call with explicit cert flags - [ ] Used
kubectl auth can-iwith--asto test access