What Are Kubernetes Secrets? Uses, Types, and How to Create

14 minute read
Main takeaways from Kubernetes Secrets:
  • Kubernetes secrets securely store sensitive data, such as API keys, passwords, and TLS certificates, reducing exposure risks compared to hardcoding credentials in pods or configurations.

  • Secrets can be consumed by pods in multiple ways, including environment variables, mounted volumes, and for authenticating access to private container registries.

  • Managing secrets effectively requires proper access control, rotation, and monitoring to prevent credential leaks and unauthorized access.

  • Kubernetes lacks native encryption for secrets at rest, which makes additional security measures like RBAC restrictions and external secret management tools (e.g., Vault, AWS Secrets Manager) crucial.

A Kubernetes secret is an object in the Kubernetes ecosystem that contains sensitive information (think keys, passwords, and tokens). Instead of including this data directly in a pod or a deployment, storing data you want to keep secure in a secret allows you to reduce your attack surface - and reduce the chance this critical information is altered during the software development life cycle.

apiVersion: v1

kind: Secret

metadata:

 name: file-credential

data:

 .secret-file: dmFsdWUtMg0KDQo=

Once you create a secret, you need to refer to that secret in your pod. The config file below gives your pod access to the Kubernetes secret we created in the manifest above:

apiVersion: v1


kind: Pod


metadata:


 name: secret-files-pod


spec:


 volumes:


   - name: secret-volume


     secret:


       secretName: file-secret


 containers:


   - name: dotfile-test-container


     image: registry.k8s.io/busybox


     command:


       - ls


       - "-l"


       - "/etc/secret-volume"


     volumeMounts:


       - name: secret-volume


         readOnly: true


         mountPath: "/etc/secret-volume"

In this example, your secrets file will be present in the /etc/secret-volume location in the file system for your application to access. (In the volume mount definition, you specify where the file path will be.) 

Use cases for Kubernetes secrets

Let’s take a look at specific scenarios where it’s best practice to leverage Kubernetes secrets:

  • Providing environment variables to containers: Some environment variables can be used to control the behavior of your application, so it’s a good idea to use secrets to provide those values. These container environment variables can also contain sensitive information like credentials, which are used to call third-party apps (for example, payment gateways). 

  • Providing credentials such as SSH keys and passwords to containers: Secrets can deliver SSH credentials, passwords, TLS certificates, and more to containers. SSH keys and TLS certificates are important security tokens that can be used in applications and via secrets delivered to them. 

  • Allowing container images to be pulled from the registry: Secrets are also used when allowing the image-pull step in nodes. You can configure image pull secrets by providing Docker registry credentials in secrets, which will be used by Kubelet to pull the container images stored in the registry.

  • Storing extra information like Helm details: Just like Helm uses secrets, other applications can use secrets to carry out their functions.

Types of Kubernetes secrets

Based on specified secret values, secrets are divided into these types:

Opaque

Opaque secrets are generic secrets that anyone can create and use. These are basic key-value pairs and are the default secret type, so if you don’t explicitly mention the type, an Opaque secret will be created (with opaque type defined). Using this secret type is often recommended for storing arbitrary key-value pairs when no specialized secret format is required.

ServiceAccount token secrets

These are the tokens that are used to identify the service accounts, which can be used to provide specified Kubernetes APIs with access to pods. This API uses the kubernetes.io/service-account-token type. 

SSH-auth

This type of secret is used to save data that’s used for SSH authentication purposes. SSH authentication secrets use the kubernetes.io/ssh-auth (defined and public secret) type.

TLS

Use these to store TLS certificates and the associated keys; kubernetes.io/tls is the type to define to leverage this form of secret.

Basic-auth

For basic authentication secrets, define the type as kubernetes.io/basic-auth.

Docker-cgf and Dockerconfigjson

Configurations related to Docker and registry secrets are generally stored in these two types of secrets. To use docker-cfg and dockerconfigjson, define the type as kubernetes.io/dockercfg or kubernetes.io/dockerconfigjson.

Token

This secrets type refers to the bootstrap token secrets that are used to add new nodes to a Kubernetes cluster. To use this token in the node bootstrap process, define bootstrap.kubernetes.io/token.

How to create a secret in Kubernetes

Below are the steps to create and apply a Kubernetes secret:

1. Encode the secret value in Base64

Before adding a Secret to Kubernetes, the sensitive data must be encoded in Base64. Run the following command to encode your secret value:

echo -n "value-2" | base64

This outputs an encoded string, which you will use in the Secret manifest. Kubernetes requires Secrets in Base64 format to ensure proper storage and retrieval. Keep in mind that Base64 is not encryption, so the data remains readable if decoded. Use additional security measures like encryption at rest for better protection.

2. Create a secret YAML manifest

Now, define the Secret in a YAML file using the encoded value. Create a new file called secret.yaml and add the following content:

apiVersion: v1
kind: Secret
metadata:
  name: file-credential
data:
  .secret-file: dmFsdWUtMg0KDQo=
  • The .secret-file key represents the name of the secret file inside the pod, and the corresponding value is the Base64-encoded secret.

  • Kubernetes allows secret names beginning with dot characters, which means these files will be treated as hidden files when mounted inside a container. Keep in mind that in Unix-like systems, files beginning with dot are hidden by default—so if you run a standard ls -l, they may not appear; use ls -la to display all files, including hidden ones.

Alternatively, you can use stringData to store unencoded values, and Kubernetes will automatically encode them:

apiVersion: v1
kind: Secret
metadata:
  name: file-credential
stringData:
  .secret-file: value-2

3. Apply the secret to the cluster

Use kubectl apply to create the Secret in the Kubernetes cluster:

kubectl apply -f secret.yaml

To confirm that the Secret was created successfully, list all Secrets:

kubectl get secrets

To view the specific Secret in YAML format:

kubectl get secret file-credential -o yaml

To verify the stored value (decoding it from Base64):

kubectl get secret file-credential -o jsonpath="{.data.\.secret-file}" | base64 --decode

4. Mount the secret in a pod

To allow a pod to use the Secret, you need to define a volume that references it. Create a new file called pod.yaml and add the following configuration:

apiVersion: v1
kind: Pod
metadata:
  name: secret-files-pod
spec:
  volumes:
    - name: secret-volume
      secret:
        secretName: file-credential
  containers:
    - name: dotfile-test-container
      image: registry.k8s.io/busybox
      command: [ "ls", "-l", "/etc/secret-volume" ]
      volumeMounts:
        - name: secret-volume
          readOnly: true
          mountPath: "/etc/secret-volume"
  • This mounts the Secret as a read-only file inside the container in a pod at /etc/secret-volume.

  • Kubernetes automatically creates a file for each key inside the mounted directory.

  • The secret value will be stored inside /etc/secret-volume/.secret-file.

  • This approach is also applicable for secrets with static pods, where the secret is pre-mounted into the pod's filesystem.

5. Deploy the pod and confirm the secret is accessible

Apply the pod configuration to deploy the pod:

kubectl apply -f pod.yaml

Check if the pod is running:

kubectl get pods

Instead of relying on logs, exec into the pod and verify the Secret is present:

kubectl exec secret-files-pod -- ls -l /etc/secret-volume
kubectl exec secret-files-pod -- cat /etc/secret-volume/.secret-file

If everything is set up correctly, the first command will list the secret file, and the second command will print its decoded contents.

How pods consume Kubernetes secrets

Kubernetes provides multiple ways for pods to securely access secrets, depending on the application's requirements. Secrets can be injected as environment variables, mounted as volumes, used for pulling container images, or leveraged for API authentication. Let's explore each method below with examples.

1. Using secrets as environment variables

Kubernetes allows secrets to be injected into a container’s environment variables, enabling applications to securely access sensitive data without hardcoding credentials. This method is useful for passing API keys, database passwords, or authentication tokens.

Below is a YAML example where a pod references a secret (db-secret) as an environment variable:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  DB_PASSWORD: c3VwZXJzZWNyZXQ=  # Base64-encoded "supersecret"
---
apiVersion: v1
kind: Pod
metadata:
  name: env-secret-pod
spec:
  containers:
    - name: app-container
      image: nginx
      env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: DB_PASSWORD
  • The DB_PASSWORD environment variable pulls its value from the db-secret secret.

  • This keeps sensitive data out of the container’s image and deployment files.

2. Mounting secrets as volumes

Another approach is mounting secrets as files inside a container, allowing applications to read them at runtime. This is ideal for SSH keys, TLS certificates, or complex configurations that don’t fit neatly into environment variables.

Here’s an example of a pod mounting a secret (tls-secret) as a volume:

apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
type: kubernetes.io/tls
data:
  tls.crt: BASE64_ENCODED_CERT
  tls.key: BASE64_ENCODED_KEY
---
apiVersion: v1
kind: Pod
metadata:
  name: tls-secret-pod
spec:
  volumes:
    - name: tls-volume
      secret:
        secretName: tls-secret
  containers:
    - name: web-server
      image: nginx
      volumeMounts:
        - name: tls-volume
          mountPath: "/etc/tls"
          readOnly: true
  • The secret is mounted inside the container at /etc/tls.

  • Applications can securely read the secret from this path at runtime.

3. Using secrets for pulling container images

When pulling images from private container registries, Kubernetes requires authentication credentials, which can be stored as a Docker registry secret. This secret allows nodes to securely fetch images without exposing credentials.

To use a container image pull secret (docker-registry-secret), reference it in a pod spec like this:

apiVersion: v1
kind: Pod
metadata:
  name: private-registry-pod
spec:
  containers:
    - name: private-app
      image: my-private-registry.com/private-image:latest
  imagePullSecrets:
    - name: docker-registry-secret
  • The imagePullSecrets field specifies the secret containing registry credentials.

  • Kubernetes will use this secret when pulling the container image.

4. Service account secrets for API authentication

Kubernetes automatically mounts service account tokens as secrets inside pods, allowing them to authenticate with the Kubernetes API securely. These tokens are used for inter-service communication and permission management.

By default, Kubernetes mounts the service account token in each pod at /var/run/secrets/kubernetes.io/serviceaccount/token. An application inside the pod can use this token to authenticate API requests, as shown in this example:

apiVersion: v1
kind: Pod
metadata:
  name: service-account-pod
spec:
  serviceAccountName: default
  containers:
    - name: api-client
      image: busybox
      command: [ "cat", "/var/run/secrets/kubernetes.io/serviceaccount/token" ]
  • The service account token allows the pod to interact with the Kubernetes API.

  • This is essential for applications that need to query cluster resources or perform automated tasks.

Managing Kubernetes secrets: Key actions and best practices

Kubernetes offers different ways to securely handle secrets, from creation and access control to monitoring and rotation. Proper secret management helps reduce the risk of unauthorized access and credential leaks. Below are key actions and best practices to ensure secrets are handled securely.

1. Create secrets

Kubernetes secrets can be created using three main methods: YAML manifests, kubectl commands, and the Kubernetes API.

YAML manifests allow you to define secrets declaratively, while kubectl create secret generic provides a quick command-line approach. For advanced use cases, the Kubernetes API enables dynamic secret creation within applications.

2. List secrets

To track secret usage in a Kubernetes namespace using kubectl, you can list all secrets to monitor their presence and ensure proper management. This helps identify outdated or unnecessary secrets that should be rotated or removed. Regularly reviewing secrets also improves security by reducing the risk of exposure.

3. Inspect secrets

Retrieving metadata and key names for a secret helps verify its contents and track usage. Using kubectl describe secret <secret-name> displays details such as creation timestamp, labels, annotations, and the keys stored within the secret. This allows administrators to confirm the presence of expected data without exposing the actual secret values.

4. Decode secret values

Kubernetes secrets are stored in Base64-encoded format rather than plaintext, requiring decoding for human-readable access.

To retrieve and decode a secret’s value, you must first extract it using kubectl get secret <secret-name> -o yaml and then apply a Base64 decoding command. This ensures that secret values remain obscured by default but can be accessed by authorized users when necessary.

5. Update secrets

To modify an existing secret, you can use kubectl edit secret <secret-name> to make inline changes or kubectl replace -f <file>.yaml to update it with a new configuration.

Alternatively, you can delete the existing secret and recreate it to ensure a clean update. Since changes to secrets aren’t automatically reflected in running pods, restarting affected workloads may be necessary.

6. Rotate secrets

Regularly rotating secrets helps mitigate the risk of credential leaks and unauthorized access by ensuring that compromised or outdated secrets are no longer valid.

Automating secret rotation reduces human error and enforces security best practices, especially for highly sensitive data such as API keys and database credentials. Kubernetes does not automatically propagate secret updates to running pods, so workloads may need to be restarted to apply new values.

7. Mount secrets in pods

Kubernetes secrets can be made available to containers by mounting them as volumes or injecting them as environment variables.

Mounting secrets as volumes allows applications to read them as files at runtime, while using environment variables enables direct access within the container’s execution environment. Choosing the right method depends on the application’s security requirements and how it consumes sensitive data.

8. Restrict access to secrets

Kubernetes Role-Based Access Control (RBAC) policies restrict which users and workloads can view or modify secrets, ensuring that only authorized entities have access.

By defining roles and role bindings, administrators can configure least privilege access to secrets, preventing unauthorized users from listing or retrieving secrets. This privileged access to secrets reduces the risk of accidental exposure or malicious access to secret data.

9. Monitor secret usage

Monitoring which workloads reference a secret helps identify unused or orphaned secrets that should be rotated or deleted.

Regular audits prevent unnecessary secret retention, reducing the risk of outdated credentials being exploited. By tracking secret usage, security teams can ensure that secrets are only accessible by the applications that actually need them.

10. Audit secret access

Enabling Kubernetes audit logs helps detect unauthorized access to secrets by capturing API requests related to secret creation, modification, and retrieval.

These logs provide visibility into who accessed or attempted to access a secret, helping security teams identify potential threats. Regularly reviewing audit logs strengthens security by allowing organizations to respond to suspicious activity in real time.

11. Delete secrets

Removing unused secrets reduces the attack surface by eliminating credentials that are no longer needed but could be exploited if left in the system. Stale secrets increase security risks, as they may contain outdated but still valid credentials. Regularly auditing and deleting unnecessary secrets ensures a cleaner and more secure Kubernetes environment.

12. Back up and restore secrets

Keeping encrypted backups of secrets is crucial for disaster recovery and compliance, ensuring that sensitive data can be restored in case of accidental deletion or system failures.

Secure backups should be stored in trusted, access-controlled locations, such as cloud key management services or encrypted storage solutions. Proper backup and recovery strategies help maintain operational resilience while meeting regulatory requirements for data protection.

Are Kubernetes secrets safe?

It’s important to remember that the way Kubernetes secrets are stored in etcd is not very secure because they aren’t encrypted. Instead, they’re stored as Base64-encoded objects. This means that if anyone gets their hands on the data, they can quickly decode the Base64 string and use all the secrets—all they need is access to see the Kubernetes secrets objects. (You can get around using Base64 by leveraging the stringData field.)

Configuring Kubernetes secrets to make them more secure 

Below are a few steps you can take to keep Kubernetes secrets secure: 

  • Implement RBAC rules: Kubernetes has rich support for policy-based and role-based access control. You can very easily control who can access which components in Kubernetes, meaning you can restrict the usage of secrets APIs and remove access to secrets from all users. Making sure that no one can access secrets via the Kubectl command-line tool is the first step.

  • Allow only containers to access specific secrets: Just like controlling RBAC for users, you can restrict secrets access to a particular set of applications. This way, your secrets will be accessible only to applications that are authorized to use them. 

  • Enable encryption at rest: Encryption at rest is a feature that can be enabled on the API server using the flag --encryption-provider-config. In this flag, you’ll refer to a file that specifies the providers for which the encryption at rest will be enabled. The content of the YAML file will be something like this

apiVersion: apiserver.config.k8s.io/v1

kind: EncryptionConfiguration

resources:

 - resources:

     - events

   providers:

     - identity: {} # do not encrypt Events even though *.* is specified below

 - resources:

     - '*.apps' 

   providers:

     - aescbc:

         keys:

         - name: first_key

           secret: c2VlkansaklnsxlanslxHsa1hUndklMgaXQ/Cg==

 - resources:

     - '*.*' 
   providers:

     - aescbc:

         keys:

         - name: second_key

           secret: c2VjcmV12ds2JJklY3vyZSwgSSB0aGluaw==

If you look at this file, you’ll notice an array of resources we’re applying conditions to. The events resource has no encryption at rest because the provider identity is an empty array. Next, we’ve specified that resources under the app's API will be encrypted at rest. The last array shows that everything in Kubernetes will be encrypted. 

Tools for robust secrets management 

By following the configuration tips above, you can make sure that no unauthorized users or entities can access your secrets. However, actually delivering secrets to Kubernetes also presents security risks, which require role-based access control and other checks to mitigate. These features aren’t native to Kubernetes, but luckily, there are many effective tools to choose from. Let’s look at the third-party solutions first.

Third-party solutions

  • Vault: Vault is an industry standard and is used widely. By using the sidecar container, it provides functionalities like RBAC, auditing, secrets rotation, and a dynamic secrets engine. You can use Vault and deliver secrets to your containers without worrying about security. 

  • Secrets Manager from AWS: AWS Secrets Manager is a much more affordable solution, but it lacks many of Vault’s features, like dynamic secrets generation and an RBAC UI. That said, you can implement RBAC using AWS native IAM policies.

  • Key Vault in Azure: Key Vault is similar to AWS Secrets Manager and secures secrets, TLS certificates, SSH keys, and more. One big benefit? You can create vaults in Azure’s international data centers to keep your secrets safer and make them more efficient. 

Open-source solutions

  • Helm secrets: Helm is widely used to manage deployments in Kubernetes, and Helm secrets is an easy solution to integrate. Though it’s not as secure as a Vault, with proper privileges, Helm is a worthy open-source solution. 

  • Open-source Vault: Vault has an open-source distribution in addition to the paid version we’ve already discussed. You can deploy the open-source version of Vault in your Kubernetes clusters or on a native VM and utilize it to push secrets to your containers. This version of Vault provides almost all of the features of the upgraded version except for backup and restore.

Conclusion

Secure everything you build and run in the cloud

Kubernetes secrets have some security gaps, but these can be handled by following the principle of least privilege and implementing encryption at rest. Auditing is also a key means of limiting your attack surface, and all the tools mentioned above have one or more ways to produce audit logs. 

On the other hand, it can be tricky to keep track of all of the essential data from these disparate logs. Enter Wiz. With our all-in-one platform, you get complete visibility across containers, Kubernetes, and cloud environments in minutes without agents, and you can leverage the power of the Wiz Security Graph to analyze and prioritize risk with complete context.

Ready to secure everything you build and run in the cloud? Schedule a demo today

Empower your developers to be more productive, from code to production

Learn why the fastest growing companies choose Wiz to secure containers, Kubernetes, and cloud environments from build-time to real-time.

Get a demo 

FAQs