Langsung ke konten
M
MANTRA

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

INT — Intent & Arah
A01 Visi & Hasil
A02 Pernyataan Masalah
A03 Lingkup & Non-Goals
A04 Prinsip & Nilai
ARCH — Arsitektur & Batas
A05 Domain & Bounded Context
A06 Service & Module Boundary INI
A07 Kepemilikan Data
A08 Integrasi & Kontrak
CTL — Kontrol, Kebijakan & Risiko
A09 Kebijakan & Aturan
A10 Persetujuan & Otoritas
A11 Keamanan & Kepatuhan
A12 Risiko & Blast Radius
EVO — Eksekusi & Evolusi
A13 Siklus Hidup Keputusan
A14 Reversibilitas & Exit
A15 Environment & Promosi
A16 Anti-Drift & Konsistensi
ARCH-A06-APP-DEC-001 v2.0.0 Aktif ENFORCING DECISION
Pernyataan

Gunakan PostgreSQL dengan Row-Level Security (RLS) untuk isolasi data multi-tenant di seluruh service backend

Alasan

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.

Ringkasan

Semua tabel tenant wajib pakai RLS. Filter di level DB, bukan aplikasi. Menghilangkan risiko kebocoran data antar tenant.

Domain
ARCH — Architecture & Boundaries
Aspect
A06 — Service & Module Boundary
Scope
APPLICATION
Blast Radius
HIGH
Tipe
DECISION
Tipe Perubahan
REPLACEMENT
Dibuat oleh
Ahmad Rizki (Tech Lead)
Disetujui oleh
Budi Santoso (CTO)
Tag SECURITYDATABASEMULTI_TENANCYRLSPOSTGRESQL
Tech Stack PostgreSQL 16pgx v5Bun.sql
Berlaku untuk backend/**/*.tsdatabase/migrations/**/*.sql

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

Application-level filtering REJECTED

Filter tenant_id di setiap query di level kode aplikasi. Sudah digunakan sebelumnya, tapi terbukti rawan human error.

Separate database per tenant REJECTED

Setiap tenant punya database sendiri. Isolasi sempurna tapi biaya operasional sangat tinggi untuk startup.

Schema-per-tenant DEFERRED

Setiap tenant punya schema sendiri dalam satu database. Lebih baik dari DB terpisah tapi masih sulit di-maintain.

Area yang Terpengaruh

Backend
Semua repository layerQuery builderMigration scripts
Database
Semua tabel dengan data tenantRLS policiesConnection pooling
DevOps
Migration pipelineDatabase backup strategy

Constraints

Aturan yang WAJIB dipatuhi — pelanggaran terdeteksi otomatis

C-001 REQUIREMENT BLOCKING SCHEMA

Setiap tabel dengan data tenant WAJIB memiliki kolom tenant_id NOT NULL

Contoh benar
CREATE TABLE orders (id uuid, tenant_id uuid NOT NULL, ...);
Contoh salah
CREATE TABLE orders (id uuid, ...);  -- tenant_id missing
C-002 REQUIREMENT BLOCKING SCHEMA

Setiap tabel dengan tenant_id WAJIB memiliki RLS policy yang aktif

Contoh benar
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON orders USING (tenant_id = current_setting('app.tenant_id')::uuid);
Contoh salah
-- Table has tenant_id but no RLS policy enabled
C-003 PROHIBITION BLOCKING REGEX

Raw SQL query DILARANG tanpa filter tenant_id eksplisit

Contoh benar
SELECT * FROM orders WHERE tenant_id = $1 AND status = $2
Contoh salah
SELECT * FROM orders WHERE status = 'active'  -- no tenant_id filter
C-004 PROHIBITION WARNING REGEX

Cross-tenant JOIN DILARANG dalam satu query

Contoh benar
SELECT o.* FROM orders o WHERE o.tenant_id = $1
Contoh salah
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.

PASS
src/database/migrations/042_users.sql
C-001, C-002

Kolom tenant_id ada (NOT NULL), RLS policy aktif

WARNING
src/api/services/user-service.ts
C-003

Baris 47: query SELECT tanpa filter tenant_id eksplisit

PASS
src/api/routes/admin.ts
C-001, C-003

Semua query menggunakan tenant_id terparameterisasi

FAIL
src/database/migrations/051_analytics.sql
C-002

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.

1.0.0 INITIAL 2026-01-15 — Ahmad Rizki

Keputusan awal: gunakan PostgreSQL RLS untuk isolasi multi-tenant

1.1.0 EXTENSION 2026-02-20 — Ahmad Rizki

Tambah constraint C-004: larangan cross-tenant JOIN

2.0.0 REPLACEMENT 2026-03-10 — Dewi Putri

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.

ARCH-A08-APP-DEC-003 DEPENDS_ON STRONG

JWT authentication harus menyertakan tenant_id claim

RLS policy membaca tenant_id dari session variable yang di-set dari JWT claim

CTL-A09-APP-DEC-001 RELATED_TO NORMAL

API rate limiting 1000 req/min per tenant

Rate limiting juga menggunakan tenant_id untuk isolasi kuota

CTL-A11-ORG-LAW-001 RELATED_TO NORMAL

Audit logging wajib untuk semua mutasi data

Audit log harus mencatat tenant_id untuk traceability

Buat keputusan pertama Anda

Gratis untuk 3 anggota dan 25 keputusan.