# ETCD Encryption Configuration for Kubernetes To enable static encryption at rest for Kubernetes secrets in ETCD, you need to configure the API Server with an EncryptionConfiguration. ## 1. Generate an Encryption Key ```bash # Generate a 32-byte base64-encoded key head -c 32 /dev/urandom | base64 # Example output: sxFdbKYquCe3EbRWVV+pFe2lS8K8hbiv3V8ExQZ0fD4= ``` ## 2. Create EncryptionConfiguration File Create `/etc/kubernetes/encryption-config.yaml` on the control plane node: ```yaml apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: sxFdbKYquCe3EbRWVV+pFe2lS8K8hbiv3V8ExQZ0fD4= - identity: {} ``` ## 3. Update kube-apiserver Static Pod Manifest Edit `/etc/kubernetes/manifests/kube-apiserver.yaml` on the control plane node: ```yaml spec: containers: - name: kube-apiserver command: - kube-apiserver # ... existing flags ... - --encryption-provider-config=/etc/kubernetes/encryption-config.yaml volumeMounts: - name: encryption-config mountPath: /etc/kubernetes readOnly: true volumes: - name: encryption-config hostPath: path: /etc/kubernetes type: DirectoryOrCreate ``` ## 4. Verify Encryption is Working ```bash # After restarting the API server, create a secret and verify it's encrypted kubectl create secret generic test-secret --from-literal=key=value -n juwan # Check if the secret is encrypted in etcd kubectl get secret test-secret -o yaml # You can also check raw etcd data (requires etcd access): # etcdctl --endpoints=https://127.0.0.1:2379 get /kubernetes.io/secrets/juwan/test-secret # The data should be encrypted (not human-readable) ``` ## 5. Important Notes - **Backup your encryption key** in a secure location - **Never commit encryption keys** to version control - If you lose the key, all encrypted secrets will be unrecoverable - After enabling encryption, existing unencrypted secrets will not be automatically encrypted - To encrypt existing secrets, you can use: `kubectl delete secret && kubectl create secret ...` - Or use: `kubectl patch secret -p '{}' --type=merge` (triggers re-encryption) ## 6. RBAC Configuration for JWT Secret The `jwt-secret.yaml` includes RBAC rules that: - Create a `jwt-secret` Secret in the `juwan` namespace - Create ServiceAccounts for `user-rpc` and `envoy-gateway` - Create a Role `jwt-secret-reader` that allows reading only the `jwt-secret` Secret - Bind this Role to both ServiceAccounts via RoleBindings This ensures: - Only `user-rpc` and `envoy-gateway` Pods can read the JWT secret - Other services and users cannot access the JWT secret - Least privilege access principle is enforced ## 7. Update Deployment to Use ServiceAccount Make sure your Deployment references the ServiceAccount: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: user-rpc namespace: juwan spec: template: spec: serviceAccountName: user-rpc # This is important! containers: - name: user-rpc env: - name: JWT_SECRET_KEY valueFrom: secretKeyRef: name: jwt-secret key: secret-key ``` ## 8. For Minikube Users If using Minikube, you can enable encryption with: ```bash minikube config set apiserver.encryption-provider-config /path/to/encryption-config.yaml minikube start ``` Or manually edit the kube-apiserver manifest after starting Minikube: ```bash minikube ssh sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml # Add the flags and volume mounts as shown above ```