> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes Secrets its Drawbacks

> This article reviews Kubernetes Secrets, their limitations, and how to securely manage sensitive data using HashiCorp Vault.

Welcome to the HashiCorp Vault series! In this lesson, we’ll review how Kubernetes stores sensitive data in Secrets, highlight key drawbacks, and prepare for a secure injection of dynamic secrets using Vault.

## Why Use Kubernetes Secrets?

Managing sensitive data—passwords, API tokens, SSH keys—is critical in any deployment. Kubernetes Secrets help you:

* Decouple credentials from application pods and container images
* Store sensitive values centrally in etcd (the Kubernetes key-value store)
* Consume secrets as mounted volumes or environment variables

| Mount Method    | Use Case                              | Example                  |
| --------------- | ------------------------------------- | ------------------------ |
| Volume mount    | Inject files (e.g., TLS certs)        | `volumes: - name: creds` |
| Environment var | Pass small values (e.g., DB password) | `env: - name: DB_PASS`   |

<Callout icon="triangle-alert" color="#FF6B6B">
  Kubernetes Secrets are only base64-encoded, not encrypted by default. Any user with API or etcd access can decode them.
</Callout>

Learn more in the [Kubernetes Secrets documentation][k8s-secrets].

## Creating a Generic Secret

Create a simple Secret in one command:

```bash theme={null}
kubectl create secret generic mysql-crds \
  --from-literal=password=s3cR3t!
```

Inspect it as YAML:

```bash theme={null}
kubectl get secret mysql-crds -o yaml
```

```yaml theme={null}
apiVersion: v1
data:
  password: czNjUjN0IQ==
kind: Secret
metadata:
  name: mysql-crds
  namespace: default
type: Opaque
```

Decode it easily:

```bash theme={null}
echo czNjUjN0IQ== | base64 -d
# s3cR3t!
```

## Viewing Secrets Directly in etcd

With etcd client certificates, stored Secrets appear in plain text:

```bash theme={null}
ETCDCTL_API=3 etcdctl get /registry/secrets/default/mysql-crds \
  --cacert /etc/kubernetes/pki/etcd/ca.crt \
  --cert    /etc/kubernetes/pki/etcd/server.crt \
  --key     /etc/kubernetes/pki/etcd/server.key
```

```text theme={null}
/registry/secrets/default/mysql-crds
k8s.io/v1Secret: |
  {"password":"s3cR3t!"}
```

## Mitigation: Encryption at Rest

Kubernetes supports encrypting Secrets in etcd with an `EncryptionConfiguration`.

1. Create `/etc/kubernetes/pki/encryption-config.yaml`:

   ```yaml theme={null}
   apiVersion: apiserver.config.k8s.io/v1
   kind: EncryptionConfiguration
   resources:
     - resources:
         - secrets
       providers:
         - aescbc:
             keys:
               - name: key1
                 secret: RSYzZbCmZbshlScWcjm+zAbB83coDIJ47HTRLOOW4=
         - identity: {}
   ```

2. Update the API server flags:

   ```text theme={null}
   --encryption-provider-config=/etc/kubernetes/pki/encryption-config.yaml
   ```

3. Restart the kube-apiserver. All new Secrets will be encrypted in etcd.

<Callout icon="lightbulb" color="#1CB2FE">
  To encrypt existing Secrets, run:

  ```bash theme={null}
  kubectl get secrets --all-namespaces -o json \
    | kubectl replace -f -
  ```
</Callout>

After re-encryption, etcd shows only metadata:

```bash theme={null}
ETCDCTL_API=3 etcdctl get /registry/secrets/default/mysql-crds \
  --cacert /etc/kubernetes/pki/etcd/ca.crt \
  --cert    /etc/kubernetes/pki/etcd/server.crt \
  --key     /etc/kubernetes/pki/etcd/server.key
```

```text theme={null}
/registry/secrets/default/mysql-crds
k8s:enc:aescbc:v1:key1
```

## Best Practices for Kubernetes Secrets

| Best Practice                | Description                                                  |
| ---------------------------- | ------------------------------------------------------------ |
| Restrict etcd access         | Limit etcdctl and API access to cluster administrators only. |
| Enforce TLS                  | Enable TLS for all component communications.                 |
| Audit logging                | Turn on audit logs for `kubectl` and API server operations.  |
| Use an external secret store | Integrate HashiCorp Vault for dynamic, auditable secrets.    |

## Next Steps

In the next lesson, we’ll dive into the Vault Kubernetes Agent Injector—a mutating admission webhook that injects secrets via init and sidecar containers, removing static Kubernetes Secrets altogether.

***

## Links and References

* [Kubernetes Secrets][k8s-secrets]
* [Encrypting Data at Rest][etcd-encryption]
* [HashiCorp Vault][vault-docs]

[k8s-secrets]: https://kubernetes.io/docs/concepts/configuration/secret/

[etcd-encryption]: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/

[vault-docs]: https://www.vaultproject.io/docs/

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/devsecops-kubernetes-devops-security/module/baf5859d-32c2-4e7c-9808-f3486d6b9827/lesson/56de0285-8e7e-48b7-9429-58c23fa7bd5a" />
</CardGroup>
