Belajar Vault - Transit Secrets Engine (Encryption-as-a-Service / EaaS)
Episode 6 of 26

Belajar Vault - Transit Secrets Engine (Encryption-as-a-Service / EaaS)

Di episode ini kita akan membahas Transit Secrets Engine — layanan enkripsi sebagai API. Vault mengenkripsi dan mendekripsi data sensitif (kartu kredit, NIK, data kesehatan) tanpa pernah menyimpan datanya. Kita akan mempraktikkan create key, encrypt, decrypt, dan rotasi key.

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

Pendahuluan

Setelah di episode 5 sebelumnya kita membahas Dynamic Database Secrets — kredensial sementara yang otomatis hancur — pada episode kali ini kita akan membahas topik yang menjawab pertanyaan yang berbeda namun sama kritisnya: bagaimana mengamankan data itu sendiri, bukan hanya kredensial yang mengaksesnya. Jawabannya: Transit Secrets Engine, atau yang dikenal sebagai Encryption-as-a-Service (EaaS).

Kenapa topik ini penting di dunia nyata? Coba pikirkan aplikasi yang mengelola data PII (Personally Identifiable Information): nomor kartu kredit, NIK, nomor BPJS, rekam medis, atau alamat email. Regulasi seperti GDPR, PCI-DSS, dan UU PDP di Indonesia mewajibkan data sensitif dienkripsi saat disimpan (at rest). Tapi masalah klasiknya: di mana menyimpan kunci enkripsinya? Jika kunci disimpan di dalam kode aplikasi, di environment variable, atau di file konfigurasi — maka sama saja dengan menaruh kunci gembok di sebelah gemboknya.

Vault Transit mengubah pola ini secara radikal: aplikasi tidak pernah melihat kunci enkripsi sama sekali. Aplikasi hanya mengirim data ke Vault, Vault yang memegang kunci, lalu mengembalikan hasilnya. Mari kita bedah mengapa ini begitu penting dan bagaimana cara kerjanya.

Pembahasan Utama

Problem Enkripsi Aplikasi Tradisional

Secara teknis, siapa pun bisa mengenkripsi data di aplikasi mereka — misalnya dengan library AES di Node.js, Python, atau Go. Tapi masalahnya bukan kemampuan untuk mengenkripsi, melainkan pengelolaan kunci (key management). Ketika setiap tim aplikasi mengenkripsi sendiri, berikut yang terjadi:

  1. Key sprawl — setiap aplikasi punya kunci sendiri, disimpan dengan caranya sendiri, di environment variable atau bahkan di source code. Tidak ada satu tempat pun yang menyimpan "siapa punya kunci apa".
  2. Kesulitan rotasi — saat kunci perlu dirotasi (wajib dilakukan berkala, atau darurat saat bocor), aplikasi harus diubah dan di-deploy ulang. Dengan puluhan aplikasi, ini memakan waktu berminggu-minggu.
  3. Algoritma yang tidak konsisten — satu tim memakai AES-256-GCM, tim lain memakai AES-CBC dengan IV yang salah, tim ketiga memakai MD5 untuk hashing. Audit keamanan menjadi mimpi buruk.
  4. Kunci tersebar di tangan banyak developer — semakin banyak orang yang "membawa" kunci, semakin besar permukaan serangan.
AspekIn-App EncryptionEncryption-as-a-Service
Lokasi kunciDi kode / env var aplikasiTerpusat di Vault, aplikasi tidak pernah melihatnya
Rotasi kunciDeploy ulang aplikasiSatu perintah API, tanpa mengubah aplikasi
Konsistensi algoritmaTergantung tiap timStandar, dikelola pusat
Audit penggunaan enkripsiTidak adaLengkap via audit log Vault
Knowledge secret ke developerTinggiNol — developer cukup tahu path transit
Kompleksitas implementasiPerlu keahlian kriptografiSatu HTTP call

Important

Prinsip utama di balik EaaS: pisahkan kunci dari data. Aplikasi boleh dan memang seharusnya menyimpan data terenkripsi, tetapi kunci enkripsi harus hidup di tempat terpisah yang terpusat, terkontrol, dan ter-audit. Ini persis filosofi yang sama dengan KMS (Key Management Service) di cloud — tapi dengan kebebasan untuk berjalan on-premise dan multi-cloud.

Konsep Transit: Enkripsi sebagai API

Secara singkat, alur kerja Transit adalah:

  1. Aplikasi mengirim plaintext (data asli) ke Vault: vault write transit/encrypt/my-app-key plaintext=$(echo "..." | base64).
  2. Vault mengenkripsi dengan kunci yang tersimpan di dalam Vault, mengembalikan ciphertext (data terenkripsi) ke aplikasi.
  3. Aplikasi menyimpan ciphertext di databasenya.
  4. Saat data dibutuhkan lagi, aplikasi mengirim ciphertext kembali: vault write transit/decrypt/my-app-key ciphertext=....
  5. Vault mendekripsi dan mengembalikan plaintext.

Poin kunci yang sering disalahpahami: Vault tidak pernah menyimpan data. Ciphertext hidup di database aplikasi; Vault hanyalah mesin enkripsi yang memegang kunci. Jika kalian menghapus data di database aplikasi, data itu hilang dari seluruh sistem — Vault tidak punya salinannya.

Mengaktifkan Transit Secrets Engine
vault secrets enable transit

Output:

Output vault secrets enable transit
Success! Enabled the transit secrets engine at: transit/

Membuat Encryption Key

Setiap penggunaan Transit dimulai dari sebuah key. Nama key ini adalah satu-satunya "alamat" yang perlu diketahui aplikasi:

Membuat encryption key
vault write -f transit/keys/my-app-key

Output:

Output vault write -f transit/keys
Key                       Value
---                       -----
allow_plaintext_backup    false
auto_rotate_period        0s
deletion_allowed          false
derived                   false
exportable                false
keys                      map[1:map[creation_time:2026-08-02T09:00:00Z name:my-app-key version:1]]
latest_version            1
min_available_version     0
min_decryption_version    1
supports_decryption       true
supports_derivation       true
supports_encryption       true
supports_signing          true
type                      aes256-gcm96

Perhatikan beberapa hal penting:

  • latest_version: 1 — key punya sistem versi seperti KV. Versi ini krusial untuk rotasi.
  • type: aes256-gcm96 — default key type, AES-256 dengan GCM (authenticated encryption). Kunci 256-bit yang sangat kuat.
  • supports_decryption: true — key ini bisa dipakai untuk encrypt dan decrypt.

Note

Flag -f pada vault write -f transit/keys/my-app-key berarti "jangan tanya nilai apa pun" — karena membuat key tidak butuh argumen tambahan. Pola ini juga dipakai untuk operasi rotasi nanti.

Enkripsi: Mengirim Data ke Vault

Transit menerima input plaintext dalam format base64. Kenapa base64? Karena enkripsi bekerja pada byte, dan base64 adalah cara standar untuk mewakili byte (termasuk data biner atau karakter unicode) dalam teks yang aman dikirim melalui API.

Enkripsi data sensitif
vault write transit/encrypt/my-app-key plaintext=$(echo -n "NIK: 3273121234567890" | base64)

Output:

Output vault write transit/encrypt
Key           Value
---           -----
ciphertext    vault:v1:k2x9mQ8pLzV7nB4cX1dF6gH3jR5sT0wY...

Ciphertext yang dihasilkan memiliki format vault:v1:.... Bagian vault: menandakan asal ciphertext, v1 adalah versi key yang dipakai untuk mengenkripsi. Format ini penting karena saat key dirotasi, Vault tetap bisa mendekripsi data lama yang dienkripsi dengan versi key sebelumnya.

Dekripsi: Mengembalikan Data

Dekripsi ciphertext
vault write transit/decrypt/my-app-key ciphertext="vault:v1:k2x9mQ8pLzV7nB4cX1dF6gH3jR5sT0wY..."

Output:

Output vault write transit/decrypt
Key       Value
---       -----
plaintext TklLOiAzMjczMTIxMjM0NTY3ODkw

Untuk melihat data aslinya, decode hasil base64:

Decode hasil plaintext
echo -n "TklLOiAzMjczMTIxMjM0NTY3ODkw" | base64 -d

Output:

Output base64 -d
NIK: 3273121234567890

Mari rangkum seluruh alur encrypt-decrypt dalam satu code-group agar mudah dibandingkan:

vault write transit/encrypt/my-app-key \
    plaintext=$(echo -n "NIK: 3273121234567890" | base64)

Rotasi Kunci: Rahasia Keamanan Jangka Panjang

Inilah kekuatan utama Transit dibanding enkripsi in-app: rotasi kunci yang tanpa-downtime. Ketika kalian merotasi kunci:

Merotasi key
vault write -f transit/keys/my-app-key/rotate

Output:

Output rotasi key
Success! Data written to: transit/keys/my-app-key/rotate

Yang terjadi di balik layar:

  1. Versi key naik ke 2 (cek dengan vault read transit/keys/my-app-key).
  2. Semua enkripsi baru otomatis memakai versi 2.
  3. Semua data lama yang dienkripsi dengan versi 1 tetap bisa didekripsi — karena Vault menyimpan versi lama sebagai decryption keys.
  4. Aplikasi tidak perlu diubah sama sekali. Nol downtime, nol deploy.
Melihat status key setelah rotasi
vault read transit/keys/my-app-key

Output:

Output vault read transit/keys
Key                       Value
---                       -----
latest_version            2
min_available_version     0
min_decryption_version    1
keys                      map[1:map[creation_time:2026-08-02T09:00:00Z name:my-app-key version:1] 2:map[creation_time:2026-08-02T10:00:00Z name:my-app-key version:2]]

Perhatikan keys kini berisi versi 1 dan 2. Versi 1 tidak dihapus — ia disimpan untuk keperluan dekripsi data lama. Inilah yang disebut key versioning.

Untuk melihat seluruh key yang tersedia di mount transit:

List semua key di mount transit
vault list transit/keys

Output:

Output vault list transit/keys
Keys
----
my-app-key

Pola Integrasi: Enkripsi saat Menulis, Dekripsi saat Membaca

Setelah memahami primitifnya, mari lihat bagaimana pola ini dipakai di aplikasi sungguhan. Alur yang paling umum disebut encrypt-at-write, decrypt-at-read: saat aplikasi menyimpan data PII ke database, data terlebih dahulu dienkripsi lewat Vault; saat data dibaca kembali untuk ditampilkan, aplikasi mendekripsinya lewat Vault. Database hanya menyimpan ciphertext.

vault write transit/encrypt/my-app-key \
    plaintext=$(echo -n "arman@devvnull.local" | base64)

Dari sisi aplikasi, logikanya sederhana: panggil API Vault dua kali — sekali saat menyimpan, sekali saat menampilkan. Yang luar biasa: aplikasi tidak pernah tahu kunci enkripsinya, dan data sensitif tidak pernah tersimpan dalam bentuk aslinya di database. Jika database bocor, yang bocor hanyalah ciphertext — tidak berguna tanpa Vault.

Re-Wrap: Menyegarkan Data Lama

Setelah rotasi, ciphertext lama masih terenkripsi dengan versi 1. Untuk keamanan optimal, data lama sebaiknya di-re-encrypt ke versi baru — menghapus ketergantungan pada kunci lama. Proses ini disebut re-wrapping:

Re-wrap ciphertext ke versi terbaru
vault write transit/rewrap/my-app-key \
    ciphertext="vault:v1:k2x9mQ8pLzV7nB4cX1dF6gH3jR5sT0wY..."

Output:

Output vault write transit/rewrap
Key           Value
---           -----
ciphertext    vault:v2:rT4uW0xYqN9sL7bVc2eF5gH8jK1mP0nZ...

Perhatikan bagian v1 pada ciphertext input kini menjadi v2 pada output. Data yang sama, tetapi sekarang terenkripsi dengan kunci versi 2 — tanpa pernah memaparkan plaintext ke aplikasi. Inilah alasan kenapa rewrap lebih aman daripada decrypt-then-encrypt: data tidak pernah "terbuka" di dalam aplikasi.

Tip

Untuk key dengan rotasi rutin (misalnya kebijakan rotasi tiap 90 hari), gabungkan auto_rotate_period saat membuat key — misalnya vault write transit/keys/app period="8760h" untuk rotasi otomatis setahun sekali. Vault akan merotasi kunci secara berkala tanpa intervensi manual, dan karena mekanisme versioning, seluruh ciphertext lama tetap bisa didekripsi.

Kasus Penggunaan Nyata di Indonesia

Agar lebih membumi, berikut skenario-skenario di mana Transit dipakai di dunia nyata:

SkenarioData yang DienkripsiMengapa Transit Cocok
E-commerce / Payment gatewayNomor kartu kredit, CVV (dengan tokenisasi)Memenuhi PCI-DSS, rotasi kunci tanpa downtime
Fintech & PerbankanNIK, nomor rekening, saldo transaksiUU PDP, audit trail penggunaan enkripsi
Rumah sakit / Health-techRekam medis, hasil lab, data pasienData kesehatan sangat sensitif, wajib enkripsi at rest
SaaS multi-tenantAPI keys pelanggan, data PIIEnkripsi per-tenant dengan key berbeda (derived + context)
E-commerce appAlamat, nomor telepon pelangganCompliance & trust

Warning

Penting untuk memahami batas Transit: Transit tidak menyimpan data dan tidak menggantikan fungsi database atau storage. Ia hanya mesin enkripsi. Untuk data yang volumenya besar, kirim ke Transit dalam batch; untuk keperluan yang butuh penyimpanan rahasia terpusat, gunakan KV. Jangan bingung antara "mengenkripsi data" (Transit) dengan "menyimpan rahasia" (KV) — keduanya sering dianggap sama padahal peran arsitekturalnya berbeda.

Kesalahan Umum Transit

KesalahanGejalaSolusi
Tidak meng-encode plaintext ke base64Error: plaintext is required / data rusakSelalu `echo -n "..."
Menyimpan plaintext di Vault "biar aman"Data justru tersebar di banyak tempatCiphertext di database aplikasi, plaintext tidak disimpan
Lupa bahwa ciphertext lama tetap valid setelah rotasiPanik saat mendekripsi data lamaItu fitur! Versi lama disimpan untuk dekripsi
Menganggap rewrap = decryptMencoba decrypt dulu lalu encrypt lagiPakai rewrap agar plaintext tidak pernah keluar
Memakai key yang sama untuk semua tenantKebocoran satu aplikasi = semua data terbacaPertimbangkan derived key + konteks per aplikasi
Tidak pernah merotasi kunciRisiko jika satu kunci bocorJadwalkan rotasi rutin (manual / auto_rotate_period)

Penutup

Pada episode 6 ini kita telah membahas Transit Secrets Engine (Encryption-as-a-Service): mengapa aplikasi sebaiknya tidak mengelola kunci enkripsi sendiri, cara kerja Transit sebagai mesin enkripsi via API, seluruh alur create key → encrypt → decrypt, serta mekanisme rotasi kunci dan re-wrap yang memungkinkan pergantian kunci tanpa downtime dan tanpa memaparkan plaintext.

Inti episode ini: Vault Transit memisahkan kunci dari data — aplikasi mengelola data, Vault mengelola kunci. Dengan ini, kepatuhan terhadap regulasi seperti PCI-DSS dan UU PDP menjadi jauh lebih mudah dipenuhi, karena enkripsi at rest dilakukan oleh kunci yang terpusat, teraudit, dan mudah dirotasi.

Di episode 7 selanjutnya, kita akan membahas secrets engine yang melindungi lapisan komunikasi: PKI Secrets Engine — cara Vault bertindak sebagai Certificate Authority otomatis, menerbitkan sertifikat TLS short-lived untuk service internal, dan menyelesaikan masalah klasik sertifikat yang kadaluarsa tanpa sepengetahuan siapa pun. Pastikan tetap semangat!

Belajar Vault - Transit Secrets Engine (Encryption-as-a-Service / EaaS) | Belajar Secret Management dengan HashiCorp Vault