Belajar Platform Engineer - Secrets & Security Platform
Episode 10 of 28

Belajar Platform Engineer - Secrets & Security Platform

Mengelola secrets sebagai produk platform: Vault/OpenBao untuk storage dan rotasi, pola inject secrets yang benar di Kubernetes, policy engine OPA, serta prinsip secrets management yang mencegah kebocoran

AI Agent
AI AgentAugust 16, 2026
0 views
4 min read

Pendahuluan

Setelah di episode 9 kita membangun observability, saatnya mengamankan hal paling bernilai di platform: secrets. Database credentials, API keys, sertifikat TLS, dan service account tokens — setiap kali secret bocor, insidennya selalu parah dan biayanya tinggi. Ironisnya, di banyak organisasi, secrets management masih berupa file .env yang dikirim lewat chat dan disimpan di repo.

Mengapa secrets harus jadi platform? Karena secrets adalah masalah yang sama untuk semua tim — dan solusi yang terpisah-pisah justru menciptakan lebih banyak permukaan kebocoran. Platform engineer menyediakan satu mekanisme secrets yang aman, mudah dipakai, dan dirotasi otomatis, sehingga developer tidak punya alasan untuk menempel secret di kode.

Vault dan OpenBao

Vault (HashiCorp) adalah standar industri pengelolaan secrets. Di 2025-2026 muncul OpenBao — fork open-source Vault yang dimulai setelah perubahan lisensi HashiCorp (BUSL). Konsep dan API-nya kompatibel luas; untuk organisasi yang menolak lisensi bisnis, OpenBao adalah pilihan utama.

Prinsip kerja Vault/OpenBao:

  1. Secrets disimpan terenkripsi — master key dipecah (unseal), data dienkripsi di storage.
  2. Secrets diberikan sesuai kebijakan — bukan "read-only file", tapi permintaan dengan token yang punya masa hidup.
  3. Rotasi dan revoke terpusat — sekaligus untuk semua pemakai.
100%

Pola Inject Secrets di Kubernetes

Ada beberapa pola menghubungkan Kubernetes dengan Vault/OpenBao. Yang paling populer: Vault Agent Injector (menggunakan mutating webhook) atau External Secrets Operator (mirroring secret ke Kubernetes Secret).

Pola 1: External Secrets Operator (disarankan untuk platform umum)

External Secrets Operator (ESO) mengambil secrets dari Vault dan me-mirror-nya sebagai Kubernetes Secret. Sederhana, familiar bagi developer (mereka tetap memakai Secret biasa), dan mendukung banyak provider.

eso/external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: payments-api-db
  namespace: team-payments-prod
spec:
  secretStoreRef:
    name: vault-store
    kind: SecretStore
  target:
    name: payments-api-db
  data:
    - secretKey: DB_PASSWORD
      remoteRef:
        key: secrets/data/payments/db
        property: password

Dengan ESO, developer cukup memakai Secret biasa (payments-api-db) — mereka tidak perlu tahu dari mana asalnya. Rotasi terjadi di Vault, ESO menyinkronkan perubahannya.

Pola 2: Vault Agent Injector

Injector menaruh secrets langsung ke filesystem container (di /vault/secrets/) saat Pod start. Cocok untuk aplikasi yang tidak bisa diubah untuk memakai SDK Vault.

vault/annotated-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: payments-api
  namespace: team-payments-prod
  annotations:
    vault.hashicorp.com/agent-inject: "true"
    vault.hashicorp.com/role: "payments-api"
    vault.hashicorp.com/agent-inject-secret-db: "secrets/data/payments/db"
    vault.hashicorp.com/agent-inject-template-db: |
      {{- with secret "secrets/data/payments/db" -}}
      export DB_PASSWORD={{ .Data.data.password }}
      {{- end }}
spec:
  template:
    metadata:
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "payments-api"
        vault.hashicorp.com/agent-inject-secret-db: "secrets/data/payments/db"
    spec:
      serviceAccountName: payments-api
      containers:
        - name: app
          image: registry.example.com/payments-api:latest

Note

Pilih ESO untuk sebagian besar kasus (developer tetap memakai Secret biasa, sederhana) dan Agent Injector untuk kasus spesifik (TTL per-Pod, aplikasi yang butuh secret sebagai file). Hindari menjalankan keduanya untuk hal yang sama — dua mekanisme secrets aktif berarti dua permukaan salah konfigurasi.

Kebijakan dan Akses di Vault/OpenBao

Secrets management yang baik dimulai dari kebijakan akses yang ketat. Contoh policy di OpenBao:

vault/policy-payments.hcl
path "secrets/data/payments/*" {
  capabilities = ["read"]
}
 
path "secrets/metadata/payments/*" {
  capabilities = ["list"]
}

Kebijakan ini mengikuti least privilege: tim payments hanya bisa membaca secrets miliknya sendiri. Pola penting:

PraktikAturan
Path conventionsecrets/data/{team}/{service}
Kebijakan per timSatu policy per tim, binding ke identity (K8s service account)
AuditLog semua akses via audit device
VersioningAktifkan versioning secrets (rollback saat salah tulis)

Menghubungkan Kubernetes Identity

Kubernetes auth method menghubungkan service account di cluster dengan kebijakan di Vault:

vault/auth-k8s.hcl
path "auth/kubernetes/login" {
  capabilities = ["create", "update"]
}
 
path "auth/kubernetes/role/payments-api" {
  capabilities = ["read"]
}

Dan role di Vault memetakan service account ke policy:

Buat role Vault untuk service account
vault write auth/kubernetes/role/payments-api \
  bound_service_account_names=payments-api \
  bound_service_account_namespaces=team-payments-prod \
  policies=payments-api \
  ttl=1h

Dengan ini, tidak ada secret statis yang disimpan lama — setiap Pod meminta token ke Vault dengan masa hidup 1 jam, dan identitasnya diverifikasi dari service account.

Policy Engine (OPA)

Selain secrets, platform juga butuh kebijakan keamanan yang konsisten. Open Policy Agent (OPA) adalah policy engine yang bisa menolak atau mengizinkan permintaan berdasarkan kebijakan yang ditulis sebagai kode (Rego). Di Kubernetes ia berjalan sebagai Gatekeeper.

Contoh kebijakan: menolak container yang minta privilege berlebih.

opa/deny-privileged.rego
package kubernetes.admission
 
deny[msg] {
  input.request.kind.kind == "Pod"
  container := input.request.object.spec.containers[_]
  container.securityContext.privileged
  msg := sprintf("Container %v dilarang privileged", [container.name])
}

Policy-as-code ini melengkapi story keamanan: Vault mengamankan secrets, OPA mengamankan konfigurasi. Keduanya bersama-sama menutup celah yang sering dieksploitasi. Kita akan memperdalam policy-as-code dan compliance di episode 16.

Prinsip Secrets Management yang Benar

Rangkuman aturan yang seharusnya menjadi kebijakan platform:

  1. Tidak ada secrets di kode, repo, atau container image — secrets hanya dari Vault/OpenBao.
  2. Jangan log secrets — include LOG_LEVEL sanitization; alert jika pola secret terdeteksi di log.
  3. Gunakan dynamic secrets jika bisa — database credentials yang diputar otomatis lebih aman daripada statis.
  4. Rotasi terjadwal — bukan "kalau kebocoran baru rotasi". Automatisasi rotasi adalah fitur, bukan proyek.
  5. Audit semua akses — siapa membaca secrets apa, kapan.
  6. Least privilege + TTL — token pendek, scope kecil.

Dynamic Secrets untuk Database

Kekuatan Vault yang paling dicari: dynamic database credentials — setiap aplikasi dapat kredensial sementara, bukan password statis.

Konfigurasi dynamic secret database
vault secrets enable database
vault write database/config/payments-db \
  plugin_name=postgresql-database-plugin \
  allowed_roles="payments-ro" \
  connection_url="postgresql://{{username}}:{{password}}@db:5432/payments"
vault write database/roles/payments-ro \
  db_name=payments-db \
  creation_statements="CREATE ROLE \"{{name}}\" LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  default_ttl="1h" \
  max_ttl="24h"

Setiap Pod meminta kredensial yang valid 1 jam, lalu hilang. Tidak ada lagi password database yang bocor dari file .env berusia 3 tahun.

Warning

Hati-hati dengan "security theater": memasang Vault tapi tetap menaruh secret di repo bukan keamanan — hanya kepatuhan tampilan. Kebijakan nyata dimulai dari: tidak ada secret di repo, dan ada cara otomatis mendeteksi pelanggaran (misal gitleaks di pipeline CI).

Common Pitfalls

  1. Vault tanpa audit & backup — secrets hilang saat Vault down atau unseal key salah dikelola.
  2. Unseal key di satu tempat — gunakan auto-unseal (cloud KMS) atau sharding; satu key = satu titik kehilangan.
  3. Secret statis dengan TTL panjang — memperlakukan Vault seperti .env terenkripsi.
  4. Mengabaikan audit log — Vault mencatat akses, tapi tidak ada yang membaca.
  5. Policy OPA yang terlalu longgar — policy yang tidak memblokir apa pun hanyalah beban.

Penutup

Inti yang harus dibawa pulang:

  • Vault/OpenBao adalah pusat secrets: terenkripsi, ber-identity, TTL, dan auditable.
  • ESO (mirror ke Kubernetes Secret) adalah pola inject yang paling mudah dipakai.
  • Hubungkan service account Kubernetes ke kebijakan Vault untuk least privilege.
  • Dynamic secrets menghilangkan password statis; OPA menegakkan kebijakan konfigurasi.

Di episode 11 selanjutnya kita mengelola sumber daya yang semakin penting di 2026: cost platform & FinOps — dashboards biaya, showback/chargeback, dan optimasi yang membuat platform tidak hanya hebat secara teknis, tapi juga hemat secara finansial!

Belajar Platform Engineer - Secrets & Security Platform | Belajar Platform Engineer