Security
Encryption model
Semua secret di-encrypt sebelum masuk database:
- Algorithm: AES-256-GCM (authenticated encryption)
- Key: 32-byte (256-bit), stored di
ENCRYPTION_KEYenv var — tidak di database - Nonce: 96-bit random, unik per-secret, regenerate tiap update
- Authentication tag: GCM built-in (16-byte), deteksi tampering
Code reference: internal/crypto/crypto.go (Go stdlib crypto/aes + crypto/cipher).
Password hashing
- Algorithm: bcrypt
- Cost: 12 (configurable via
BCRYPT_COST) - Cost 12 = ~250ms per hash di modern CPU → brute force resistant
Token hashing
Personal Access Token stored sebagai SHA-256 hash — tidak bisa di-decrypt:
Input: cvsm_abc123...DB: hash(cvsm_abc123...) = "e3b0c442..."Artinya: kalau DB bocor, attacker tidak punya token plain. Tapi kalau memori server/logs kena dump, ada risiko.
2FA / TOTP
- Standard: RFC 6238 (TOTP)
- Library:
github.com/pquerna/otp(Go) - Period: 30 detik, 6 digit
- Secret storage: encrypted dengan
ENCRYPTION_KEYsama seperti secret - Backup codes: planned v0.3
Transport
- HTTPS wajib di production (CVSM sendiri gak punya cert — gunakan nginx + Let’s Encrypt)
- HSTS header dikirim default
- Cookie
Secure+HttpOnly+SameSite=Strict
Threat model
Yang kami lindungi
✅ Database breach — secret tetap encrypted, attacker butuh ENCRYPTION_KEY juga
✅ Network eavesdrop — TLS end-to-end
✅ Brute force password — bcrypt + rate limit 10 req/min
✅ Session hijack — JWT short-lived (24 jam) + sessions_invalidated_at
✅ Token leak di log — token hashed, scanning pattern cvsm_ di GitHub
✅ CSRF — SameSite cookie + OAuth state nonce
Yang tidak kami lindungi
❌ Compromised server — kalau root akses ke VPS, ENCRYPTION_KEY + DB sama-sama accessible
❌ Malicious insider — owner/admin bisa read semua secret team-nya (audit log cuma deteksi, bukan prevent)
❌ Supply chain (NPM/PyPI) — dependency kompromise akan bypass SDK auth
❌ Client-side leak — kalau aplikasi kamu log process.env ke external service, bukan tanggung jawab CVSM
❌ End-to-end encryption ke user — value dikirim plaintext ke server, server decrypt dengan key-nya sendiri sebelum return. E2EE true (kunci di client) coming v0.3+
Secret lifecycle
- Create:
POST /secretsdengan value plaintext → server encrypt → store ciphertext - Read: SDK call
GET /secrets/export→ server decrypt → return plaintext via TLS - Update: value baru encrypted; versi lama disimpan di
secret_versions(juga encrypted) - Delete: soft delete (
deleted_atset), data tidak ter-erase — butuh admin DB operation - Export: sama dengan read tapi multi-secret, semua ter-audit log
Disclosure policy
Bug kecil (UI, non-sensitive)
- GitHub issue publik: github.com/RenzyArmstrong/Calvery-Vault/issues
Security vulnerability
- Jangan buka public issue
- Email: [email protected] (GPG key planned)
- Setiap laporan valid akan kami respons serius, investigasi, dan patch secepat mungkin — lihat SLA di bawah
Response timeline (SLA indie)
- Ack: 48 jam
- Triage: 7 hari
- Patch deploy (critical): 14 hari
- Public disclosure: 90 hari setelah patch (atau segera kalau sudah di-exploit in the wild)
Audit & compliance (planned)
- ✅ GDPR — data di Singapore region, DPA tersedia (v0.2)
- ⏳ SOC 2 Type 1 — planned 2026 Q3, via Vanta
- ⏳ ISO 27001 — planned 2027
- ⏳ OJK compliance — planned via on-premise tier
Transparency report
Published quarterly di calvery.xyz/security:
- Jumlah government data request (IND + asing)
- Ringkasan laporan keamanan yang sudah di-patch (anonymous / consent reporter)
- Incident postmortems (kalau ada)
Responsible disclosure hall of fame
Researchers yang disclose bug valid dapat:
- Mention di hall of fame (consent dulu)
- Credit di CHANGELOG & security advisory
- Komunikasi terbuka selama investigasi + perbaikan
Calvery saat ini belum punya program bounty berbayar. Fokus kami membangun produk dulu — program apresiasi finansial akan hadir setelah layanan stabil dan menghasilkan revenue. Sampai saat itu, kontribusi kamu murni semangat bikin software lebih aman, dan itu yang paling kami hargai.
(List kosong untuk sekarang — jadilah yang pertama!)