External Secret Manager #
Penyimpanan data rahasia (secrets) secara bawaan di Kubernetes memiliki keterbatasan operasional yang serius untuk kebutuhan infrastruktur skala enterprise. Di lingkungan kluster skala besar, kita dituntut untuk mengelola ratusan kredensial yang tersebar di puluhan namespace dan beberapa kluster berbeda. Jika kita hanya mengandalkan Kubernetes Secret native: kita akan kehilangan kemampuan pelacakan audit terpusat, tidak memiliki fitur rotasi kredensial otomatis, tidak ada riwayat versi (secret versioning), serta rentan terhadap kesalahan manusia jika data sensitif ter-commit ke dalam repositori GitOps.
Untuk mengatasi kesenjangan keamanan ini, industri modern mengadopsi pola integrasi dengan External Secret Manager—seperti AWS Secrets Manager, Google Cloud Secret Manager, Azure Key Vault, atau HashiCorp Vault. Sistem eksternal ini dirancang khusus dengan fitur kriptografi perangkat keras (HSM), audit log super ketat, rotasi kredensial otomatis, dan pemisahan wewenang (separation of duties). Artikel ini mengupas tuntas arsitektur pengelola rahasia eksternal, implementasi menggunakan External Secrets Operator (ESO), dan panduan memilih solusi yang tepat untuk kluster produksi kita.
Kebutuhan Integrasi Rahasia Eksternal #
Beralih dari Kubernetes Secret native ke solusi eksternal terkelola memberikan peningkatan keamanan yang signifikan bagi ekosistem produksi.
Mari kita perhatikan tabel perbandingan komparatif di bawah ini untuk melihat perbedaannya secara mendalam:
| Fitur | Kubernetes Secret Native | External Secret Manager |
|---|---|---|
| Penyimpanan Utama | etcd (Database kluster internal). | Database terdedikasi terenkripsi HSM. |
| Audit Logs | Terbatas (Hanya melacak request API Server). | Lengkap (Melacak siapa, kapan, dari mana secara detail). |
| Rotasi Kredensial | Manual (Membutuhkan deploy ulang). | Otomatis (Terintegrasi fungsi serverless/engine). |
| Manajemen Lintas Kluster | Terisolasi per kluster. | Terpusat (Satu sumber data untuk banyak kluster). |
| Versioning Rahasia | Tidak ada versioning native. | Mendukung pemulihan riwayat versi sebelumnya. |
| Dynamic Credentials | Static credentials saja. | Mendukung pembuatan kredensial sementara (on-demand). |
Arsitektur dan Cara Kerja External Secrets Operator (ESO) #
Untuk menghubungkan sumber data dari pengelola rahasia eksternal ke dalam Kubernetes, kita membutuhkan agen sinkronisasi aktif. Standar de facto industri saat ini adalah menggunakan External Secrets Operator (ESO). ESO adalah operator Kubernetes berbasis custom controller yang secara berkala memantau perubahan rahasia di cloud provider, lalu menulis ulang nilainya secara aman ke dalam objek Kubernetes Secret lokal.
Mari kita pelajari alur sinkronisasi data dinamis yang dilakukan oleh ESO di dalam kluster melalui diagram berikut:
flowchart TD
subgraph ExternalProvider["Cloud Secret Provider"]
AWS_SM["AWS Secrets Manager / GCP SM / Vault"]
end
subgraph K8sCluster["Kubernetes Cluster Boundary"]
ESO["External Secrets Operator Controller"]
SecretStore["SecretStore / ClusterSecretStore"]
ExtSecret["ExternalSecret Resource"]
K8sSecret["Kubernetes Secret (Target)"]
Pod["Pod Aplikasi Kontainer"]
SecretStore -.->|"Menyediakan Autentikasi IAM / JWT"| AWS_SM
ExtSecret -->|"Merujuk Rantai Autentikasi"| SecretStore
ESO -->|"Watch Perubahan"| ExtSecret
ESO -->|"1. Tarik Data Rahasia Baru"| AWS_SM
ESO -->|"2. Tulis & Sinkronkan Data"| K8sSecret
K8sSecret -->|"3. Dikonsumsi Runtime"| Pod
end
ESO menggunakan dua Custom Resource Definitions (CRD) utama:
- SecretStore / ClusterSecretStore: Mendefinisikan koneksi dan metode autentikasi ke cloud provider.
SecretStoreterikat pada namespace tertentu, sedangkanClusterSecretStorebersifat global dan dapat digunakan oleh semua namespace di kluster. - ExternalSecret: Mendefinisikan pemetaan kunci (key mapping) rahasia mana yang ingin ditarik dari cloud provider dan nama objek Kubernetes Secret target yang ingin dihasilkan.
Integrasi Mendalam dengan AWS Secrets Manager #
Bagi kluster yang berjalan di AWS (EKS), kita dapat memanfaatkan metode autentikasi IAM Roles for Service Accounts (IRSA) untuk menghubungkan ESO ke AWS Secrets Manager tanpa perlu menyimpan kredensial statis (AWS Access Key ID / Secret Access Key) di dalam kluster.
Perbandingan Autentikasi Sinkronisasi AWS #
Berikut adalah perbedaan antara mengonfigurasi koneksi menggunakan kunci statis yang berbahaya (anti-pattern) dengan autentikasi berbasis peran IAM Role dinamis (solusi):
# ANTI-PATTERN: Menggunakan AWS Access Keys statis di dalam manifest
# ✗ Sangat berbahaya karena kunci akses admin AWS terekspos di dalam kluster
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-store-unsafe
spec:
provider:
aws:
service: SecretsManager
region: ap-southeast-1
auth:
secretRef:
awsAccessKeyID:
name: static-aws-creds # Kunci statis yang berisiko bocor
key: access_key
awsSecretAccessKey:
name: static-aws-creds
key: secret_key
---
# BENAR: Terapkan autentikasi IRSA (IAM Roles for Service Accounts)
# ✓ Tanpa kunci statis, akses diotorisasi melalui federasi token OIDC dinamis
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: aws-secrets-manager-store
spec:
provider:
aws:
service: SecretsManager
region: ap-southeast-1
auth:
jwt:
# Menggunakan token dinamis ServiceAccount yang terikat Peran IAM AWS
serviceAccountRef:
name: external-secrets-operator-sa
namespace: external-secrets
Setelah ClusterSecretStore terbentuk, kita dapat membuat objek ExternalSecret untuk memetakan parameter database rahasia dari AWS Secrets Manager ke dalam namespace aplikasi:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: billing-db-secret
namespace: billing
spec:
refreshInterval: "1h" # Lakukan kueri sinkronisasi setiap 1 jam
secretStoreRef:
name: aws-secrets-manager-store
kind: ClusterSecretStore
target:
name: billing-postgres-creds # Nama Kubernetes Secret lokal yang akan dibuat
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: production/billing/db
property: db_username
- secretKey: password
remoteRef:
key: production/billing/db
property: db_password
Integrasi Mendalam dengan HashiCorp Vault #
HashiCorp Vault merupakan salah satu pengelola rahasia yang paling populer karena dukungannya yang matang terhadap arsitektur multi-cloud. Integrasi ESO dengan Vault biasanya menggunakan metode autentikasi Kubernetes Auth Method di mana Vault memverifikasi token JWT milik ServiceAccount Kubernetes.
Manifest Konfigurasi SecretStore untuk HashiCorp Vault #
Berikut adalah contoh manifest SecretStore yang dikonfigurasi untuk terhubung ke kluster Vault eksternal:
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend-store
namespace: production
spec:
provider:
vault:
server: "https://vault.internal.example.com:8200"
path: "secret" # Mount path KV secrets engine di Vault
version: "v2" # Menggunakan KV version 2 (dengan versioning)
auth:
kubernetes:
mountPath: "kubernetes" # Path auth method di Vault
role: "production-app-role" # Role yang dicocokkan di Vault
serviceAccountRef:
name: app-service-account # ServiceAccount lokal Pod
Fitur Unggulan: Dynamic Secrets Engine #
Salah satu keunggulan terbesar HashiCorp Vault dibandingkan cloud-native secret manager adalah kemampuannya untuk menghasilkan kredensial dinamis (Dynamic Secrets).
Ketika kontainer meminta akses database melalui Vault, Vault tidak mengembalikan kata sandi database admin yang statis. Vault akan secara otomatis membuat pengguna (user) database baru dengan kata sandi acak di server PostgreSQL target, memberikan hak akses minimal, dan menetapkan batas waktu aktif (TTL / Time to Live, misalnya 1 jam). Begitu TTL berakhir, Vault akan secara otomatis menghapus pengguna tersebut dari server database.
# Manifes ESO untuk mengambil Dynamic Credentials dari Vault
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: dynamic-db-creds
namespace: production
spec:
refreshInterval: "45m" # Tarik ulang kredensial baru sebelum TTL 1 jam berakhir
secretStoreRef:
name: vault-backend-store
kind: SecretStore
target:
name: dynamic-db-secret
data:
- secretKey: db-username
remoteRef:
key: database/creds/read-only-role # Path dynamic database engine
property: username
- secretKey: db-password
remoteRef:
key: database/creds/read-only-role
property: password
Pola ini sangat tangguh dalam menekan risiko peretasan, karena tidak ada kata sandi database permanen yang tersimpan di dalam berkas konfigurasi kluster kita.
Integrasi dengan Google Cloud (GCP) Secret Manager #
Di lingkungan Google Kubernetes Engine (GKE), kita mengintegrasikan sinkronisasi menggunakan metode Workload Identity. Workload Identity memetakan Kubernetes ServiceAccount secara langsung ke Google Service Account (GSA) tingkat GCP IAM.
1. ClusterSecretStore untuk GCP Secret Manager #
Berikut adalah manifes konfigurasi integrasi GCP Secret Manager menggunakan Workload Identity:
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: gcp-secret-store
spec:
provider:
gcpsm:
projectID: "my-gcp-production-project"
auth:
workloadIdentity:
clusterLocation: asia-southeast1
clusterName: gke-prod-cluster
serviceAccountRef:
name: eso-gcp-sync-sa
namespace: external-secrets
2. ExternalSecret untuk GCP Secret Manager #
Setelah ClusterSecretStore aktif, kita dapat menarik data rahasia dari GCP Secret Manager menggunakan manifes berikut:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: gcp-db-secret
namespace: production
spec:
refreshInterval: "1h"
secretStoreRef:
name: gcp-secret-store
kind: ClusterSecretStore
target:
name: gcp-db-secret # Nama Kubernetes Secret lokal yang dihasilkan
data:
- secretKey: db-password
remoteRef:
key: production-db-password # Nama rahasia di GCP Secret Manager
version: "latest" # Versi rahasia (bisa ditentukan spesifik angka versi)
Integrasi dengan Azure Key Vault #
Bagi organisasi yang mengoperasikan infrastruktur di Microsoft Azure (AKS), kita dapat menyinkronkan data sensitif dari Azure Key Vault menggunakan metode autentikasi Azure AD Workload Identity.
1. SecretStore untuk Azure Key Vault #
Berikut adalah manifes SecretStore yang dikonfigurasi untuk menghubungkan namespace kita ke layanan Azure Key Vault:
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: azure-key-vault-store
namespace: production
spec:
provider:
azurekv:
tenantId: "12345678-abcd-1234-abcd-1234567890ab" # Tenant ID Azure Directory Anda
vaultUrl: "https://my-prod-key-vault.vault.azure.net" # URL Azure Key Vault Anda
auth:
workloadIdentity:
serviceAccountRef:
name: eso-azure-sync-sa # ServiceAccount lokal yang terikat dengan Azure Managed Identity
2. ExternalSecret untuk Azure Key Vault #
Gunakan manifes berikut untuk menarik rahasia (secrets) atau kunci (keys) dari Azure Key Vault dan mengubahnya menjadi Kubernetes Secret:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: azure-app-secret
namespace: production
spec:
refreshInterval: "1h"
secretStoreRef:
name: azure-key-vault-store
kind: SecretStore
target:
name: local-azure-secret
data:
- secretKey: api-token
remoteRef:
key: production-api-token # Nama rahasia di Azure Key Vault
Panduan Pemilihan Solusi Terbaik Berdasarkan Kebutuhan #
Setiap pengelola rahasia eksternal memiliki karakteristik performa, integrasi, dan biaya yang berbeda. Memilih solusi yang tidak sesuai dengan kebutuhan infrastruktur dapat meningkatkan kompleksitas operasional secara tidak perlu.
Mari kita pelajari pohon keputusan (decision tree) di bawah ini untuk menentukan pilihan solusi terbaik:
flowchart TD
Start{"Mulai Evaluasi Pilihan"} --> IsMultiCloud{"Apakah Menggunakan Multi-Cloud / On-Premise?"}
IsMultiCloud -- "Ya" --> UseVault["Pilihan Utama: HashiCorp Vault"]
IsMultiCloud -- "Tidak" --> CloudProvider{"Di Mana Cluster Kubernetes Berjalan?"}
CloudProvider -- "AWS (EKS)" --> UseAWS["Pilihan: AWS Secrets Manager"]
CloudProvider -- "GCP (GKE)" --> UseGCP["Pilihan: GCP Secret Manager"]
CloudProvider -- "Azure (AKS)" --> UseAzure["Pilihan: Azure Key Vault"]
UseVault --> FeaturesVault["Kelebihan: Dynamic Secrets, PKI engine, Multi-Cloud"]
UseAWS --> FeaturesAWS["Kelebihan: Auto-rotation RDS, KMS native integration"]
UseGCP --> FeaturesGCP["Kelebihan: Workload Identity integration, hemat biaya"]
Berikut adalah ringkasan perbandingan karakteristik teknis untuk membantu proses pengambilan keputusan tim platform engineer:
- HashiCorp Vault:
- Kelebihan: Sangat portabel, mendukung dynamic secrets, manajemen PKI otomatis, kontrol RBAC sangat kaya.
- Kekurangan: Membutuhkan biaya operasional tinggi untuk instalasi, pemeliharaan backup cluster, dan operasional tim security policy.
- AWS Secrets Manager:
- Kelebihan: Terkelola penuh (fully managed), integrasi bawaan dengan sistem rotasi otomatis database RDS, otorisasi native KMS.
- Kekurangan: Vendor lock-in AWS, biaya per kueri API (API calls cost) cukup mahal jika
refreshIntervalESO disetel terlalu agresif.
- GCP Secret Manager:
- Kelebihan: Sangat sederhana, autentikasi tanpa password menggunakan Workload Identity, integrasi audit logging Cloud Logging.
- Kekurangan: Fitur rotasi otomatis tidak sekaya AWS, vendor lock-in GCP.
Ringkasan #
- Gunakan ESO sebagai standar sinkronisasi: Terapkan External Secrets Operator untuk menyinkronkan data sensitif dari luar ke dalam objek Secret kluster secara transparan dan konsisten.
- Wajib gunakan autentikasi IRSA/Workload Identity: Hindari penulisan access keys statis di manifest YAML; gunakan token JWT dinamis yang diotorisasi oleh OIDC cloud provider.
- Manfaatkan dynamic secrets untuk proteksi database: Gunakan fitur Dynamic Secrets Engine milik Vault untuk meminimalkan risiko pencurian kredensial database permanen.
- Pilih solusi berdasarkan lingkungan kluster: Gunakan AWS Secrets Manager jika berjalan penuh di EKS, GCP Secret Manager di GKE, dan gunakan HashiCorp Vault untuk kebutuhan multi-cloud.
- Atur parameter refreshInterval secara bijaksana: Jangan setel waktu sinkronisasi terlalu sering (misalnya setiap 5 detik) pada cloud-managed secrets manager untuk menghindari tagihan API calls cloud yang membengkak.
- Pelihara prinsip separation of duties: Tim developer hanya boleh membuat manifes
ExternalSecret, sedangkan konfigurasi koneksiClusterSecretStoredikelola khusus oleh tim platform security.
Navigasi #
← Sebelumnya: Secret Management Best Practice Berikutnya: ConfigMap vs Secret →