Sebelum HashiCorp Vault, manajemen secrets kami di Commsult Indonesia sangat memalukan: password database dalam file .env yang di-commit ke repo Git privat, API key yang disalin secara manual antar developer, dan sertifikat SSL yang tersimpan dalam folder Google Drive bersama. Ini lebih umum dari yang diakui kebanyakan tim. Vault mengubah model secara fundamental — tidak ada secrets yang diam di file atau Git, credential dinamis berumur pendek yang kedaluwarsa secara otomatis, dan log audit lengkap dari setiap akses secrets. Biaya setup adalah beberapa jam; peningkatan operasional bersifat permanen. Panduan ini mencakup pola deployment dan konfigurasi yang saya gunakan.
Secrets statis — password database, API key, sertifikat — memiliki siklus hidup yang berbahaya: dibuat sekali, dibagikan melalui Slack atau email, disimpan dalam file .env, dan sering tidak pernah dirotasi karena 'akan kita lakukan nanti.' Setiap developer yang pernah memiliki akses tetap mengetahui secrets tersebut bahkan setelah meninggalkan tim. Jika file .env bocor (melalui commit tidak disengaja, mesin developer yang dikompromikan, atau miskonfigurasi cloud storage), blast radius-nya adalah seluruh sistem yang secrets tersebut memberikan akses. Vault memperkenalkan dynamic secrets: Vault menghasilkan credential database unik untuk setiap instance aplikasi, dengan TTL (time-to-live) yang dapat dikonfigurasi setelah itu credential kedaluwarsa dan Vault secara otomatis mencabutnya.
Vault memiliki dua mode operasional. Dev mode (vault server -dev) berjalan sepenuhnya di memori dengan root token yang dikonfigurasi sebelumnya — berguna untuk pengembangan dan pengujian lokal tetapi tidak menyimpan apa pun secara persisten dan tidak memiliki keamanan. Mode produksi memerlukan: backend penyimpanan yang tahan lama (Consul, integrated Raft, atau backend penyimpanan cloud seperti GCS), sertifikat TLS untuk semua komunikasi, inisialisasi dengan Shamir secret share (5 share kunci, 3 diperlukan untuk unseal adalah baseline umum), dan mekanisme unseal. Proses inisialisasi terjadi sekali — Vault menghasilkan root token dan Shamir key share, dan Anda mendistribusikan key share ke orang yang berbeda (misalnya, 5 engineer senior masing-masing memegang satu share).
Beban operasional dari manual Vault unsealing (mengharuskan 3 pemegang kunci untuk bekerja sama setiap kali proses Vault restart) sering dikutip sebagai alasan tim tidak mengadopsi Vault. Auto-unseal dengan cloud KMS (Key Management Service) menyelesaikan ini. Konfigurasikan stanza seal dalam file konfigurasi Vault untuk menggunakan GCP KMS: Vault mengenkripsi master key-nya dengan kunci KMS. Saat startup, Vault secara otomatis mendekripsi master key-nya melalui API KMS tanpa intervensi manusia. Kunci GCP KMS dilindungi oleh manajemen kunci berbasis HSM GCP. Auto-unseal memungkinkan Vault restart secara otomatis (setelah patching VM, crash) tanpa memerlukan beberapa manusia on-call untuk memasukkan kembali key share.
Dari pengalaman saya: mulai Vault dengan backend penyimpanan Raft terintegrasi daripada Consul untuk deployment yang lebih kecil (di bawah 5 node). Raft sudah terintegrasi dalam Vault sejak versi 1.4 dan menyediakan clustering high-availability tanpa menjalankan cluster Consul terpisah. Cluster Vault 3-node menggunakan Raft memberikan HA dengan kompleksitas operasional yang lebih rendah. Deploy setiap node Vault di availability zone berbeda untuk ketahanan. Backend penyimpanan Raft mereplikasi semua data di seluruh node — satu node adalah leader, yang lain adalah follower. Jika leader gagal, Raft secara otomatis memilih leader baru.
Secrets engine database Vault menghasilkan dynamic credential untuk PostgreSQL, MySQL, MongoDB, dan database lainnya. Konfigurasikan dengan role Vault yang mendefinisikan TTL dan pernyataan SQL untuk CREATE dan REVOKE user. Ketika aplikasi membutuhkan akses database, ia meminta credential dari Vault melalui API. Vault membuat user database unik (vault-my-app-20240515-abc123) dengan izin yang sesuai, mengembalikan username dan password ke aplikasi, dan menandai credential untuk kedaluwarsa pada TTL. Ketika TTL kedaluwarsa atau aplikasi memanggil Vault untuk secara eksplisit mencabut credential, Vault menghapus user database. Tidak ada password bersama yang berumur panjang.
# Configure Vault database secrets engine for PostgreSQL
vault secrets enable database
vault write database/config/mydb plugin_name=postgresql-database-plugin allowed_roles="my-app-role" connection_url="postgresql://{{username}}:{{password}}@db.internal:5432/mydb?sslmode=require" username="vault_admin" password="initial_password"
# Create a role that generates short-lived credentials
vault write database/roles/my-app-role db_name=mydb creation_statements="CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA public TO "{{name}}";" default_ttl="1h" max_ttl="24h"
# Application requests dynamic credentials
vault read database/creds/my-app-role
# Key Value
# --- -----
# username vault-my-app-20260515-abc123xyz
# password A1B2-C3D4-E5F6-G7H8
# lease_duration 1h
# Auto-unseal configuration (config.hcl)
# seal "gcpckms" {
# project = "my-gcp-project"
# region = "asia-southeast1"
# key_ring = "vault-keyring"
# crypto_key = "vault-unseal-key"
# }Aplikasi mengautentikasi ke Vault menggunakan auth method. AppRole dirancang untuk autentikasi machine-to-machine: role ID (publik, seperti username) dan secret ID (privat, seperti password, valid untuk waktu singkat atau penggunaan tunggal). Pipeline CI/CD mengambil secret ID dari Vault saat runtime menggunakan credential bootstrap, menggabungkannya dengan role ID, dan mengautentikasi ke Vault untuk menerima token berumur pendek dengan izin kebijakan tertentu. Untuk Kubernetes, auth method Kubernetes lebih sederhana: token akun layanan pod digunakan untuk mengautentikasi ke Vault secara langsung, tanpa mengelola role ID atau secret ID.
┌──────────────────────────────────────────────────────┐
│ HashiCorp Vault Architecture │
├──────────────────────────────────────────────────────┤
│ │
│ ┌────────────┐ ┌────────────┐ ┌──────────┐ │
│ │ Vault │ │ Vault │ │ Vault │ │
│ │ Node 1 │◄───►│ Node 2 │◄───►│ Node 3 │ │
│ │ (Leader) │ │ (Follower)│ │ (Follower│ │
│ └─────┬──────┘ └────────────┘ └──────────┘ │
│ │ Raft consensus (integrated storage) │
│ ↓ │
│ ┌─────────────────────────────────┐ │
│ │ GCP KMS (Auto-Unseal) │ │
│ │ HSM-backed encryption key │ │
│ └─────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘Vault menghasilkan root token selama inisialisasi yang memiliki akses tidak terbatas ke semua yang ada di Vault. Saya pernah melihat tim menggunakan root token ini dalam file konfigurasi aplikasi karena itu adalah credential pertama yang mereka miliki setelah inisialisasi. Root token harus digunakan tepat sekali — untuk menyiapkan kebijakan awal, auth method, dan secrets engine — lalu dicabut. Simpan root token dalam brankas fisik atau HSM, bukan dalam file atau secrets manager. Root token adalah kunci master untuk seluruh infrastruktur secrets Anda; memperlakukannya seperti API key biasa adalah kegagalan keamanan yang serius.
Aktifkan log audit Vault ke file dan opsional ke target syslog. Log audit mencatat setiap permintaan ke Vault — siapa yang mengautentikasi, secrets apa yang mereka akses atau tulis, apa responsnya (di-hash), dan kapan. Ini menciptakan trail lengkap untuk kepatuhan (PCI-DSS, SOC 2, ISO 27001 semuanya memerlukan trail audit untuk akses secrets). Tulis kebijakan Vault (dalam HCL) yang mengikuti prinsip hak istimewa minimum: aplikasi harus memiliki akses baca hanya ke jalur secrets spesifik yang dibutuhkan, tidak pernah akses tulis ke secrets yang tidak dibuat, dan tidak pernah akses hapus sama sekali. Kebijakan adalah kontrol keamanan utama di Vault — kebijakan yang salah dikonfigurasi adalah cara utama deployment Vault dikompromikan.
Untuk workload Kubernetes, Vault Agent Injector adalah pola integrasi standar. Ini adalah Kubernetes mutating webhook yang secara otomatis menyuntikkan sidecar Vault Agent ke pod yang dianotasi. Sidecar mengautentikasi ke Vault menggunakan akun layanan Kubernetes pod, mengambil secrets yang ditentukan, dan menulisnya ke volume memori bersama yang dibaca container aplikasi Anda. Ketika secrets dirotasi, sidecar mengambil kembali nilai baru dan opsional memberi sinyal pada aplikasi Anda untuk reload. Tidak ada integrasi SDK Vault dalam kode aplikasi Anda — secrets muncul sebagai file dalam filesystem container.
GCP Secret Manager dan AWS Secrets Manager adalah alternatif managed yang sangat baik untuk Vault self-hosted. Mereka menyelesaikan masalah inti (tidak ada secrets plaintext dalam kode) dengan overhead operasional nol. Saya menggunakan GCP Secret Manager untuk proyek klien yang lebih sederhana di mana Vault self-hosted akan terlalu berlebihan. Saya menggunakan Vault untuk proyek di mana: (1) kami membutuhkan dynamic database credential (Secret Manager tidak menghasilkan ini); (2) kami membutuhkan manajemen secrets di berbagai cloud provider (Vault bersifat agnostik provider); (3) persyaratan kepatuhan mengharuskan penyimpanan secrets on-premises; atau (4) kami membutuhkan model kebijakan yang kaya dan kemampuan audit yang disediakan Vault. Untuk UKM Indonesia dengan tim DevOps kecil, mulailah dengan opsi cloud-native dan beralih ke Vault ketika Anda membutuhkan fitur spesifiknya.
Sumber & Bacaan Lanjutan