--- reviewers: - marosset - jsturtevant - zshihang title: Projected Volumes content_type: concept weight: 21 # just after persistent volumes --- This document describes _projected volumes_ in Kubernetes. Familiarity with [volumes](/docs/concepts/storage/volumes/) is suggested. ## Introduction A `projected` volume maps several existing volume sources into the same directory. Currently, the following types of volume sources can be projected: * [`secret`](/docs/concepts/storage/volumes/#secret) * [`downwardAPI`](/docs/concepts/storage/volumes/#downwardapi) * [`configMap`](/docs/concepts/storage/volumes/#configmap) * [`serviceAccountToken`](#serviceaccounttoken) All sources are required to be in the same namespace as the Pod. For more details, see the [all-in-one volume](https://git.k8s.io/design-proposals-archive/node/all-in-one-volume.md) design document. ### Example configuration with a secret, a downwardAPI, and a configMap {#example-configuration-secret-downwardapi-configmap} {{% code_sample file="pods/storage/projected-secret-downwardapi-configmap.yaml" %}} ### Example configuration: secrets with a non-default permission mode set {#example-configuration-secrets-nondefault-permission-mode} {{% code_sample file="pods/storage/projected-secrets-nondefault-permission-mode.yaml" %}} Each projected volume source is listed in the spec under `sources`. The parameters are nearly the same with two exceptions: * For secrets, the `secretName` field has been changed to `name` to be consistent with ConfigMap naming. * The `defaultMode` can only be specified at the projected level and not for each volume source. However, as illustrated above, you can explicitly set the `mode` for each individual projection. ## serviceAccountToken projected volumes {#serviceaccounttoken} You can inject the token for the current [service account](/docs/reference/access-authn-authz/authentication/#service-account-tokens) into a Pod at a specified path. For example: {{% code_sample file="pods/storage/projected-service-account-token.yaml" %}} The example Pod has a projected volume containing the injected service account token. Containers in this Pod can use that token to access the Kubernetes API server, authenticating with the identity of [the pod's ServiceAccount](/docs/tasks/configure-pod-container/configure-service-account/). The `audience` field contains the intended audience of the token. A recipient of the token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. This field is optional and it defaults to the identifier of the API server. The `expirationSeconds` is the expected duration of validity of the service account token. It defaults to 1 hour and must be at least 10 minutes (600 seconds). An administrator can also limit its maximum value by specifying the `--service-account-max-token-expiration` option for the API server. The `path` field specifies a relative path to the mount point of the projected volume. {{< note >}} A container using a projected volume source as a [`subPath`](/docs/concepts/storage/volumes/#using-subpath) volume mount will not receive updates for those volume sources. {{< /note >}} ## SecurityContext interactions The [proposal](https://git.k8s.io/enhancements/keps/sig-storage/2451-service-account-token-volumes#proposal) for file permission handling in projected service account volume enhancement introduced the projected files having the correct owner permissions set. ### Linux In Linux pods that have a projected volume and `RunAsUser` set in the Pod [`SecurityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context), the projected files have the correct ownership set including container user ownership. When all containers in a pod have the same `runAsUser` set in their [`PodSecurityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) or container [`SecurityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1), then the kubelet ensures that the contents of the `serviceAccountToken` volume are owned by that user, and the token file has its permission mode set to `0600`. {{< note >}} {{< glossary_tooltip text="Ephemeral containers" term_id="ephemeral-container" >}} added to a Pod after it is created do *not* change volume permissions that were set when the pod was created. If a Pod's `serviceAccountToken` volume permissions were set to `0600` because all other containers in the Pod have the same `runAsUser`, ephemeral containers must use the same `runAsUser` to be able to read the token. {{< /note >}} ### Windows In Windows pods that have a projected volume and `RunAsUsername` set in the Pod `SecurityContext`, the ownership is not enforced due to the way user accounts are managed in Windows. Windows stores and manages local user and group accounts in a database file called Security Account Manager (SAM). Each container maintains its own instance of the SAM database, to which the host has no visibility into while the container is running. Windows containers are designed to run the user mode portion of the OS in isolation from the host, hence the maintenance of a virtual SAM database. As a result, the kubelet running on the host does not have the ability to dynamically configure host file ownership for virtualized container accounts. It is recommended that if files on the host machine are to be shared with the container then they should be placed into their own volume mount outside of `C:\`. By default, the projected files will have the following ownership as shown for an example projected volume file: ```powershell PS C:\> Get-Acl C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt | Format-List Path : Microsoft.PowerShell.Core\FileSystem::C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt Owner : BUILTIN\Administrators Group : NT AUTHORITY\SYSTEM Access : NT AUTHORITY\SYSTEM Allow FullControl BUILTIN\Administrators Allow FullControl BUILTIN\Users Allow ReadAndExecute, Synchronize Audit : Sddl : O:BAG:SYD:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) ``` This implies all administrator users like `ContainerAdministrator` will have read, write and execute access while, non-administrator users will have read and execute access. {{< note >}} In general, granting the container access to the host is discouraged as it can open the door for potential security exploits. Creating a Windows Pod with `RunAsUser` in it's `SecurityContext` will result in the Pod being stuck at `ContainerCreating` forever. So it is advised to not use the Linux only `RunAsUser` option with Windows Pods. {{< /note >}}