Mengelola Identitas dan Rahasia Aplikasi di Kubernetes: Praktik Terbaik untuk Workload yang Aman
1. Pendahuluan
Kubernetes telah menjadi standar de facto untuk orkestrasi kontainer, memungkinkan developer untuk men-deploy, mengelola, dan menskalakan aplikasi dengan efisien. Namun, dengan segala kemudahan dan kekuatannya, Kubernetes juga membawa tantangan tersendiri, terutama dalam hal keamanan. Dua aspek krusial yang sering menjadi titik lemah adalah manajemen identitas dan pengelolaan rahasia (secrets) untuk aplikasi yang berjalan di dalamnya.
Bayangkan aplikasi Anda di Kubernetes perlu mengakses database, API eksternal, atau layanan cloud lainnya. Bagaimana aplikasi tersebut membuktikan bahwa ia “berhak” mengakses sumber daya tersebut? Dan bagaimana kita menyimpan credentials sensitif seperti API key atau password database dengan aman agar tidak terekspos di image kontainer atau konfigurasi yang tidak terlindungi?
Artikel ini akan membawa Anda menyelami praktik terbaik untuk mengelola identitas dan rahasia aplikasi Anda di Kubernetes. Kita akan membahas konsep dasar seperti Service Account, Workload Identity, hingga solusi modern seperti Secrets Store CSI Driver, memberikan Anda panduan praktis untuk membangun workload yang lebih aman dan tangguh.
2. Memahami Identitas di Kubernetes: Service Account
Di Kubernetes, setiap aplikasi atau workload yang berjalan memiliki identitasnya sendiri yang disebut Service Account. Secara default, setiap Pod akan secara otomatis diasosiasikan dengan Service Account bernama default di Namespace yang sama.
Service Account adalah identitas yang digunakan oleh proses-proses di dalam Pod untuk berinteraksi dengan Kubernetes API Server. Misalnya, jika aplikasi Anda perlu melakukan listing Pod lain atau membuat ConfigMap, ia akan menggunakan izin yang diberikan kepada Service Account-nya.
📌 Konsep Penting:
- Role-Based Access Control (RBAC): Izin untuk Service Account dikelola melalui RBAC. Anda akan membuat
RoleatauClusterRoleyang mendefinisikan izin (misalnya,get,list,watchPods) dan kemudian mengikatnya ke Service Account menggunakanRoleBindingatauClusterRoleBinding. - Token Service Account: Setiap Pod yang diasosiasikan dengan Service Account akan memiliki token Service Account yang di-mount secara otomatis ke
/var/run/secrets/kubernetes.io/serviceaccount/token. Token ini adalah JWT (JSON Web Token) yang digunakan untuk mengautentikasi ke Kubernetes API Server.
Contoh Penggunaan Service Account:
# 1. Buat Service Account kustom
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-service-account
namespace: default
---
# 2. Buat Role yang memberikan izin hanya untuk melihat Pods
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-viewer-role
namespace: default
rules:
- apiGroups: [""] # "" mengacu pada core API group
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
# 3. Ikat Role ke Service Account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: view-pods-rolebinding
namespace: default
subjects:
- kind: ServiceAccount
name: my-app-service-account
namespace: default
roleRef:
kind: Role
name: pod-viewer-role
apiGroup: rbac.authorization.k8s.io
---
# 4. Deploy Pod yang menggunakan Service Account ini
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
serviceAccountName: my-app-service-account # Asosiasikan dengan Service Account kustom
containers:
- name: my-app-container
image: busybox:latest
command: ["sh", "-c", "sleep 3600"]
Dengan konfigurasi di atas, kontainer my-app-container hanya akan memiliki izin untuk melihat Pods di Namespace default, bukan izin yang lebih luas dari Service Account default.
3. Meningkatkan Keamanan dengan Workload Identity
Service Account sangat baik untuk otorisasi di dalam Kubernetes. Namun, bagaimana jika aplikasi Anda perlu mengakses layanan di luar Kubernetes, seperti AWS S3, Google Cloud Storage, atau Azure Key Vault? Secara tradisional, Anda mungkin akan menyimpan API key atau credentials layanan cloud sebagai Kubernetes Secret, lalu me-mount-nya ke Pod.
❌ Kelemahan Pendekatan Tradisional:
- Risiko Kebocoran: Kubernetes Secret, meskipun dienkripsi saat at rest (jika etcd terenkripsi), secara default disimpan sebagai base64 dan dapat dengan mudah diakses oleh siapa saja dengan izin ke Namespace tersebut.
- Rotasi Kredensial: Mengelola rotasi API key atau password secara manual bisa menjadi mimpi buruk.
- Privilege Escalation: Jika Pod dikompromikan, credentials hardcoded bisa digunakan untuk mengakses sumber daya eksternal tanpa batas.
✅ Solusi: Workload Identity
Workload Identity adalah fitur yang memungkinkan Service Account Kubernetes untuk bertindak sebagai identitas terkelola di penyedia cloud Anda (misalnya, IAM Roles di AWS, Service Accounts di GCP, Managed Identities di Azure). Ini menghilangkan kebutuhan untuk menyimpan credentials cloud secara manual di dalam Kubernetes Secret.
Bagaimana cara kerjanya? Penyedia cloud akan mengizinkan Service Account Kubernetes untuk mengasumsikan peran atau identitas cloud tertentu. Ketika aplikasi Anda membuat panggilan ke API cloud, Kubernetes API Server akan mengeluarkan token JWT yang ditandatangani untuk Service Account aplikasi. Token ini kemudian ditukar dengan credentials sementara dari penyedia cloud, yang digunakan aplikasi untuk mengautentikasi ke layanan cloud.
💡 Manfaat Workload Identity:
- Tanpa Kredensial: Tidak ada API key atau secret layanan cloud yang perlu disimpan secara eksplisit di Kubernetes.
- Rotasi Otomatis: Credentials sementara yang diperoleh secara otomatis dirotasi oleh penyedia cloud.
- Granularitas Izin: Anda dapat memberikan izin yang sangat spesifik untuk setiap Service Account/aplikasi.
- Zero Trust: Mengurangi attack surface karena tidak ada long-lived credentials di dalam klaster.
Implementasi Workload Identity bervariasi tergantung penyedia cloud:
- AWS EKS: IAM Roles for Service Accounts (IRSA)
- Google Cloud GKE: Workload Identity
- Azure AKS: Azure AD Workload Identity
Meskipun detail implementasinya berbeda, prinsip intinya sama: Service Account Kubernetes Anda mendapatkan identitas cloud secara aman.
4. Mengelola Rahasia (Secrets) di Kubernetes
Selain identitas untuk mengakses layanan eksternal, aplikasi juga sering membutuhkan rahasia lain seperti password database, sertifikat TLS, atau konfigurasi API key internal.
4.1. Kubernetes Native Secrets: Kelebihan dan Kekurangan
Kubernetes memiliki objek Secret bawaan yang dirancang untuk menyimpan data sensitif.
Kelebihan:
- Mudah Digunakan: Terintegrasi langsung dengan Kubernetes.
- Mount Otomatis: Dapat di-mount sebagai file ke volume atau diinjeksikan sebagai environment variable ke kontainer.
- Isolasi Namespace: Secret terikat pada Namespace, membatasi akses.
Kekurangan:
- Disimpan sebagai Base64: Secara default, data Secret hanya di-encode dengan Base64, BUKAN dienkripsi. Siapa pun yang memiliki akses ke Kubernetes API dapat mendekode dan melihat isinya.
- Keamanan etcd: Keamanan Secret sangat bergantung pada keamanan dan konfigurasi enkripsi etcd (datastore Kubernetes). Jika etcd tidak dienkripsi at rest, Secret akan terekspos.
- Tidak Ada Auditing/Versioning: Sulit melacak siapa yang mengakses atau mengubah Secret.
- Rotasi Manual: Rotasi Secret masih harus dilakukan secara manual di Kubernetes.
Contoh Kubernetes Secret:
apiVersion: v1
kind: Secret
metadata:
name: my-database-secret
namespace: default
type: Opaque
data:
DB_USERNAME: YWRtaW4= # base64("admin")
DB_PASSWORD: c2VjcmV0cGFzc3dvcmQ= # base64("secretpassword")
Kemudian di Pod:
apiVersion: apps/v1
kind: Deployment
# ...
spec:
containers:
- name: my-app-container
image: my-app-image:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: my-database-secret
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-database-secret
key: DB_PASSWORD
⚠️ Peringatan: Jangan pernah menyimpan Kubernetes Secret dalam repositori Git publik! Gunakan solusi seperti Sealed Secrets untuk mengenkripsi Secret di Git.
4.2. Secrets Store CSI Driver: Solusi Modern untuk Rahasia Eksternal
Untuk mengatasi keterbatasan Kubernetes Native Secrets, solusi yang semakin populer adalah menggunakan Secrets Store CSI Driver. CSI (Container Storage Interface) Driver memungkinkan Kubernetes untuk berinteraksi dengan berbagai sistem penyimpanan eksternal. Dalam kasus ini, Secrets Store CSI Driver memungkinkan Anda untuk meng-mount rahasia dari eksternal secret manager (seperti HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) langsung ke Pod Anda sebagai volume file.
🎯 Bagaimana cara kerjanya?
- Anda menginstal Secrets Store