Busque em todas as páginas da documentação
Create a dedicated ServiceAccount per workload, bind the minimum Role, and reference it from the pod spec.
kubectl create serviceaccount checkout --namespace paymentsapiVersion: v1
kind: Pod
metadata:
name: checkout
namespace: payments
spec:
serviceAccountName: checkout
automountServiceAccountToken: true
containers:
- name: app
image: registry.example.com/checkout@sha256:abc123Bind a narrow Role so the account can read only what it needs.
Here is a complete, minimal setup: a ServiceAccount, a Role, a RoleBinding, and a Deployment that uses it.
apiVersion: v1
kind: ServiceAccount
metadata:
name: checkout
namespace: payments
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: payments
name: config-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: payments
name: checkout-config
subjects:
- kind: ServiceAccount
name: checkout
namespace: payments
roleRef:
kind: Role
name: config-reader
apiGroup: rbac.authorization.k8s.ioSet automountServiceAccountToken back on only for the pod that needs it.
apiVersion: apps/v1
kind: Deployment
metadata:
name: checkout
namespace: payments
spec:
replicas: 2
selector:
matchLabels: { app: checkout }
template:
metadata:
labels: { app: checkout }
spec:
serviceAccountName: checkout
automountServiceAccountToken: true
containers:
- name: app
image: registry.example.com/checkout@sha256:abc123The pod now authenticates to the API server as system:serviceaccount:payments:checkout and can read configmaps in payments, nothing more.
Every namespace ships with a default ServiceAccount, and pods that name none inherit it.
The API server projects a signed JWT into the pod, and the kubelet keeps it fresh.
The token's sub claim resolves to system:serviceaccount:<namespace>:<name>, which is the subject RBAC evaluates.
Since the BoundServiceAccountTokenVolume feature graduated, tokens are delivered through a projected volume, not a persistent Secret.
volumes:
- name: api-token
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 3600
audience: apiexpirationSeconds bounds the token lifetime, and the kubelet rotates it before expiry.audience scopes the token to a specific recipient, so a token meant for one service is rejected by another.Most workloads never call the API server, so they should not carry a token.
Set automountServiceAccountToken: false on the ServiceAccount or pod to drop the mount.
This shrinks the blast radius if a container is compromised.
The TokenRequest API issues audience-scoped tokens that external systems can verify against the cluster's OIDC discovery document.
Cloud providers use this for workload identity federation, letting a pod assume a cloud role without any static cloud key.
A pod requests such a token by declaring the target audience on a projected volume, and the receiving service validates the signature and audience before trusting it.
Because these tokens are short-lived and audience-bound, a token minted for one downstream cannot be replayed against another.
You can confirm what a pod actually receives without leaving the cluster.
kubectl exec -n payments deploy/checkout -- \
cat /var/run/secrets/kubernetes.io/serviceaccount/tokensub, aud, and exp claims.sub claim is the exact RBAC subject the API server evaluates.Do not bind Roles to the default ServiceAccount, since every pod without an explicit account inherits that access.
Legacy long-lived Secret tokens still exist if you manually create a kubernetes.io/service-account-token Secret, but avoid them - they do not expire and are a standing credential.
A ServiceAccount with no binding is not an error, it simply has zero API permissions, which is the correct default.
Cross-namespace binding requires the namespace field on the subject, and omitting it silently targets the binding's own namespace.
Granting create on serviceaccounts/token lets a subject mint tokens for other accounts, which is an escalation path worth auditing.
Use a per-workload ServiceAccount when a pod must call the API server or a token-trusting service - this is the default recommendation.
Use cloud workload identity federation, layered on projected tokens, when a pod needs cloud APIs without static keys.
Use automountServiceAccountToken: false with no bindings when a workload never talks to the API, which is the majority of application pods.
Use a human OIDC identity, not a ServiceAccount, for interactive kubectl access - ServiceAccounts are for workloads.
What identity does a pod use if I set nothing?
The default ServiceAccount of its namespace, which should carry no meaningful permissions.
Are ServiceAccount tokens still stored as Secrets? No, by default they are projected, short-lived tokens. Long-lived Secret tokens exist only if you create them explicitly.
How do I give a ServiceAccount permissions? Bind a Role or ClusterRole to it with a RoleBinding or ClusterRoleBinding, exactly as you would for a user.
Can one ServiceAccount be used across namespaces? No, a ServiceAccount is namespaced. A binding in another namespace can reference it, but the account object lives in one namespace.
How do I stop a container from receiving a token?
Set automountServiceAccountToken: false on the pod or the ServiceAccount.
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026