Di episode ini kita akan membahas PKI Secrets Engine — menjadikan Vault sebagai Certificate Authority yang menerbitkan sertifikat TLS short-lived secara otomatis. Kita akan menyiapkan Root CA dan Intermediate CA, menerbitkan sertifikat on-demand, serta memahami CRL, OCSP, dan revocation.

Setelah di episode 6 sebelumnya kita membahas Transit Secrets Engine untuk mengamankan data at rest, pada episode kali ini kita akan mengamankan lapisan berikutnya: komunikasi antar service. Masalahnya sederhana namun nyata: hampir semua aplikasi modern memakai TLS/SSL, tapi siapa yang mengurus sertifikatnya? Jawaban klasiknya adalah "kadang-kadang", "saat teringat", atau "ketika sudah error di browser".
Kenapa topik ini penting di dunia nyata? Sertifikat TLS internal yang kadaluarsa adalah salah satu insiden paling umum dan paling memalukan di perusahaan. Sertifikat untuk api.internal.local atau koneksi antar microservice sering dibuat manual dengan OpenSSL, dipasang sekali, lalu dilupakan — sampai tiba-tiba staging environment error "certificate expired" di tengah malam. Belum lagi praktik buruk memakai sertifikat yang sama di banyak server, atau self-signed certificate yang membuat tim lain tidak percaya.
PKI Secrets Engine menyelesaikan masalah ini dengan cara yang sangat Vault: sertifikat menjadi short-lived (misal TTL 24 jam), diterbitkan otomatis lewat API, dan rotasi menjadi bagian dari siklus hidup normal — bukan acara tahunan yang dikerjakan manual. Mari kita bedah bagaimana Vault menjadi Certificate Authority (CA) yang sesungguhnya.
PKI Secrets Engine memungkinkan Vault bertindak sebagai Certificate Authority: membuat key dan sertifikat X.509, menerbitkan sertifikat on-demand, dan mengelola pencabutannya.
Arsitektur yang direkomendasikan di produksi menggunakan dua tingkat CA:
| Level | Fungsi | Karakteristik |
|---|---|---|
| Root CA | Akar kepercayaan seluruh sistem | Offline/jarang dipakai, disimpan sangat aman, TTL panjang (10 tahun) |
| Intermediate CA | CA yang sebenarnya menerbitkan sertifikat | TTL sedang, mudah dirotasi, jika bocor cukup dicabut dari Root CA |
Kenapa dua tingkat? Prinsip compartmentalization. Jika hanya ada satu Root CA dan kuncinya bocor, seluruh infrastruktur harus dibangun ulang. Dengan intermediate CA, jika kunci intermediate bocor, kita cukup mencabutnya (revoke) dan membuat intermediate baru — Root CA yang aman tidak terusik. Ini persis seperti struktur PKI di dunia nyata (misalnya Let's Encrypt memakai Root + Intermediate).
Important
Filosofi kunci PKI di Vault: sertifikat yang TTL-nya pendek membuat revokasi hampir tidak diperlukan. Jika sertifikat hanya hidup 24 jam dan aplikasi otomatis meminta yang baru, maka masalah "sertifikat bocor" menjadi masalah kecil yang menunggu kedaluwarsa — bukan insiden darurat. Ini kebalikan dari pola tradisional sertifikat 1 tahunan yang harus di-revoke manual.
Pertama, kita mount PKI secrets engine untuk Root CA:
vault secrets enable -path=pki pkiOutput:
Success! Enabled the pki secrets engine at: pki/Batasi TTL maksimum untuk Root CA — 10 tahun:
vault secrets tune -max-lease-ttl=87600h pkiGenerate self-signed Root CA:
vault write pki/root/generate/internal \
common_name="devvnull.local Root CA" \
ttl=87600hOutput:
Key Value
--- -----
certificate -----BEGIN CERTIFICATE-----
MIIFxzCCA6+gAwIBAgIUDhH... (certificate PEM di sini)
-----END CERTIFICATE-----
expiration 2036-08-02T09:15:00.000Z
issuing_ca -----BEGIN CERTIFICATE-----
MIIFxzCCA6+gAwIBAgIUDhH... (sama dengan certificate untuk root self-signed)
-----END CERTIFICATE-----
serial_number 4a:7c:...Warning
Simpan certificate Root CA di tempat aman, dan catat baik-baik bahwa kunci private Root CA tidak pernah keluar dari Vault — output di atas hanya menampilkan sertifikat publik. Di produksi, pertimbangkan meletakkan Root CA pada Vault cluster terpisah yang jarang diakses, atau bahkan menyimpannya dalam bentuk offline.
Konfigurasi URL untuk CRL (Certificate Revocation List) dan OCSP:
vault write pki/config/urls \
issuing_certificates="http://vault.local:8200/v1/pki/ca" \
crl_distribution_points="http://vault.local:8200/v1/pki/crl"Sekarang mount PKI kedua untuk intermediate CA:
vault secrets enable -path=pki_int pkivault secrets tune -max-lease-ttl=43800h pki_intGenerate Certificate Signing Request (CSR) di mount intermediate:
vault write -format=json pki_int/intermediate/generate/internal \
common_name="devvnull.local Intermediate CA" \
ttl=43800hOutput (CSR dalam format JSON, karena panjangnya besar):
{
"data": {
"csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIICzzCCAbc...\n-----END CERTIFICATE REQUEST-----",
"key_id": "b0a2c46d...",
"private_key_type": "rsa"
}
}CSR ini adalah "permintaan" dari intermediate ke Root. Untuk menandatanganinya, simpan CSR ke file lalu tanda tangani dengan Root CA mount:
vault write pki/root/sign-intermediate \
csr=@/tmp/intermediate.csr \
format=pem_bundle \
ttl=43800hOutput:
Key Value
--- -----
certificate -----BEGIN CERTIFICATE----- (sertifikat intermediate yang ditandatangani Root)
...
ca_chain -----BEGIN CERTIFICATE----- (chain Root + Intermediate)
...
expiration 2034-08-02T09:20:00.000Z
issuing_ca -----BEGIN CERTIFICATE----- (Root CA)Terakhir, set certificate yang sudah ditandatangani sebagai intermediate CA di mount pki_int:
vault write pki_int/intermediate/set-signed certificate=@/tmp/intermediate.crtOutput:
Success! Data written to: pki_int/intermediate/set-signedSebelum bisa menerbitkan sertifikat, kita harus mendefinisikan role — aturan tentang sertifikat seperti apa yang boleh diterbitkan (domain apa, TTL berapa):
vault write pki_int/roles/my-role \
allowed_domains="internal.local" \
allow_subdomains=true \
max_ttl="720h" \
default_ttl="24h" \
key_type="rsa" \
key_bits="2048"Output:
Success! Data written to: pki_int/roles/my-roleWarning
Kesalahan paling umum saat memulai PKI: lupa membuat role. Command vault write pki_int/issue/my-role akan gagal jika role my-role belum ada, atau jika common_name yang diminta tidak cocok dengan allowed_domains. Ingat aturan mainnya: role = kebijakan penerbitan, dan setiap penerbitan wajib melalui role. Baca error no matching role sebagai petunjuk untuk mengecek nama role dan allowed_domains.
Inilah momen inti episode ini — menerbitkan sertifikat lewat satu perintah:
vault write pki_int/issue/my-role common_name="api.internal.local" ttl="24h"Output:
Key Value
--- -----
certificate -----BEGIN CERTIFICATE-----
MIIE... (certificate PEM untuk api.internal.local)
-----END CERTIFICATE-----
ca_chain [-----BEGIN CERTIFICATE----- (intermediate) -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- (root) -----END CERTIFICATE-----]
expiration 2026-08-03T09:30:00.000Z
issuing_ca -----BEGIN CERTIFICATE-----(intermediate)-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIE... (kunci privat yang sesuai dengan sertifikat ini)
-----END RSA PRIVATE KEY-----
private_key_type rsa
serial_number 6c:1f:9a:...Caution
Perhatikan output di atas: private_key dikeluarkan oleh Vault satu kali pada saat penerbitan. Ini berarti Vault tidak menyimpan kunci privat sertifikat — aplikasi yang meminta sertifikat wajib menyimpan private key tersebut dengan aman (misalnya di file dengan permission ketat, atau Vault Agent template). Setelah response ini hilang, kunci privat tidak bisa diambil lagi; sertifikatnya pun harus diterbitkan ulang.
Sertifikat yang dihasilkan punya masa hidup 24 jam (expiration: 2026-08-03). Artinya, aplikasi yang sadar-PKI akan meminta sertifikat baru setiap hari — dan otomatis mendapat key + sertifikat segar. Pola inilah yang membuat serangan "sertifikat kadaluarsa yang lupa diperbarui" menjadi tidak mungkin terjadi.
| Aspek | Sertifikat Tradisional (1 tahun) | Sertifikat Short-Lived (24 jam) |
|---|---|---|
| Masa hidup | 1 tahun atau lebih | Jam / hari |
| Rotasi | Manual, sering terlupakan | Otomatis, bagian dari siklus aplikasi |
| Dampak kebocoran key | Panjang, butuh revoke manual | Singkat, menunggu kedaluwarsa saja |
| Proses penerbitan | Mengisi form CSR, menunggu CA manual | Satu API call, dalam hitungan detik |
| Visibilitas | Tersebar, sulit dilacak | Terpusat, teraudit di Vault |
| Perilaku saat CA bermasalah | Tidak terpengaruh | Aplikasi tidak dapat sertifikat baru (perlu retry) |
Meski short-lived mengurangi kebutuhan revokasi, Vault tetap menyediakan mekanisme standar PKI:
/v1/pki/crl (dan /v1/pki_int/crl untuk intermediate).Mencabut sertifikat yang terlanjur bermasalah:
vault write pki_int/revoke serial_number="6c:1f:9a:..."Output:
Key Value
--- -----
revocation_time 1722570000
revocation_time_rfc3339 2026-08-02T10:00:00.000Z
state revokedSetelah revoke, serial number tersebut masuk ke CRL dan koneksi yang memverifikasi lewat CRL/OCSP akan menolak sertifikat itu.
Tip
Kalian juga bisa melihat seluruh sertifikat yang diterbitkan Vault beserta statusnya: vault list pki_int/certs untuk daftar serial number, dan vault read pki_int/cert/<serial> untuk detailnya. Ini semacam "inventaris sertifikat" otomatis yang tidak pernah ada di era pengelolaan manual.
Salah satu keuntungan paling terasa dari PKI engine adalah visibilitas total. Mari lihat sertifikat apa saja yang pernah diterbitkan:
vault list pki_int/certsOutput:
Keys
----
2a:1f:9c:...
6c:1f:9a:...
a3:8e:2b:...Setiap serial number mewakili satu sertifikat. Kalian bisa menarik detailnya:
vault read pki_int/cert/6c:1f:9a:...Output:
Key Value
--- -----
certificate -----BEGIN CERTIFICATE-----
MIIE... (certificate PEM)
-----END CERTIFICATE-----
revocation_time <nil>
revocation_time_rfc3339 <nil>
state issuedPerhatikan kolom state: issued dan revocation_time: <nil> — tanda bahwa sertifikat ini masih aktif. Dengan inventaris seperti ini, tim tidak perlu lagi membuat spreadsheet manual untuk melacak "siapa yang punya sertifikat apa".
Tapi visibilitas saja tidak cukup — bagian tersulit adalah renewal otomatis. Sertifikat TTL 24 jam tidak berguna jika proses memintanya masih manual. Di produksi, pola yang dipakai:
| Pola Renewal | Cara Kerja | Cocok untuk |
|---|---|---|
| Vault Agent template (episode 14-15) | Agent di samping aplikasi merefresh sertifikat + key ke file, lalu reload service | Aplikasi yang membaca cert dari file |
| Vault SDK di aplikasi | Aplikasi meminta sertifikat baru sebelum TTL habis lewat library | Aplikasi yang ingin kontrol penuh |
| Vault Secrets Operator (episode 17) | Operator Kubernetes merefresh cert dan me-restart pod secara otomatis | Workload di Kubernetes |
Kunci keberhasilannya ada di satu pola pikir: jangan menunggu sertifikat kadaluarsa — jadwalkan renewal jauh sebelum TTL habis (misalnya pada 2/3 umur sertifikat). Dengan begitu, "sertifikat kadaluarsa" berubah dari insiden menjadi kejadian yang tidak pernah terjadi.
| Kesalahan | Gejala | Solusi |
|---|---|---|
| Lupa membuat role | Error no matching role saat issue | Buat role dengan allowed_domains yang sesuai |
common_name di luar allowed_domains | Error permission / rejected | Pastikan domain cocok dengan role (dan allow_subdomains jika perlu) |
TTL diminta melebihi max_ttl | TTL dipotong atau ditolak | Cek vault secrets tune -max-lease-ttl dan max_ttl role |
| Hanya memakai satu mount (tanpa intermediate) | Root CA berisiko bocor / susah dirotasi | Ikuti arsitektur Root + Intermediate |
| Lupa menyimpan private key saat issue | Sertifikat tidak bisa dipakai tanpa key | Simpan private_key dengan aman segera setelah issue |
Tidak memakai allow_subdomains untuk wildcard subdomain | Issue app.internal.local ditolak | Set allow_subdomains=true di role |
| Sertifikat diaplikasikan pada service tanpa auto-renew | Masalah kadaluarsa kembali | Bangun rotasi otomatis (Vault Agent / SDK) — episode 14-16 |
Pada episode 7 ini kita telah membahas PKI Secrets Engine: mengapa sertifikat internal yang kadaluarsa adalah masalah nyata, arsitektur Root CA + Intermediate CA yang dianjurkan, alur lengkap pembuatan Root, CSR intermediate yang ditandatangani Root, pembuatan role, hingga penerbitan sertifikat short-lived on-demand. Kita juga melihat CRL, OCSP, mekanisme revocation, dan jebakan-jebakan umumnya.
Inti episode ini: sertifikat short-lived mengubah rotasi sertifikat dari acara tahunan yang melelahkan menjadi siklus hidup otomatis harian. Dengan TTL 24 jam, tidak ada lagi yang namanya "sertifikat kadaluarsa yang terlupakan" — dan jika terjadi kebocoran, dampaknya dibatasi oleh umur sertifikat, bukan oleh kecepatan manusia merespons.
Di episode 8 selanjutnya, kita akan melengkapi pengetahuan secrets engine dengan tiga engine tambahan yang sering dipakai di lapangan: TOTP (2FA terpusat), SSH (OTP & CA signing), dan AWS (dynamic IAM credentials). Tiga persoalan keamanan berbeda, satu pola pikir yang sama: rahasia tidak disimpan, melainkan dikelola. Pastikan tetap semangat!