karawaci.kode

2026-08-23 · 10 min

Vault vs Doppler vs GitHub Secrets: Secrets Management untuk Startup

Setiap startup pasti sampai di titik ini: .env file yang di-copy paste lewat Slack, secret production yang cuma ada di laptop satu orang, dan tidak ada yang tahu password database itu sudah berapa tahun tidak diganti. Saya sudah melihat pola ini di beberapa klien Jakarta — dan kebanyakan baru bergerak setelah ada insiden. Artikel ini membahas tiga opsi yang paling sering saya rekomendasikan beserta kondisi kapan masing-masing masuk akal.

Kenapa Secrets Management Itu Masalah Nyata

Sebelum masuk ke tool, saya ingin luruskan dulu: secrets management bukan soal paranoia keamanan. Ini soal operabilitas. Pertanyaan praktisnya: ketika ada karyawan resign, seberapa cepat Anda bisa revoke aksesnya ke semua secret? Ketika ada rotasi database credential, berapa banyak tempat yang harus diupdate manual? Ketika production down jam 2 pagi, apakah on-call engineer bisa akses secret tanpa harus membangunkan orang lain?

Tiga opsi yang akan saya bahas:

  1. GitHub Secrets — sudah ada, gratis, cukup untuk banyak kasus
  2. Doppler — managed secrets platform, sweet spot untuk startup
  3. HashiCorp Vault — powerful, tapi ada ongkos ops yang signifikan

GitHub Secrets: Titik Awal yang Wajar

Kalau tim Anda sudah pakai GitHub Actions untuk CI/CD, GitHub Secrets adalah zero-friction choice. Secret dienkripsi dengan libsodium, tidak pernah muncul di log, dan langsung tersedia sebagai environment variable di workflow.

# .github/workflows/deploy.yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy ke production
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
        run: |
          ./scripts/deploy.sh

GitHub Secrets punya hierarki yang berguna: Repository secrets, Environment secrets (staging vs production dipisah), dan Organization secrets (untuk secrets yang dishare ke banyak repo). Untuk tim yang baru pertama kali structured mengelola secrets, ini cukup.

Yang menjadi batas GitHub Secrets:

  • Tidak ada audit log akses: Anda tahu siapa yang bisa set secret, tapi tidak tahu kapan secret itu diakses atau dipakai
  • Tidak ada versioning secret: salah overwrite, tidak ada rollback
  • Rotasi manual: update secret di GitHub UI, lalu pastikan semua workflow sudah pakai value baru
  • Tidak ada injection ke aplikasi running: GitHub Secrets hanya bekerja dalam konteks GitHub Actions runner, bukan di server production Anda yang sedang berjalan

Kalau deployment Anda masih sederhana — push ke VPS lewat GitHub Actions, satu environment production — GitHub Secrets adalah pilihan yang sangat masuk akal. Jangan over-engineer ini.

Doppler: Sweet Spot untuk Startup

Doppler adalah managed secrets platform yang positioning-nya persis di antara “cukup powerful” dan “tidak butuh DevOps senior untuk operasikan”. Saya sudah pakai ini di dua produk startup dan sejauh ini tidak ada keluhan berarti.

Setup awal Doppler:

# Install Doppler CLI
brew install dopplerhq/cli/doppler

# Login dan setup project
doppler login
doppler setup --project my-app --config production

Struktur Doppler: Project > Config (environment). Satu project bisa punya config dev, staging, production, bahkan production_us_east kalau perlu.

Inject secrets ke aplikasi lokal semudah ini:

# Jalankan app dengan secrets dari Doppler
doppler run -- node server.js

# Atau export sebagai env vars untuk proses lain
doppler secrets download --format env-no-quotes > .env.local

Untuk production di VPS, buat service token lalu pakai sebagai environment variable di systemd:

# /etc/systemd/system/myapp.service
[Service]
Environment=DOPPLER_TOKEN=dp.st.production.xxxxxxxxxxxx
ExecStart=/usr/bin/doppler run -- /opt/myapp/server

Untuk Kubernetes, pakai Doppler Operator:

# Install operator via Helm
helm repo add doppler https://helm.doppler.com
helm install --generate-name doppler/doppler-kubernetes-operator

# Buat DopplerSecret resource
kubectl apply -f - <<EOF
apiVersion: secrets.doppler.com/v1alpha1
kind: DopplerSecret
metadata:
  name: myapp-secrets
  namespace: production
spec:
  tokenSecret:
    name: doppler-token-secret
  managedSecret:
    name: myapp-env
    namespace: production
EOF

Setelah itu pod yang mount myapp-env Kubernetes Secret akan otomatis mendapat secrets terbaru setiap kali ada update di Doppler.

Yang saya suka dari Doppler:

  • UI yang bisa dipakai non-DevOps: developer bisa akses secrets mereka sendiri tanpa SSH ke server
  • Audit log: setiap akses tercatat siapa, kapan, dari mana
  • Sync ke platform lain: Doppler bisa push secrets ke GitHub Actions, Vercel, Railway, Render, Kubernetes — satu sumber kebenaran
  • Permission granular: dev hanya bisa akses config dev, bukan production

Batasnya: Doppler adalah third-party service. Kalau Doppler down, aplikasi Anda yang restart saat itu tidak akan bisa inject secrets. Doppler punya SLA 99.99% dan local fallback dengan cache, tapi ini tetap dependency eksternal. Untuk startup, ini trade-off yang acceptable. Untuk fintech dengan compliance ketat atau yang membutuhkan air-gap environment, ini perlu dipertimbangkan lebih serius.

Harga Doppler: free tier untuk tim kecil, Team plan mulai $9/user/bulan. Untuk tim 5 orang, ini $45/bulan — sangat reasonable dibanding biaya operasional Vault.

HashiCorp Vault: Power yang Ada Harganya

Vault adalah pilihan yang bisa melakukan hampir segalanya soal secrets management: dynamic secrets, PKI as a service, encryption as a service, audit log lengkap, auth method dari Kubernetes service account sampai AWS IAM. Saya pakai Vault di dua klien enterprise Jakarta, dan power-nya nyata.

Setup Vault dengan Raft HA (production-grade, minimal):

# vault-config.hcl
storage "raft" {
  path    = "/opt/vault/data"
  node_id = "vault-1"

  retry_join {
    leader_api_addr = "https://vault-2:8200"
  }
}

listener "tcp" {
  address       = "0.0.0.0:8200"
  tls_cert_file = "/opt/vault/tls/vault.crt"
  tls_key_file  = "/opt/vault/tls/vault.key"
}

api_addr     = "https://vault-1:8200"
cluster_addr = "https://vault-1:8201"
ui           = true

Dynamic secrets — ini fitur Vault yang tidak ada di Doppler atau GitHub Secrets. Vault bisa generate credential database yang valid selama N menit, lalu otomatis revoke:

# Enable database secrets engine
vault secrets enable database

# Konfigurasi koneksi ke Postgres
vault write database/config/my-postgres \
  plugin_name=postgresql-database-plugin \
  allowed_roles="app-role" \
  connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
  username="vault_admin" \
  password="vault_admin_pass"

# Buat role dengan TTL
vault write database/roles/app-role \
  db_name=my-postgres \
  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  default_ttl="1h" \
  max_ttl="24h"

Aplikasi yang request credential ke Vault dapat username/password unik yang expire dalam 1 jam. Kalau credential bocor, damage window terbatas.

Di Kubernetes, Vault Agent Injector meng-inject secrets langsung ke pod sebagai file:

# Pod annotation untuk Vault injection
metadata:
  annotations:
    vault.hashicorp.com/agent-inject: "true"
    vault.hashicorp.com/role: "my-app"
    vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
    vault.hashicorp.com/agent-inject-template-config: |
      {{- with secret "secret/data/myapp/config" -}}
      export DATABASE_URL="{{ .Data.data.database_url }}"
      export API_KEY="{{ .Data.data.api_key }}"
      {{- end }}

Ongkos operasional Vault yang sering underestimated:

  • Unseal process: setiap kali Vault restart, butuh unseal manual (atau auto-unseal via cloud KMS — tapi ini biaya tambahan)
  • Snapshot dan backup: Raft snapshot harus dijadwalkan, disimpan di tempat aman, dan ditest recovery-nya secara berkala
  • Upgrade: Vault upgrade bukan zero-downtime tanpa perencanaan — ada protocol rolling upgrade yang harus diikuti
  • Monitoring: Vault butuh monitoring khusus untuk seal status, token TTL, dan lease renewal

Saya pernah melihat startup yang install Vault, setup awal lancar, lalu tiga bulan kemudian tidak ada yang ingat cara unseal ketika server restart karena satu-satunya engineer yang setup sudah resign.

Perbandingan Langsung

DimensiGitHub SecretsDopplerHashiCorp Vault
Setup awal0 menit30 menit2-8 jam
Biaya bulanan (5 orang)Gratis~$45Self-host: biaya server + ops
Dynamic secretsTidakTidakYa
Audit logTerbatasYaYa, sangat detail
Third-party dependencyGitHubDopplerTidak (self-host)
Ops burdenSangat rendahRendahTinggi
Rotation automationManualSemi-otomatisFully otomatis
Cocok untukSolo/tim kecil, CI/CD onlyStartup hingga scale-upEnterprise, fintech, compliance

Verdict: Rekomendasi Berdasarkan Kondisi

Pakai GitHub Secrets kalau: tim Anda 1-3 orang, workflow deployment sepenuhnya lewat GitHub Actions, dan belum ada kebutuhan compliance. Ini bukan pilihan buruk — ini pilihan yang tepat untuk tahap tersebut.

Pakai Doppler kalau: tim mulai tumbuh (4-20 orang), ada lebih dari satu environment yang perlu dikelola, developer butuh akses ke secrets development mereka tanpa friction, dan Anda tidak punya kapasitas ops untuk mengelola Vault. Ini adalah rekomendasi default saya untuk startup yang belum punya dedicated DevOps engineer.

Pakai Vault kalau: ada compliance requirement yang spesifik (SOC2 Type II, PCI-DSS), butuh dynamic credentials untuk database, punya Kubernetes cluster yang perlu PKI internal, atau ada kebijakan bahwa secrets tidak boleh melewati third-party platform. Dan pastikan ada orang yang benar-benar paham cara operasikan Vault — bukan sekadar install dan berharap.

Satu hal yang sering saya tegaskan ke klien: tidak ada di antara ketiganya yang salah pilihan secara absolut. Yang salah adalah memilih tool yang complexity-nya melebihi kapasitas tim untuk operasikannya, karena pada akhirnya secrets yang “aman” di Vault yang tidak ada yang bisa maintain justru lebih berbahaya dari secrets yang dikelola rapi di Doppler.

Mulai dari yang paling sederhana yang cukup untuk kebutuhan saat ini, dan naik level ketika ada alasan konkret — bukan karena mengikuti arsitektur startup yang jauh lebih besar dari Anda.

Ditulis oleh Reza Pradipta