Di episode ini kita akan membahas secrets engine pertama yang paling sering dipakai: KV Secrets Engine. Kita akan membandingkan KV v1 dan KV v2 dengan versioning, serta mempraktikkan operasi put, get, list, metadata, rollback, destroy, dan undelete.

Setelah di episode 3 sebelumnya kita membahas arsitektur utama Vault — mulai dari storage backend dan Vault Core Engine, proses initialization dengan Shamir's Secret Sharing, sampai risiko root token — pada episode kali ini kita akan masuk ke fase yang paling sering disentuh sehari-hari sebagai praktisi Vault: secrets engine. Dan titik mulainya adalah yang paling fundamental: KV Secrets Engine.
Kenapa topik ini penting di dunia nyata? Karena hampir semua implementasi Vault yang berjalan di produksi dimulai dari KV. Aplikasi butuh API key, database connection string, kredensial SMTP, atau token integrasi pihak ketiga — dan semua "rahasia statis" itu pertama-tama disimpan di KV sebelum dipakai oleh secrets engine lain yang lebih canggih. Memahami cara kerja mount path, perbedaan KV v1 dan KV v2, serta mekanisme versioning-nya akan menjadi fondasi yang membuat kalian tidak tersesat saat membaca dokumentasi Vault atau menulis policy (yang akan kita bahas di episode 9).
Kesalahan memahami perbedaan ini bukan sekadar error di terminal — bisa berakibat aplikasi gagal membaca secret, secret lama tak sengaja dipulihkan, atau data sensitif yang seharusnya sudah "hilang" ternyata masih bisa di-undelete. Mari kita bedah tuntas.
Sebelum membahas KV, penting memahami posisinya. Secrets engine adalah komponen Vault yang menyimpan, menghasilkan, atau mengenkripsi data rahasia. Ia dipasang (mount) pada sebuah path tertentu, dan setiap path itu menjadi titik akses API sekaligus batas isolasi.
Bayangkan Vault sebagai gedung bank. Setiap secrets engine adalah satu divisi di gedung tersebut dengan pintu masuknya sendiri-sendiri:
| Secrets Engine | Analogi | Path Default |
|---|---|---|
| KV | Brankas penyimpanan barang berharga | secret/ |
| Database | Mesin yang mencetak kartu ATM sementara | database/ |
| Transit | Ruang enkripsi data (tidak menyimpan data) | transit/ |
| PKI | Divisi penerbit sertifikat | pki/ |
Setiap mount punya path-nya sendiri sehingga satu secrets engine tidak bisa mengganggu yang lain. Inilah yang memungkinkan satu server Vault melayani banyak kebutuhan sekaligus.
Untuk memasang KV, gunakan perintah vault secrets enable. KV v2 adalah versi yang mendukung versioning, dan ini default yang disarankan sejak Vault 0.10:
vault secrets enable -path=secret kv-v2Output:
Success! Enabled the kv-v2 secrets engine at: secret/Tip
Secara default, path mount KV adalah secret/. Tapi kalian bebas memilih nama path lain dengan flag -path — misalnya -path=app-prod untuk memisahkan secret produksi dari development. Nama path inilah yang nanti menjadi bagian dari URL API, misalnya GET /v1/secret/data/my-app. Jadi pemilihan nama mount adalah keputusan desain, bukan sekadar formalitas.
Untuk memastikan engine sudah terpasang, lihat daftar seluruh secrets engine:
vault secrets listOutput (contoh):
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_xxa3... per-token private secret storage
identity/ identity identity_xxa3... identity store
secret/ kv kv_xxa3... n/a
sys/ system system_xxa3... system endpoints used for control, policy and debuggingPerhatikan dua hal: mount secret/ dengan tipe kv, dan mount bawaan cubbyhole/, identity/, serta sys/ yang tidak bisa di-disable. Mount cubbyhole adalah penyimpanan rahasia per-token yang akan kita bahas di episode 13.
Di sinilah banyak pemula tersesat. KV punya dua versi dengan perilaku yang berbeda secara fundamental:
| Aspek | KV v1 | KV v2 |
|---|---|---|
| Versioning | Tidak ada — tulis ulang = timpa permanen | Ya — setiap tulis membuat versi baru, riwayat tersimpan |
| Metadata | Tidak ada | Ada (created time, version, deletion time, dll) |
| Soft delete | Tidak ada | Ya (destroy menandai versi hancur, masih bisa di-undelete) |
| Undelete | Tidak ada | Ya (undelete memulihkan versi yang di-soft-delete) |
| Permanent destroy | Tidak ada | Ya (destroy dengan versi spesifik, atau metadata delete seluruh path) |
| Rollback ke versi lama | Tidak mungkin | Mungkin dengan kv rollback |
| Path API | secret/my-app | secret/data/my-app (prefix /data/) |
| Kapan dipakai | Legacy / migration | Semua penggunaan baru (disarankan) |
Intinya: KV v2 memperlakukan setiap nilai sebagai kumpulan versi yang bisa dipulihkan, sementara KV v1 memperlakukannya sebagai nilai tunggal yang bisa ditimpa. Di dunia nyata, ability to rollback sangat berharga — misalnya ketika sebuah konfigurasi yang salah menimpa secret produksi, kalian tidak perlu panik karena versi sebelumnya masih tersimpan.
Important
Perbedaan path inilah sumber kesalahan paling umum: di KV v2, secret disimpan di secret/data/<path> sedangkan operasi CRUD Vault CLI lewat perintah vault kv otomatis menambahkan prefix /data/ untuk kalian. Jika kalian memakai API raw (misalnya curl), jangan lupa menambahkan prefix /data/ saat menulis/membaca. Sebaliknya, jika kalian mencoba memakai vault write secret/foo langsung tanpa kv subcommand pada mount KV v2, Vault akan menolak dengan error path tidak ditemukan.
kv put, kv get, kv listMari kita mulai dengan menulis secret pertama:
vault kv put secret/my-app/db \
username="appuser" \
password="SuperSecret-2026!"Output:
== Secret Path ==
secret/data/my-app/db
======= Metadata =======
Key Value
--- -----
created_time 2026-08-02T08:15:00.123456Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1Perhatikan output-nya: Vault menampilkan version 1 dan created_time. Inilah penanda bahwa kalian berhadapan dengan KV v2 — setiap operasi tulis menghasilkan versi baru, bukan sekadar menimpa.
Untuk membaca kembali:
vault kv get secret/my-app/dbOutput:
== Secret Path ==
secret/data/my-app/db
======= Metadata =======
Key Value
--- -----
created_time 2026-08-02T08:15:00.123456Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
===== Data =====
Key Value
--- -----
password SuperSecret-2026!
username appuserUntuk membaca versi spesifik, gunakan flag -version:
vault kv get -version=1 secret/my-app/dbUntuk melihat seluruh path yang tersimpan di bawah mount:
vault kv list secret/my-appOutput:
Keys
----
dbTip
Biasakan menulis secret multi-key dalam satu pemanggilan kv put (seperti username + password di atas) daripada memecahnya menjadi banyak path. Selain hemat operasi API, ini membuat secret menjadi satu kesatuan logis yang mudah di-rollback dan di-audit.
kv metadataSalah satu keunggulan KV v2 adalah metadata. Untuk melihat riwayat seluruh versi sebuah secret:
vault kv metadata get secret/my-app/dbOutput:
========== Metadata Path ==========
secret/metadata/my-app/db
========= Metadata =========
Key Value
--- -----
created_time 2026-08-02T08:15:00.123456Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 2
====== Version Tree ======
Key Value
--- -----
1 2026-08-02T08:15:00.123456Z
2 2026-08-02T08:30:45.987654ZJika kita tulis ulang secret tersebut, version bertambah menjadi 3, dan data versi 1 masih tersimpan di balik layar. Inilah kekuatan riwayat: setiap perubahan tercatat, lengkap dengan timestamp.
Sekarang kita masuk ke bagian yang paling menarik — pengelolaan siklus hidup versi.
1. Soft delete dengan kv destroy
kv destroy menghancurkan versi tertentu secara "lembut" (soft delete). Versi tersebut tidak lagi bisa dibaca, tapi metadata-nya masih ada dan bisa dipulihkan:
vault kv destroy -versions=2 secret/my-app/dbOutput:
Success! Data written to: secret/destroy/my-app/dbCoba baca versi yang sudah di-destroy:
vault kv get -version=2 secret/my-app/dbOutput:
No value found at secret/data/my-app/db2. Memulihkan dengan kv undelete
Kesadaran bahwa versi 2 ternyata masih dibutuhkan? Pulihkan kapan saja selama belum di-destroy permanen:
vault kv undelete -versions=2 secret/my-app/dbSuccess! Data written to: secret/undelete/my-app/dbSetelah itu vault kv get -version=2 secret/my-app/db kembali menampilkan datanya.
3. Rollback ke versi lama
Bagaimana jika konfigurasi terbaru (versi 3) ternyata salah dan ingin kembali ke versi 1? Gunakan kv rollback — perintah ini membaca data versi lama dan menuliskannya sebagai versi baru (tanpa menghapus riwayat):
vault kv rollback -version=1 secret/my-app/dbOutput:
Success! Data written to: secret/data/my-app/dbWarning
kv rollback tidak menghapus versi yang salah — ia membuat versi baru yang berisi salinan data versi lama. Ini perilaku yang aman secara desain: jejak audit tetap lengkap. Jika kalian ingin menghapus seluruh riwayat sebuah path (misalnya karena secret sudah tidak terpakai dan berisi data yang sangat sensitif), gunakan vault kv metadata delete secret/my-app/db yang menghapus data dan seluruh versinya secara permanen.
Berikut jebakan yang paling sering ditemui saat bekerja dengan KV:
| Kesalahan | Gejala | Solusi |
|---|---|---|
Lupa prefix /data/ saat memakai raw API | Error 404 no handler exists for path "secret/my-app/db" | Tambahkan prefix: GET /v1/secret/data/my-app/db |
Memakai vault write secret/foo pada mount KV v2 | Error path tidak ditemukan | Gunakan vault kv put secret/foo yang menangani prefix /data/ |
Mengira kv destroy menghapus permanen | Versi "hilang" padahal masih bisa di-undelete | Sadari beda soft delete vs metadata delete |
| Tidak memikirkan nama mount sejak awal | Migrasi path saat produksi berjalan | Rencanakan -path yang jelas sejak episode setup |
| Membuat satu path per key | Banyak operasi API & sulit di-rollback | Gabungkan key yang logis dalam satu path |
Lupa menambah capabilities list di policy | kv list gagal meski read berhasil | Tambahkan capability list pada path yang sesuai (episode 9) |
Caution
KV v2 dengan versioning terdengar "aman", tapi ingat: versioning juga berarti riwayat rahasia (termasuk password lama) tetap tersimpan selama metadata path belum dihapus. Jika kalian mengelola data yang wajib dihancurkan (compliance seperti PCI-DSS atau kebijakan retensi data), pastikan ada prosedur vault kv metadata delete untuk menghapus riwayat, bukan hanya kv destroy per versi.
KV v1 memang tidak lagi direkomendasikan untuk penggunaan baru, tapi kalian akan tetap menjumpainya di banyak Vault yang sudah berjalan lama. Perilakunya sederhana: setiap vault kv put langsung menimpa nilai lama tanpa riwayat.
vault secrets enable -path=legacy kvvault kv put legacy/api-key value="old-secret-123"
vault kv get legacy/api-keyKapan KV v1 masih dipakai? Umumnya untuk kompatibilitas dengan tooling lama yang sudah terlanjur memanggil path tanpa /data/, atau sebagai langkah migrasi bertahap. Di luar itu, selalu pilih KV v2.
Pada episode 4 ini kita telah membedah secrets engine pertama dan paling fundamental: KV Secrets Engine. Kalian sudah belajar konsep mount path sebagai titik akses API, cara mengaktifkan KV v2 dengan vault secrets enable, perbandingan menyeluruh KV v1 vs KV v2, serta seluruh operasi inti — kv put, kv get, kv list, kv metadata, kv rollback, kv destroy, dan kv undelete. Jebakan utama yang perlu diingat: perbedaan path /data/ di KV v2 dan perilaku soft delete vs permanent delete.
Inti episode ini: KV v2 mengubah cara kalian berpikir tentang "menyimpan rahasia" — dari sekadar menimpa nilai menjadi mengelola riwayat yang bisa dipulihkan. Kemampuan inilah yang membuat KV aman dipakai di produksi: kesalahan konfigurasi tidak lagi menjadi bencana permanen.
Di episode 5 selanjutnya, kita akan melompat ke paradigma yang lebih canggih: Dynamic Database Secrets Engine — di mana kredensial database tidak lagi disimpan permanen, melainkan di-generate on-demand dengan TTL pendek dan otomatis hancur. Ini mengubah pola pikir "menyimpan rahasia" menjadi "meminjamkan rahasia". Pastikan tetap semangat!