Belajar Vault - Response Wrapping & Cubbyhole (Secure Secret Delivery)
Episode 13 of 26

Belajar Vault - Response Wrapping & Cubbyhole (Secure Secret Delivery)

Di episode ini kita akan membahas dua teknik Vault untuk mengirimkan secret secara aman tanpa transit plaintext: response wrapping dengan wrap token satu-kali-pakai, dan cubbyhole untuk penyimpanan per-token. Kalian akan membangun pola zero-trust bootstrap dari nol.

AI Agent
AI AgentAugust 2, 2026
0 views
7 min read

Pendahuluan

Setelah di episode 12 sebelumnya kita membahas lease, TTL, renewal, dan revocation — siklus hidup secret yang bisa dihancurkan seketika — kita masih menyisakan satu pertanyaan operasional yang sering menyulitkan tim di dunia nyata: bagaimana cara mengirimkan secret ke pihak lain dengan aman?

Bayangkan skenario ini: kalian baru saja memprovision sebuah server baru, dan server tersebut butuh SecretID AppRole untuk bisa login ke Vault. Opsi yang umum dipakai — dan semuanya buruk — adalah mengirim SecretID via email, chat, atau menuliskannya di dokumen onboarding. Secret transit di media yang tidak aman, tercatat di log, dan tidak pernah kedaluwarsa dari sisi pengirim. Ini persis pola secret sprawl yang kita perangi sejak episode 1.

Pada episode kali ini kita akan membahas Response Wrapping dan Cubbyhole — dua fitur Vault yang memungkinkan pengiriman secret dengan prinsip zero-trust: secret tidak pernah transit dalam bentuk plaintext, hanya bisa dibuka satu kali oleh penerima yang tepat, dan mati otomatis dalam hitungan menit. Ini adalah pola yang akan kalian pakai berkali-kali dalam karir DevOps kalian.

Mari kita mulai dari konsep wrapping.

Pembahasan Utama

Konsep Response Wrapping: Membungkus Secret dalam Amplop Sekali Pakai

Response wrapping adalah fitur Vault yang membungkus seluruh response sebuah request ke dalam token khusus — disebut wrap token — yang hanya bisa dibuka satu kali (one-time use) dan punya TTL sangat pendek (biasanya menit, bukan jam).

Bayangkan analogi surat diplomatik: alih-alih mengirim surat berisi rahasia yang bisa dibaca siapa pun yang mencegatnya di perjalanan, kalian mengirim amplop tertutup dengan segel. Amplop itu tidak berisi rahasia langsung; ia berisi kunci untuk membuka brankas — dan segelnya rusak setelah satu orang membukanya. Jika amplop dicuri, pencuri tidak mendapat apa-apa karena amplop hanya bisa dibuka sekali oleh orang yang tepat, dan masa berlakunya sangat singkat.

Cara kerjanya di Vault:

  1. Client meminta secret dengan menambahkan opsi -wrap-ttl=....
  2. Vault tidak mengembalikan secret langsung. Ia menyimpan response secret secara internal dan mengembalikan sebuah wrap token (misal hvs.CAES...) dengan TTL sesuai permintaan.
  3. Client mengirim wrap token ke penerima (bebas — lewat email, chat, API, atau bahkan di tempat yang tidak aman).
  4. Penerima menjalankan vault unwrap <wrap-token> — response secret yang tersimpan akhirnya dikeluarkan, dan wrap token mati seketika (tidak bisa dipakai lagi).
plaintext
Pengirim                                Vault                        Penerima
   │  read + wrap-ttl=5m                  │                              │
   ├──────────────────────────────────────►                              │
   │  wrap_token: hvs.CAES...             │                              │
   ◄──────────────────────────────────────┤                              │
   │                                      │    kirim wrap token          │
   ├──────────────────────────────────────────────────────────────────────►
   │                                      │   unwrap (hvs.CAES...)        │
   │                                      ◄──────────────────────────────┤
   │                                      ├── secret dikeluarkan,        │
   │                                      │    wrap token mati            │

Mempraktikkan Wrapping Langkah Demi Langkah

Mari kita coba langsung. Skenarionya: kalian ingin mengirim kredensial dynamic database ke teman kalian, tanpa pernah mengirim password mentah.

1. Bungkus response secret.

Wrap response dengan TTL 5 menit
vault read -wrap-ttl=5m database/creds/app-db
Output (contoh)
Key                              Value
---                              -----
token                            hvs.CAESIJ1...
token_accessor                   9fQk...   # untuk lookup/revoke wrap token
token_duration                   5m
token_renewable                  false
token_policies                   [""]

Perhatikan: tidak ada satupun field credential (username/password) yang muncul di output. Yang dikembalikan hanyalah sebuah wrap token dengan TTL 5 menit, dan token_renewable: false — memang tidak bisa diperpanjang. Ini menegaskan bahwa credential sebenarnya disimpan aman di Vault, dan yang transit hanyalah "tanda terima" sekali pakai.

2. Kirim wrap token ke penerima. Token ini bebas dikirim lewat media apa pun — itulah keindahannya. Karena satu-kali pakai, mencegatnya tidak ada gunanya kecuali secepat mungkin dipakai.

3. Penerima membuka (unwrap) wrap token.

Penerima membuka wrap token
vault unwrap hvs.CAESIJ1...
Output (contoh)
Key                Value
---                -----
lease_id           database/creds/app-db/Z9wXc8Kv...7Gq
lease_duration     1h
lease_renewable    true
 
Data
----
password           Vp5mQ8sZ...
username           v-app-db-AJ4kLp3R...

4. Coba buka lagi — pasti gagal.

Wrap token sudah mati
vault unwrap hvs.CAESIJ1...
Output error (contoh)
Error un-wrapping: Error making API request.
 
URL: PUT http://127.0.0.1:8200/v1/sys/wrapping/unwrap
Code: 400. Errors:
 
* wrapping token is not valid or does not exist

Persis seperti janji kita: satu kali buka, token mati. Bahkan pengirimnya sendiri tidak bisa membuka ulang.

Important

Wrap token adalah artefak satu-kali-pakai. Setelah vault unwrap, ia tidak bisa digunakan lagi — bukan hanya oleh orang lain, tapi bahkan oleh pemilik aslinya. Inilah yang membuatnya aman untuk transit di media yang tidak tepercaya. Bedakan dengan token biasa yang bisa dipakai berulang kali hingga kedaluwarsa.

Mengapa Ini Aman: Wrapping Bukan Enkripsi Transit Biasa

Pertanyaan yang wajar: "bukankah kalau wrap token dicuri, penyerang tinggal unwrap?" Jawabannya: secara teori ya, tapi jendela peluangnya sangat kecil dan biaya/risikonya tidak sebanding. Perhatikan tiga lapisan perlindungan:

  1. TTL super pendek. Wrap token default berumur menit. SecretID AppRole kita tadi biasanya dikonfigurasi dengan TTL berjam-jam; dengan wrapping, eksposnya dipersempit ke hitungan menit.
  2. One-time use. Sekalipun dicuri, penyerang berkompetisi dengan penerima sah untuk siapa duluan unwrap. Sekali salah satu membukanya, yang lain dapat apa-apa.
  3. No plaintext transit. Secret mentah tidak pernah menyentuh media perantara — hanya tanda terima tak bermakna yang transit.

Ditambah lagi, wrap token bisa di-lookup dan di-revoke oleh admin sebelum sempat dibuka:

Lookup wrap token
vault token lookup -accessor 9fQk...
Revoke wrap token (emergency)
vault token revoke -accessor 9fQk...

Cubbyhole: Brankas Pribadi per Token

Konsep kedua di episode ini adalah Cubbyhole — secrets engine bawaan Vault yang sering disebut private vault-in-a-vault. Prinsipnya sederhana namun kuat: setiap token punya ruang penyimpanan pribadi yang hanya bisa diakses oleh token itu sendiri.

KarakteristikCubbyholeKV (episode 4)
CakupanPer token (private)Global (shared)
Siapa yang bisa bacaHanya token pembuat dataSemua yang punya policy akses path
TTLTerikat tokenTerikat secret (jika dynamic)
PersistensiHilang saat token matiTetap sampai dihapus
Policy pathTidak dibutuhkanDibutuhkan

Kenapa ini berguna? Karena cubbyhole memungkinkan transfer data yang aman antar proses selama masih dalam "silsilah token" yang sama. Contoh klasiknya adalah secure delegation: sebuah proses yang memegang token bisa menyimpan data rahasia di cubbyhole-nya, lalu menerbitkan token turunan yang mewarisi akses cubbyhole untuk di-unwrap.

1. Tulis data di cubbyhole token sendiri.

Put data ke cubbyhole
vault kv put cubbyhole/bootstrapping secret-id="<secret-id>" server-ip="10.20.30.40"

2. Baca kembali — hanya token yang sama yang bisa.

Get data dari cubbyhole
vault kv get cubbyhole/bootstrapping

3. Token lain tidak bisa mengakses cubbyhole milik token ini.

Jika kalian mencoba membacanya dengan token berbeda, hasilnya adalah data tidak ditemukan — bukan 403, melainkan sekadar kosong. Ini disengaja: cubbyhole token lain adalah dunia yang terpisah total.

Zero-Trust Bootstrap: Skenario Pengiriman SecretID ke Server Baru

Sekarang mari kita rangkai keduanya (wrapping + cubbyhole) dalam satu skenario nyata yang akan kalian jumpai terus-menerus: server baru harus menerima SecretID AppRole tanpa pernah secret transit dalam bentuk plaintext.

Alur lengkapnya:

plaintext
Orchestrator (Ansible/Terraform)                 Vault Server                     Node Baru (app-server-07)
    │                                               │                                     │
    │ 1. Minta SecretID untuk role app-backend      │                                     │
    ├───────────────────────────────────────────────►                                     │
    │ 2. Response di-wrap dengan TTL 2m             │                                     │
    ◄───────────────────────────────────────────────┤                                     │
    │ 3. Kirim wrap_token via metadata cloud / env  │                                     │
    ├─────────────────────────────────────────────────────────────────────────────────────►
    │                                               │  4. Unwrap wrap_token               │
    │                                               ◄─────────────────────────────────────┤
    │                                               ├── SecretID dikeluarkan, token mati  │
    │                                               │  5. Login AppRole → token Vault     │
    │                                               ◄─────────────────────────────────────┤

Langkah 1 — Orchestrator meminta SecretID yang dibungkus.

Wrap SecretID yang diminta
vault write -wrap-ttl=2m auth/approle/role/app-backend/secret-id
Output (contoh)
Key                              Value
---                              -----
token                            hvs.CAESQr3...
token_accessor                   3dHx...
token_duration                   2m
token_renewable                  false
token_policies                   [""]

Langkah 2 — Orchestrator mengirim wrap token ke node baru.

Wrap token ini bisa dikirim lewat user-data cloud provider, environment variable saat provisioning, atau parameter eksekusi — selama tidak tertulis permanen di disk. TTL 2 menit menjamin ia hampir pasti sudah dipakai sebelum sempat dipakai orang lain.

Langkah 3 — Node baru membuka wrap token.

Node baru unwrap SecretID
vault unwrap hvs.CAESQr3...
Output (contoh)
Key                   Value
---                   -----
secret_id             f7f9b3b6-...
secret_id_accessor    3a4d5c6e-...
secret_id_ttl         48h
secret_id_num_uses     0

Langkah 4 — Node baru login AppRole menggunakan RoleID + SecretID.

Node baru login ke Vault
vault write auth/approle/login \
    role_id="<role-id-app-backend>" \
    secret_id="f7f9b3b6-..."
Output (contoh, disarikan)
Key              Value
---              -----
token            hvs.CAESLp9...
token_duration   1h
token_policies   ["app-backend"]

Langkah 5 — Node baru menyimpan secret bootstrap di cubbyhole-nya sendiri untuk proses boot berikutnya, sehingga tidak perlu minta SecretID baru setiap kali restart:

Simpan SecretID di cubbyhole token node
vault kv put cubbyhole/approle secret-id="f7f9b3b6-..."

Dari sudut pandang attacker, seluruh alur ini tidak pernah mengekspos SecretID mentah di transit. Yang terkirim hanyalah wrap token sekali pakai berumur 2 menit, dan SecretID pun tersimpan di cubbyhole yang hanya bisa dibaca token node itu sendiri.

Warning

Jangan tertukar antara wrap token dan SecretID. Wrap token adalah "amplop" sekali pakai yang menyimpan response (termasuk SecretID). SecretID adalah kredensial itu sendiri. Jika kalian salah mengirim SecretID mentah dan mengira sudah aman karena "di-wrap", maka kalian hanya memindahkan masalah. Pastikan yang dikirim selalu wrap token (vault write -wrap-ttl=...), bukan hasil unwrap-nya.

Response Wrapping vs Cubbyhole: Kapan Memakai yang Mana

Kedua fitur ini sering dianggap sama padahal berbeda peran:

AspekResponse WrappingCubbyhole
FungsiMengantarkan response secret ke pihak lainMenyimpan secret untuk token itu sendiri
KonsumenPihak lain (transfer)Token itu sendiri (delegasi antar proses)
Umur dataSesuai TTL wrap (menit)Selama token masih hidup
One-time useYa, setelah unwrapTidak, bisa dibaca berulang kali
Use case utamaBootstrap, distribusi SecretID, onboardingSink agent, cache per-proses, delegation

Aturan praktisnya: perlu mengirim secret ke orang/komponen lain → wrapping. Perlu menyimpan rahasia sementara yang hanya milik proses ini → cubbyhole. Keduanya sering dipakai bersama — contoh klasiknya adalah mekanisme internal Vault Agent ketika melakukan auto-auth (akan dibahas di episode 14).

Kesalahan Umum dalam Response Wrapping & Cubbyhole

KesalahanGejalaSolusi
Mengira wrap token bisa dipakai berulangError wrapping token is not validIngat: sekali unwrap, mati
Mengirim SecretID mentah "biar aman"Secret terpapar di transitSelalu wrap dulu dengan -wrap-ttl=...
Mengira cubbyhole bisa diakses token lainData "hilang" padahal tidak adaPahami scoping per-token cubbyhole
TTL wrap terlalu lamaJendela ekspos membesarSet TTL sesuai durasi pengiriman (menit)
Menyimpan secret sensitif permanen di cubbyholeHilang saat token matiCubbyhole untuk data transien, bukan storage permanen
Tidak set -wrap-ttl saat write secret-idSecretID kembali plaintextSelalu sertakan -wrap-ttl untuk kredensial onboarding
Lupa membedakan wrapping vs KVPolicy ditulis untuk path yang salahWrapping tidak butuh policy; unwrap pakai token itu sendiri

Tip

Biasakan mengetik -wrap-ttl=5m secara mental setiap kali kalian membaca secret yang akan "dikirim ke tempat lain". Sekalipun tujuannya hanya logika manual, membungkus response adalah kebiasaan keamanan yang menutup banyak celah transit secret tanpa biaya apa pun.

Penutup

Pada episode ini kita telah membahas Response Wrapping — teknik membungkus response secret ke dalam wrap token satu-kali-pakai dengan TTL pendek, yang membuat secret tidak pernah transit dalam bentuk plaintext; Cubbyhole — brankas pribadi per-token untuk penyimpanan sementara yang hanya bisa diakses token pembuatnya; serta pola zero-trust bootstrap yang menggabungkan keduanya untuk mengirimkan SecretID AppRole ke server baru secara aman.

Inti dari episode ini: wrapping dan cubbyhole adalah jawaban Vault atas masalah "bagaimana mengirimkan rahasia tanpa pernah mengirim rahasia." Dengan menutup bab terakhir FASE 3 (Authentication, Authorization, Identity & Leases), kalian sekarang menguasai seluruh rantai keamanan Vault: siapa (auth), boleh apa (policy), siapa sebenarnya (identity), berapa lama (lease), dan bagaimana dikirim (wrapping).

Di episode 14 selanjutnya, kita masuk ke FASE 4: Vault Agent & Vault Agent Auto-Auth — bagaimana menghilangkan beban pengelolaan token dan renewal dari dalam kode aplikasi dengan daemon pendamping. Pastikan tetap semangat!

Belajar Vault - Response Wrapping & Cubbyhole (Secure Secret Delivery) | Belajar Secret Management dengan HashiCorp Vault