{
	"id": "c45ebbad-f2ad-4aea-bf84-5f10a4d9a6da",
	"created_at": "2026-04-06T00:20:21.087089Z",
	"updated_at": "2026-04-10T13:12:50.323838Z",
	"deleted_at": null,
	"sha1_hash": "05a8242583dd1279b5316b7837d7db9106ad868a",
	"title": "Configure Service Accounts for Pods",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 137084,
	"plain_text": "Configure Service Accounts for Pods\r\nArchived: 2026-04-05 22:25:33 UTC\r\nKubernetes offers two distinct ways for clients that run within your cluster, or that otherwise have a relationship to\r\nyour cluster's control plane to authenticate to the API server.\r\nA service account provides an identity for processes that run in a Pod, and maps to a ServiceAccount object.\r\nWhen you authenticate to the API server, you identify yourself as a particular user. Kubernetes recognises the\r\nconcept of a user, however, Kubernetes itself does not have a User API.\r\nThis task guide is about ServiceAccounts, which do exist in the Kubernetes API. The guide shows you some ways\r\nto configure ServiceAccounts for Pods.\r\nBefore you begin\r\nYou need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate\r\nwith your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as\r\ncontrol plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one\r\nof these Kubernetes playgrounds:\r\niximiuz Labs\r\nKillercoda\r\nKodeKloud\r\nUse the default service account to access the API server\r\nWhen Pods contact the API server, Pods authenticate as a particular ServiceAccount (for example, default ).\r\nThere is always at least one ServiceAccount in each namespace.\r\nEvery Kubernetes namespace contains at least one ServiceAccount: the default ServiceAccount for that\r\nnamespace, named default . If you do not specify a ServiceAccount when you create a Pod, Kubernetes\r\nautomatically assigns the ServiceAccount named default in that namespace.\r\nYou can fetch the details for a Pod you have created. For example:\r\nkubectl get pods/\u003cpodname\u003e -o yaml\r\nIn the output, you see a field spec.serviceAccountName . Kubernetes automatically sets that value if you don't\r\nspecify it when you create a Pod.\r\nAn application running inside a Pod can access the Kubernetes API using automatically mounted service account\r\ncredentials. See accessing the Cluster to learn more.\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 1 of 11\n\nWhen a Pod authenticates as a ServiceAccount, its level of access depends on the authorization plugin and policy\r\nin use.\r\nThe API credentials are automatically revoked when the Pod is deleted, even if finalizers are in place. In\r\nparticular, the API credentials are revoked 60 seconds beyond the .metadata.deletionTimestamp set on the Pod\r\n(the deletion timestamp is typically the time that the delete request was accepted plus the Pod's termination grace\r\nperiod).\r\nOpt out of API credential automounting\r\nIf you don't want the kubelet to automatically mount a ServiceAccount's API credentials, you can opt out of the\r\ndefault behavior. You can opt out of automounting API credentials on\r\n/var/run/secrets/kubernetes.io/serviceaccount/token for a service account by setting\r\nautomountServiceAccountToken: false on the ServiceAccount:\r\nFor example:\r\napiVersion: v1\r\nkind: ServiceAccount\r\nmetadata:\r\n name: build-robot\r\nautomountServiceAccountToken: false\r\n...\r\nYou can also opt out of automounting API credentials for a particular Pod:\r\napiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n name: my-pod\r\nspec:\r\n serviceAccountName: build-robot\r\n automountServiceAccountToken: false\r\n ...\r\nIf both the ServiceAccount and the Pod's .spec specify a value for automountServiceAccountToken , the Pod\r\nspec takes precedence.\r\nUse more than one ServiceAccount\r\nEvery namespace has at least one ServiceAccount: the default ServiceAccount resource, called default . You can\r\nlist all ServiceAccount resources in your current namespace with:\r\nkubectl get serviceaccounts\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 2 of 11\n\nThe output is similar to this:\r\nNAME SECRETS AGE\r\ndefault 1 1d\r\nYou can create additional ServiceAccount objects like this:\r\nkubectl apply -f - \u003c\u003cEOF\r\napiVersion: v1\r\nkind: ServiceAccount\r\nmetadata:\r\n name: build-robot\r\nEOF\r\nThe name of a ServiceAccount object must be a valid DNS subdomain name.\r\nIf you get a complete dump of the service account object, like this:\r\nkubectl get serviceaccounts/build-robot -o yaml\r\nThe output is similar to this:\r\napiVersion: v1\r\nkind: ServiceAccount\r\nmetadata:\r\n creationTimestamp: 2019-06-16T00:12:34Z\r\n name: build-robot\r\n namespace: default\r\n resourceVersion: \"272500\"\r\n uid: 721ab723-13bc-11e5-aec2-42010af0021e\r\nYou can use authorization plugins to set permissions on service accounts.\r\nTo use a non-default service account, set the spec.serviceAccountName field of a Pod to the name of the\r\nServiceAccount you wish to use.\r\nYou can only set the serviceAccountName field when creating a Pod, or in a template for a new Pod. You cannot\r\nupdate the .spec.serviceAccountName field of a Pod that already exists.\r\nNote:\r\nThe .spec.serviceAccount field is a deprecated alias for .spec.serviceAccountName . If you want to remove\r\nthe fields from a workload resource, set both fields to empty explicitly on the pod template.\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 3 of 11\n\nCleanup\r\nIf you tried creating build-robot ServiceAccount from the example above, you can clean it up by running:\r\nkubectl delete serviceaccount/build-robot\r\nManually create an API token for a ServiceAccount\r\nSuppose you have an existing service account named \"build-robot\" as mentioned earlier.\r\nYou can get a time-limited API token for that ServiceAccount using kubectl :\r\nkubectl create token build-robot\r\nThe output from that command is a token that you can use to authenticate as that ServiceAccount. You can request\r\na specific token duration using the --duration command line argument to kubectl create token (the actual\r\nduration of the issued token might be shorter, or could even be longer).\r\nFEATURE STATE: Kubernetes v1.33 [stable] (enabled by default)\r\nUsing kubectl v1.31 or later, it is possible to create a service account token that is directly bound to a Node:\r\nkubectl create token build-robot --bound-object-kind Node --bound-object-name node-001 --bound-object-uid 123.\r\nThe token will be valid until it expires or either the associated Node or service account are deleted.\r\nNote:\r\nVersions of Kubernetes before v1.22 automatically created long term credentials for accessing the Kubernetes\r\nAPI. This older mechanism was based on creating token Secrets that could then be mounted into running Pods. In\r\nmore recent versions, including Kubernetes v1.35, API credentials are obtained directly by using the\r\nTokenRequest API, and are mounted into Pods using a projected volume. The tokens obtained using this method\r\nhave bounded lifetimes, and are automatically invalidated when the Pod they are mounted into is deleted.\r\nYou can still manually create a service account token Secret; for example, if you need a token that never expires.\r\nHowever, using the TokenRequest subresource to obtain a token to access the API is recommended instead.\r\nManually create a long-lived API token for a ServiceAccount\r\nIf you want to obtain an API token for a ServiceAccount, you create a new Secret with a special annotation,\r\nkubernetes.io/service-account.name .\r\nkubectl apply -f - \u003c\u003cEOF\r\napiVersion: v1\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 4 of 11\n\nkind: Secret\r\nmetadata:\r\n name: build-robot-secret\r\n annotations:\r\n kubernetes.io/service-account.name: build-robot\r\ntype: kubernetes.io/service-account-token\r\nEOF\r\nIf you view the Secret using:\r\nkubectl get secret/build-robot-secret -o yaml\r\nyou can see that the Secret now contains an API token for the \"build-robot\" ServiceAccount.\r\nBecause of the annotation you set, the control plane automatically generates a token for that ServiceAccounts, and\r\nstores them into the associated Secret. The control plane also cleans up tokens for deleted ServiceAccounts.\r\nkubectl describe secrets/build-robot-secret\r\nThe output is similar to this:\r\nName: build-robot-secret\r\nNamespace: default\r\nLabels: \u003cnone\u003e\r\nAnnotations: kubernetes.io/service-account.name: build-robot\r\n kubernetes.io/service-account.uid: da68f9c6-9d26-11e7-b84e-002dc52800da\r\nType: kubernetes.io/service-account-token\r\nData\r\n====\r\nca.crt: 1338 bytes\r\nnamespace: 7 bytes\r\ntoken: ...\r\nNote:\r\nThe content of token is omitted here.\r\nTake care not to display the contents of a kubernetes.io/service-account-token Secret somewhere that your\r\nterminal / computer screen could be seen by an onlooker.\r\nWhen you delete a ServiceAccount that has an associated Secret, the Kubernetes control plane automatically\r\ncleans up the long-lived token from that Secret.\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 5 of 11\n\nNote:\r\nIf you view the ServiceAccount using:\r\nkubectl get serviceaccount build-robot -o yaml\r\nYou can't see the build-robot-secret Secret in the ServiceAccount API objects .secrets field because that\r\nfield is only populated with auto-generated Secrets.\r\nAdd ImagePullSecrets to a service account\r\nFirst, create an imagePullSecret. Next, verify it has been created. For example:\r\nCreate an imagePullSecret, as described in Specifying ImagePullSecrets on a Pod.\r\nkubectl create secret docker-registry myregistrykey --docker-server=\u003cregistry name\u003e \\\r\n --docker-username=DUMMY_USERNAME --docker-password=DUMMY_DOCKER_PASSWORD \\\r\n --docker-email=DUMMY_DOCKER_EMAIL\r\nVerify it has been created.\r\nkubectl get secrets myregistrykey\r\nThe output is similar to this:\r\nNAME TYPE DATA AGE\r\nmyregistrykey  kubernetes.io/.dockerconfigjson  1    1d\r\nAdd image pull secret to service account\r\nNext, modify the default service account for the namespace to use this Secret as an imagePullSecret.\r\nkubectl patch serviceaccount default -p '{\"imagePullSecrets\": [{\"name\": \"myregistrykey\"}]}'\r\nYou can achieve the same outcome by editing the object manually:\r\nkubectl edit serviceaccount/default\r\nThe output of the sa.yaml file is similar to this:\r\nYour selected text editor will open with a configuration looking something like this:\r\napiVersion: v1\r\nkind: ServiceAccount\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 6 of 11\n\nmetadata:\r\n creationTimestamp: 2021-07-07T22:02:39Z\r\n name: default\r\n namespace: default\r\n resourceVersion: \"243024\"\r\n uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6\r\nUsing your editor, delete the line with key resourceVersion , add lines for imagePullSecrets: and save it.\r\nLeave the uid value set the same as you found it.\r\nAfter you made those changes, the edited ServiceAccount looks something like this:\r\napiVersion: v1\r\nkind: ServiceAccount\r\nmetadata:\r\n creationTimestamp: 2021-07-07T22:02:39Z\r\n name: default\r\n namespace: default\r\n uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6\r\nimagePullSecrets:\r\n - name: myregistrykey\r\nVerify that imagePullSecrets are set for new Pods\r\nNow, when a new Pod is created in the current namespace and using the default ServiceAccount, the new Pod has\r\nits spec.imagePullSecrets field set automatically:\r\nkubectl run nginx --image=\u003cregistry name\u003e/nginx --restart=Never\r\nkubectl get pod nginx -o=jsonpath='{.spec.imagePullSecrets[0].name}{\"\\n\"}'\r\nThe output is:\r\nmyregistrykey\r\nServiceAccount token volume projection\r\nFEATURE STATE: Kubernetes v1.20 [stable]\r\nNote:\r\nTo enable and use token request projection, you must specify each of the following command line arguments to\r\nkube-apiserver :\r\n--service-account-issuer\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 7 of 11\n\ndefines the Identifier of the service account token issuer. You can specify the --service-account-issuer\r\nargument multiple times, this can be useful to enable a non-disruptive change of the issuer. When this flag\r\nis specified multiple times, the first is used to generate tokens and all are used to determine which issuers\r\nare accepted. You must be running Kubernetes v1.22 or later to be able to specify --service-account-issuer multiple times.\r\n--service-account-key-file\r\nspecifies the path to a file containing PEM-encoded X.509 private or public keys (RSA or ECDSA), used\r\nto verify ServiceAccount tokens. The specified file can contain multiple keys, and the flag can be specified\r\nmultiple times with different files. If specified multiple times, tokens signed by any of the specified keys\r\nare considered valid by the Kubernetes API server.\r\n--service-account-signing-key-file\r\nspecifies the path to a file that contains the current private key of the service account token issuer. The\r\nissuer signs issued ID tokens with this private key.\r\n--api-audiences (can be omitted)\r\ndefines audiences for ServiceAccount tokens. The service account token authenticator validates that tokens\r\nused against the API are bound to at least one of these audiences. If api-audiences is specified multiple\r\ntimes, tokens for any of the specified audiences are considered valid by the Kubernetes API server. If you\r\nspecify the --service-account-issuer command line argument but you don't set --api-audiences , the\r\ncontrol plane defaults to a single element audience list that contains only the issuer URL.\r\nThe kubelet can also project a ServiceAccount token into a Pod. You can specify desired properties of the token,\r\nsuch as the audience and the validity duration. These properties are not configurable on the default\r\nServiceAccount token. The token will also become invalid against the API when either the Pod or the\r\nServiceAccount is deleted.\r\nYou can configure this behavior for the spec of a Pod using a projected volume type called\r\nServiceAccountToken .\r\nThe token from this projected volume is a JSON Web Token (JWT). The JSON payload of this token follows a\r\nwell defined schema - an example payload for a pod bound token:\r\n{\r\n \"aud\": [ # matches the requested audiences, or the API server's default audiences when none are explicitly re\r\n \"https://kubernetes.default.svc\"\r\n ],\r\n \"exp\": 1731613413,\r\n \"iat\": 1700077413,\r\n \"iss\": \"https://kubernetes.default.svc\", # matches the first value passed to the --service-account-issuer fla\r\n \"jti\": \"ea28ed49-2e11-4280-9ec5-bc3d1d84661a\",\r\n \"kubernetes.io\": {\r\n \"namespace\": \"kube-system\",\r\n \"node\": {\r\n \"name\": \"127.0.0.1\",\r\n \"uid\": \"58456cb0-dd00-45ed-b797-5578fdceaced\"\r\n },\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 8 of 11\n\n\"pod\": {\r\n \"name\": \"coredns-69cbfb9798-jv9gn\",\r\n \"uid\": \"778a530c-b3f4-47c0-9cd5-ab018fb64f33\"\r\n },\r\n \"serviceaccount\": {\r\n \"name\": \"coredns\",\r\n \"uid\": \"a087d5a0-e1dd-43ec-93ac-f13d89cd13af\"\r\n },\r\n \"warnafter\": 1700081020\r\n },\r\n \"nbf\": 1700077413,\r\n \"sub\": \"system:serviceaccount:kube-system:coredns\"\r\n}\r\nLaunch a Pod using service account token projection\r\nTo provide a Pod with a token with an audience of vault and a validity duration of two hours, you could define\r\na Pod manifest that is similar to:\r\napiVersion: v1\r\nkind: Pod\r\nmetadata:\r\n name: nginx\r\nspec:\r\n containers:\r\n - image: nginx\r\n name: nginx\r\n volumeMounts:\r\n - mountPath: /var/run/secrets/tokens\r\n name: vault-token\r\n serviceAccountName: build-robot\r\n volumes:\r\n - name: vault-token\r\n projected:\r\n sources:\r\n - serviceAccountToken:\r\n path: vault-token\r\n expirationSeconds: 7200\r\n audience: vault\r\nCreate the Pod:\r\nkubectl create -f https://k8s.io/examples/pods/pod-projected-svc-token.yaml\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 9 of 11\n\nThe kubelet will: request and store the token on behalf of the Pod; make the token available to the Pod at a\r\nconfigurable file path; and refresh the token as it approaches expiration. The kubelet proactively requests rotation\r\nfor the token if it is older than 80% of its total time-to-live (TTL), or if the token is older than 24 hours.\r\nThe application is responsible for reloading the token when it rotates. It's often good enough for the application to\r\nload the token on a schedule (for example: once every 5 minutes), without tracking the actual expiry time.\r\nService account issuer discovery\r\nFEATURE STATE: Kubernetes v1.21 [stable]\r\nIf you have enabled token projection for ServiceAccounts in your cluster, then you can also make use of the\r\ndiscovery feature. Kubernetes provides a way for clients to federate as an identity provider, so that one or more\r\nexternal systems can act as a relying party.\r\nNote:\r\nThe issuer URL must comply with the OIDC Discovery Spec. In practice, this means it must use the https\r\nscheme, and should serve an OpenID provider configuration at {service-account-issuer}/.well-known/openid-configuration .\r\nIf the URL does not comply, ServiceAccount issuer discovery endpoints are not registered or accessible.\r\nWhen enabled, the Kubernetes API server publishes an OpenID Provider Configuration document via HTTP. The\r\nconfiguration document is published at /.well-known/openid-configuration . The OpenID Provider\r\nConfiguration is sometimes referred to as the discovery document. The Kubernetes API server publishes the\r\nrelated JSON Web Key Set (JWKS), also via HTTP, at /openid/v1/jwks .\r\nNote:\r\nThe responses served at /.well-known/openid-configuration and /openid/v1/jwks are designed to be OIDC\r\ncompatible, but not strictly OIDC compliant. Those documents contain only the parameters necessary to perform\r\nvalidation of Kubernetes service account tokens.\r\nClusters that use RBAC include a default ClusterRole called system:service-account-issuer-discovery . A\r\ndefault ClusterRoleBinding assigns this role to the system:serviceaccounts group, which all ServiceAccounts\r\nimplicitly belong to. This allows pods running on the cluster to access the service account discovery document via\r\ntheir mounted service account token. Administrators may, additionally, choose to bind the role to\r\nsystem:authenticated or system:unauthenticated depending on their security requirements and which\r\nexternal systems they intend to federate with.\r\nThe JWKS response contains public keys that a relying party can use to validate the Kubernetes service account\r\ntokens. Relying parties first query for the OpenID Provider Configuration, and use the jwks_uri field in the\r\nresponse to find the JWKS.\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 10 of 11\n\nIn many cases, Kubernetes API servers are not available on the public internet, but public endpoints that serve\r\ncached responses from the API server can be made available by users or by service providers. In these cases, it is\r\npossible to override the jwks_uri in the OpenID Provider Configuration so that it points to the public endpoint,\r\nrather than the API server's address, by passing the --service-account-jwks-uri flag to the API server. Like the\r\nissuer URL, the JWKS URI is required to use the https scheme.\r\nWhat's next\r\nSee also:\r\nRead the Cluster Admin Guide to Service Accounts\r\nRead about Authorization in Kubernetes\r\nRead about Secrets\r\nor learn to distribute credentials securely using Secrets\r\nbut also bear in mind that using Secrets for authenticating as a ServiceAccount is deprecated. The\r\nrecommended alternative is ServiceAccount token volume projection.\r\nRead about projected volumes.\r\nFor background on OIDC discovery, read the ServiceAccount signing key retrieval Kubernetes\r\nEnhancement Proposal\r\nRead the OIDC Discovery Spec\r\nSource: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nhttps://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/\r\nPage 11 of 11",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/"
	],
	"report_names": [
		"configure-service-account"
	],
	"threat_actors": [],
	"ts_created_at": 1775434821,
	"ts_updated_at": 1775826770,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/05a8242583dd1279b5316b7837d7db9106ad868a.pdf",
		"text": "https://archive.orkl.eu/05a8242583dd1279b5316b7837d7db9106ad868a.txt",
		"img": "https://archive.orkl.eu/05a8242583dd1279b5316b7837d7db9106ad868a.jpg"
	}
}