Secret #
Secret adalah resource Kubernetes untuk menyimpan data sensitif — password, token, certificate, SSH key. Secara struktural mirip dengan ConfigMap, tapi Secret dirancang khusus untuk data yang tidak boleh muncul di log, tidak boleh ter-ekspos sembarangan, dan idealnya dienkripsi saat disimpan. Memahami cara kerja Secret dan batasannya penting untuk menghindari false sense of security.
Perbedaan Secret dan ConfigMap #
ConfigMap:
→ Data konfigurasi non-sensitif
→ Disimpan sebagai plaintext di Etcd
→ Tampil sebagai plaintext di kubectl get/describe
→ Cocok untuk: URL, hostname, feature flags, app settings
Secret:
→ Data sensitif
→ Disimpan sebagai base64 di Etcd (bukan terenkripsi secara default!)
→ Tidak tampil di kubectl describe (hanya tampil ukuran)
→ Cocok untuk: password, API key, token, TLS certificate, SSH key
Base64 bukan enkripsi. Data dalam Secret hanya di-encode base64, bukan dienkripsi. Siapapun yang bisa akses Etcd atau punya permission kubectl get secret bisa membaca nilai Secret. Untuk keamanan yang sesungguhnya, aktifkan enkripsi at-rest dan batasi akses via RBAC.Tipe Secret #
Kubernetes mendefinisikan beberapa tipe Secret dengan validasi masing-masing:
# Opaque (default) — key-value bebas, paling umum
type: Opaque
# TLS certificate dan private key
type: kubernetes.io/tls
# Docker registry credentials
type: kubernetes.io/dockerconfigjson
# Service account token
type: kubernetes.io/service-account-token
# Basic authentication
type: kubernetes.io/basic-auth
# SSH authentication
type: kubernetes.io/ssh-auth
Membuat Secret #
# Dari literal (nilai otomatis di-encode base64)
kubectl create secret generic db-credentials \
--from-literal=username=appuser \
--from-literal=password=S3cur3P@ssw0rd
# Dari file (berguna untuk certificate)
kubectl create secret tls tls-cert \
--cert=server.crt \
--key=server.key
# Dari file credentials Docker registry
kubectl create secret docker-registry registry-cred \
--docker-server=registry.example.com \
--docker-username=myuser \
--docker-password=mypassword
# Dari manifest (nilai harus di-encode base64 manual)
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: production
type: Opaque
data:
username: YXBwdXNlcg== # base64("appuser")
password: UzNjdXIzUEBzc3cwcmQ= # base64("S3cur3P@ssw0rd")
# Encode nilai ke base64
echo -n "appuser" | base64
# -n penting untuk menghindari newline yang ikut ter-encode
Menggunakan Secret sebagai Environment Variable #
spec:
containers:
- name: api
image: my-api:v2
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
# Atau inject semua key sekaligus
envFrom:
- secretRef:
name: db-credentials
Menggunakan Secret sebagai Volume #
spec:
volumes:
- name: tls-certs
secret:
secretName: tls-cert
defaultMode: 0400 # read-only untuk owner, tidak untuk group/others
containers:
- name: nginx
image: nginx:1.25
volumeMounts:
- name: tls-certs
mountPath: /etc/ssl/certs
readOnly: true
File Secret di dalam container disimpan di tmpfs (memory filesystem), bukan di disk node — lebih aman karena tidak ada jejak di disk.
Secret untuk Image Pull #
Untuk pull image dari private registry:
spec:
imagePullSecrets:
- name: registry-cred # nama Secret tipe docker-registry
containers:
- name: app
image: registry.example.com/myapp:v2
Enkripsi at-Rest #
Secara default, Secret di Etcd hanya di-encode base64, bukan dienkripsi. Untuk mengaktifkan enkripsi sesungguhnya:
# EncryptionConfiguration — konfigurasi di API Server
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc: # enkripsi AES-CBC
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {} # fallback untuk baca secret lama yang belum terenkripsi
Di cloud managed Kubernetes, enkripsi at-rest biasanya tersedia sebagai fitur yang bisa diaktifkan:
# GKE: aktifkan Application-layer Secret encryption
gcloud container clusters update CLUSTER_NAME \
--database-encryption-key projects/PROJECT/locations/REGION/keyRings/RING/cryptoKeys/KEY
# EKS: aktifkan envelope encryption
aws eks update-cluster-config \
--name CLUSTER_NAME \
--encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:......"}}]'
Risiko Keamanan yang Sering Diabaikan #
1. Secret di environment variable bisa bocor via:
→ Crash dump / core dump yang menyertakan env var
→ Debug endpoint yang expose process environment
→ Log aplikasi yang secara tidak sengaja print env var
→ `kubectl exec` ke Pod dan jalankan `env`
2. Secret di volume lebih aman, tapi:
→ Aplikasi yang meng-cache nilai masih expose di memory
→ Log yang print nilai file konfigurasi tetap berbahaya
3. Secret dalam source code atau Git:
→ JANGAN pernah commit Secret ke Git, meskipun di-encode base64
→ Gunakan .gitignore untuk file yang berisi Secret
→ Tools seperti git-secrets atau truffleHog untuk scan
4. RBAC yang longgar:
→ Siapapun dengan permission get/list secrets bisa baca semua Secret
→ Batasi permission Secret via RBAC yang ketat
Praktik Terbaik #
Untuk Secret management di produksi:
1. Aktifkan enkripsi at-rest (via KMS atau EncryptionConfiguration)
2. Batasi akses via RBAC:
→ Principle of least privilege
→ Service account Pod hanya bisa akses Secret yang benar-benar dibutuhkan
→ Audit siapa yang bisa kubectl get secrets
3. Rotasi Secret secara berkala:
→ Terutama untuk database password dan API key
→ Otomatisasi dengan external secret manager
4. Gunakan external secret manager untuk produksi kritikal:
→ AWS Secrets Manager + External Secrets Operator
→ HashiCorp Vault + Vault Agent Injector
→ GCP Secret Manager + External Secrets Operator
→ Secret value dikelola di luar cluster, disync ke Kubernetes Secret
5. Jangan log nilai Secret:
→ Pastikan konfigurasi logging aplikasi tidak print env var atau config file
→ Redact sensitive fields di log aggregation pipeline
Ringkasan #
- Base64 bukan enkripsi — Secret hanya di-encode, bukan dilindungi; untuk keamanan nyata aktifkan enkripsi at-rest dan batasi akses via RBAC.
- Volume mount lebih aman dari env var — file Secret disimpan di tmpfs (memory), tidak ada jejak di disk; env var bisa bocor via log atau debug endpoint.
- Tipe Secret untuk validasi yang tepat — gunakan
kubernetes.io/tlsuntuk certificate,kubernetes.io/dockerconfigjsonuntuk registry; Kubernetes validasi format sesuai tipe.- Enkripsi at-rest wajib untuk produksi kritikal — aktifkan via KMS di cloud managed cluster; untuk on-premise, konfigurasi EncryptionConfiguration di API Server.
- External secret manager untuk produksi skala besar — AWS Secrets Manager, HashiCorp Vault, atau GCP Secret Manager dikelola lebih professional untuk rotasi, audit, dan akses control.
- Jangan commit Secret ke Git meski dalam base64 — base64 mudah di-decode; gunakan git-secrets atau truffleHog untuk scan repository dari kebocoran Secret.
← Sebelumnya: ConfigMap Berikutnya: Environment Variable Pattern →