# Secrets in Kubernetes

A Secret in Kubernetes is an API object designed to store and manage sensitive information such as passwords, API keys, TLS certificates, and database credentials. Unlike ConfigMaps, which store non-sensitive configuration data, Secrets provide a more secure way to handle confidential information within a cluster.

By default, Kubernetes Secrets are stored in [Base64-encoded format](https://www.base64encode.org/) inside etcd (the cluster’s key-value store). While this isn’t encryption, it prevents sensitive values from being exposed as plain text in configuration files. However, additional security measures are required to properly protect Secrets.

## **Why Use a Secret Instead of a ConfigMap?**

Using Secrets instead of [ConfigMaps](/content/finops-glossary/configmap-in-kubernetes/index.html) offers several benefits:

- **Prevents storing sensitive data in container images** – Secrets can be mounted at runtime instead of being hardcoded in the application.
- **Reduces exposure risks** – Secrets are not visible in environment variables by default, reducing the risk of accidental leaks.
- **Supports encrypted storage** – When configured properly, Kubernetes Secrets can be encrypted at rest.
- **Tighter access control** – You can use [RBAC (Role-Based Access Control)](https://en.wikipedia.org/wiki/Role-based_access_control) to restrict access to specific users and pods.

## **How Does it Work?**

A Secret in Kubernetes can store:

- **Opaque data** (arbitrary key-value pairs).
- **TLS certificates** (used for HTTPS communication).
- **Docker registry credentials** (for pulling private container images).

Can be consumed by pods through:

- **Environment variables**
- **Volume mounts**
- **Direct API calls from applications**

## **Example: Creating a Secret**

A Secret storing a database password:

```none
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  DB_PASSWORD: c2VjdXJlLXJvbmRvbS1wYXNzd29yZA==  # Base64-encoded value
```

To manually encode a password:

```none
echo -n "secure-random-password" | base64
```

Once created (`kubectl apply -f secret.yaml`), this Secret can be used by pods.

### **Using a Secret in a Pod (Environment Variables)**

```none
apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: my-app
    image: my-app-image
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: DB_PASSWORD
```

### **Using a Secret as a Volume**

```none
apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: my-app
    image: my-app-image
    volumeMounts:
    - name: secret-volume
      mountPath: "/etc/secrets"
  volumes:
  - name: secret-volume
    secret:
      secretName: db-secret
```

The Secret will be accessible as a file at `/etc/secrets/DB_PASSWORD`.

## **Common Challenges**

### **1\. Base64 Encoding Is Not Encryption**

- Kubernetes stores Secrets **Base64-encoded**, but this **does not** provide encryption.
- If etcd (the database storing Kubernetes data) is not encrypted, anyone with access can **decode** and read the Secrets.

### **2\. Default Storage Is Insecure**

- By default, Secrets are stored **unencrypted** in etcd.
- Kubernetes **does not** rotate or expire Secrets automatically.

### **3\. Access Control Issues**

- By default, **any pod** in a namespace can access Secrets unless restricted.
- Misconfigured RBAC rules can lead to unintended access to Secrets.

## **Best Practices**

- **Enable Encryption at Rest** – Configure Kubernetes to encrypt Secrets stored in etcd.
- **Use External Secret Management** – Store Secrets in an external system like AWS Secrets Manager, HashiCorp Vault, or Google Secret Manager.
- **Restrict Access with RBAC** – Ensure only necessary users and applications can access Secrets.
- **Use Ephemeral Secrets** – Rotate and expire Secrets regularly instead of using long-lived credentials.
- **Avoid Mounting Secrets as Environment Variables** – Environment variables are visible to processes and might be leaked in logs or debugging tools.
- **Use Immutable Secrets** – Mark Secrets as immutable (`kubectl annotate secret db-secret kubernetes.io/immutable=true`) to prevent accidental changes.

## **Popular Tools for Managing Kubernetes Secrets**

- **Sealed Secrets** – Encrypts Secrets before storing them in Kubernetes.
- **External Secrets Operator** – Syncs Kubernetes Secrets with cloud-based secret stores.
- **Vault by HashiCorp** – A highly secure tool for managing secrets outside Kubernetes.
- **SOPS (Secrets OPerationS)** – A tool for encrypting Kubernetes Secrets using GCP KMS, AWS KMS, or Azure Key Vault.

## **Further Reading**

- [Kubernetes Documentation](https://kubernetes.io/docs/concepts/configuration/secret/)
- [Encrypting in etcd](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)
- [HashiCorp Vault for Kubernetes](https://www.vaultproject.io/docs/platform/k8s)
