Contoh Keputusan
Lihat seperti apa keputusan arsitektur di MANTRA — format standar yang bisa dipahami AI dan ditegakkan secara otomatis.
Ini adalah contoh keputusan arsitektur nyata di MANTRA. Setiap keputusan mengikuti format 68 kolom yang memungkinkan AI assistant memahami, mencari, memeriksa kepatuhan, dan menegakkan aturan tim Anda secara otomatis.
Taksonomi 4×4
Gunakan PostgreSQL dengan Row-Level Security (RLS) untuk isolasi data multi-tenant di seluruh service backend
Tim backend mengalami 2 insiden kebocoran data antar tenant di Q4 2025 akibat filter tenant_id yang terlewat di level aplikasi. RLS memindahkan enforcement ke level database sehingga kebocoran tidak mungkin terjadi meskipun developer lupa menambahkan filter. Ini mengurangi cognitive load developer dan menghilangkan satu kelas bug secara permanen.
Semua tabel tenant wajib pakai RLS. Filter di level DB, bukan aplikasi. Menghilangkan risiko kebocoran data antar tenant.
Decision Drivers
Mengapa keputusan ini diperlukan
- 2 insiden kebocoran data antar tenant di Q4 2025
- Filter tenant_id di level aplikasi sering terlewat oleh developer
- Audit keamanan merekomendasikan defense-in-depth di level database
- Tim baru akan bergabung di Q1 2026 — butuh guardrail otomatis
Konsekuensi Positif
- +Kebocoran data antar tenant menjadi tidak mungkin secara teknis
- +Developer tidak perlu mengingat filter tenant_id di setiap query
- +Compliance audit lebih mudah — isolasi bisa dibuktikan di level DB
- +Onboarding developer baru lebih aman — tidak bisa salah secara tidak sengaja
Konsekuensi Negatif
- −Performa query berkurang ~2-5% karena overhead RLS policy evaluation
- −Migrasi existing tables membutuhkan downtime terencana
- −Debugging query menjadi lebih kompleks karena RLS tersembunyi
Alternatif yang Dipertimbangkan
Filter tenant_id di setiap query di level kode aplikasi. Sudah digunakan sebelumnya, tapi terbukti rawan human error.
Setiap tenant punya database sendiri. Isolasi sempurna tapi biaya operasional sangat tinggi untuk startup.
Setiap tenant punya schema sendiri dalam satu database. Lebih baik dari DB terpisah tapi masih sulit di-maintain.
Area yang Terpengaruh
Constraints
Aturan yang WAJIB dipatuhi — pelanggaran terdeteksi otomatis
Setiap tabel dengan data tenant WAJIB memiliki kolom tenant_id NOT NULL
CREATE TABLE orders (id uuid, tenant_id uuid NOT NULL, ...);
CREATE TABLE orders (id uuid, ...); -- tenant_id missing
Setiap tabel dengan tenant_id WAJIB memiliki RLS policy yang aktif
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON orders USING (tenant_id = current_setting('app.tenant_id')::uuid);-- Table has tenant_id but no RLS policy enabled
Raw SQL query DILARANG tanpa filter tenant_id eksplisit
SELECT * FROM orders WHERE tenant_id = $1 AND status = $2
SELECT * FROM orders WHERE status = 'active' -- no tenant_id filter
Cross-tenant JOIN DILARANG dalam satu query
SELECT o.* FROM orders o WHERE o.tenant_id = $1
SELECT a.*, b.* FROM tenant_a.orders a JOIN tenant_b.orders b ON ...
Invariants
Kondisi yang HARUS selalu benar di runtime
- I1 Tidak mungkin terjadi kebocoran data antar tenant melalui query database manapun
- I2 Kolom tenant_id tidak boleh NULL pada tabel yang memiliki RLS policy
- I3 RLS policy harus aktif di semua environment (development, staging, production)
Anti-Patterns
Pola yang secara eksplisit DILARANG
- X1 Menonaktifkan RLS untuk “mempercepat” query di production
- X2 Menggunakan superuser connection yang bypass RLS untuk API endpoints
- X3 Hardcode tenant_id di kode aplikasi alih-alih mengambil dari session context
Hasil Enforcement
Hasil pemeriksaan otomatis terhadap codebase berdasarkan constraints keputusan ini.
Kolom tenant_id ada (NOT NULL), RLS policy aktif
Baris 47: query SELECT tanpa filter tenant_id eksplisit
Semua query menggunakan tenant_id terparameterisasi
Tabel analytics_events: RLS policy belum diaktifkan
2 PASS, 1 WARNING, 1 FAIL — 1 pelanggaran kritis perlu segera diperbaiki.
Riwayat Versi
Setiap perubahan tercatat secara append-only — tidak ada yang bisa dihapus atau diubah diam-diam.
Keputusan awal: gunakan PostgreSQL RLS untuk isolasi multi-tenant
Tambah constraint C-004: larangan cross-tenant JOIN
Supersede v1.1.0: tambah invariant NOT NULL, anti-patterns, enforcement CI/CD, adoption status ENFORCING
Keputusan Terkait
Keputusan ini terhubung dengan keputusan lain dalam graf dependensi.
JWT authentication harus menyertakan tenant_id claim
RLS policy membaca tenant_id dari session variable yang di-set dari JWT claim
API rate limiting 1000 req/min per tenant
Rate limiting juga menggunakan tenant_id untuk isolasi kuota
Audit logging wajib untuk semua mutasi data
Audit log harus mencatat tenant_id untuk traceability