8 menit

Bagaimana Database Multi-Tenant Mempengaruhi Keamanan dan Kinerja

Pelajari bagaimana database multi-tenant memengaruhi keamanan dan kinerja, risiko utama (isolasi, noisy neighbors), dan kontrol praktis untuk menjaga tenant aman dan cepat.

Bagaimana Database Multi-Tenant Mempengaruhi Keamanan dan Kinerja

Apa Arti Basis Data Multi-Tenant

Sebuah basis data multi-tenant adalah pengaturan di mana banyak pelanggan (tenant) berbagi sistem basis data yang sama—server basis data yang sama, penyimpanan dasar yang sama, dan seringkali skema yang sama—sementara aplikasi memastikan setiap tenant hanya dapat mengakses data mereka sendiri.

Bayangkan seperti sebuah gedung apartemen: semua orang berbagi struktur dan utilitas gedung, tetapi setiap tenant memiliki unit terkunci sendiri.

Multi-tenant vs. single-tenant (secara garis besar)

Dalam pendekatan single-tenant, setiap pelanggan mendapat sumber daya basis data khusus—misalnya, instance basis data sendiri atau server sendiri. Isolasi lebih mudah dipahami, tetapi biasanya lebih mahal dan operasionalnya berat saat jumlah pelanggan bertambah.

Dengan multi-tenancy, tenant berbagi infrastruktur, yang bisa efisien—tetapi juga berarti desain Anda harus dengan sengaja menegakkan batas-batas.

Mengapa tim SaaS memilih multi-tenancy

Perusahaan SaaS sering memilih multi-tenancy karena alasan praktis:

  • Biaya per pelanggan lebih rendah (komputasi, penyimpanan, lisensi, dan waktu operasi bersama)
  • Operasi lebih sederhana pada skala, seperti lebih sedikit basis data untuk dipatch, di-upgrade, dan dimonitor
  • Onboarding lebih cepat untuk pelanggan baru (tidak perlu menyediakan seluruh tumpukan basis data baru)

Ekspektasi kunci: desain menentukan hasil

Multi-tenancy sendiri tidak otomatis “aman” atau “cepat.” Hasil bergantung pada pilihan seperti bagaimana tenant dipisahkan (skema, baris, atau database), bagaimana kontrol akses ditegakkan, bagaimana kunci enkripsi ditangani, dan bagaimana sistem mencegah beban satu tenant memperlambat tenant lain.

Sisa panduan ini fokus pada pilihan desain tersebut—karena dalam sistem multi-tenant, keamanan dan kinerja adalah fitur yang Anda bangun, bukan asumsi yang Anda warisi.

Model-Model Umum Basis Data Multi-Tenant

Multi-tenancy bukan satu pilihan desain—itu spektrum seberapa ketat Anda berbagi infrastruktur. Model yang Anda pilih menentukan batas isolasi (apa yang tak boleh dibagi), dan itu langsung memengaruhi keamanan basis data, isolasi kinerja, dan operasi harian.

Database-per-tenant

Setiap tenant mendapat basis data sendiri (sering di server atau cluster yang sama).

Batas isolasi: basis data itu sendiri. Ini biasanya cerita isolasi tenant yang paling bersih karena akses lintas-tenant biasanya memerlukan melintasi batas database.

Pertukaran operasional: lebih berat dioperasikan pada skala. Upgrade dan migrasi skema mungkin harus dijalankan ribuan kali, dan pooling koneksi bisa menjadi rumit. Backup/restore mudah pada level tenant, tetapi overhead penyimpanan dan manajemen dapat tumbuh cepat.

Keamanan & tuning: umumnya paling mudah diamankan dan disetel per pelanggan, dan cocok kuat saat tenant punya kebutuhan kepatuhan berbeda.

Schema-per-tenant

Tenant berbagi satu database, tetapi setiap tenant memiliki skema sendiri.

Batas isolasi: skema. Pemisahan yang berarti, tetapi bergantung pada permission dan tooling yang benar.

Pertukaran operasional: upgrade dan migrasi masih berulang, tapi lebih ringan daripada database-per-tenant. Backup lebih rumit: banyak alat menganggap database sebagai unit backup, jadi operasi level tenant mungkin memerlukan ekspor skema.

Keamanan & tuning: lebih mudah menegakkan isolasi dibandingkan tabel bersama, tetapi Anda harus disiplin tentang privilege dan memastikan query tidak pernah mereferensikan skema yang salah.

Table-per-tenant

Semua tenant berbagi database dan skema, tetapi setiap tenant memiliki tabel terpisah (mis. orders_tenant123).

Batas isolasi: set tabel. Bisa bekerja untuk sejumlah kecil tenant, tetapi skala buruk: bloat metadata, skrip migrasi menjadi tak tertahankan, dan perencanaan query bisa menurun.

Keamanan & tuning: izin bisa sangat presisi, namun kompleksitas operasi tinggi, dan mudah membuat kesalahan saat menambah tabel atau fitur baru.

Shared-table (skema bersama)

Semua tenant berbagi tabel yang sama, dibedakan dengan kolom tenant_id.

Batas isolasi: lapisan query dan kontrol akses Anda (umumnya row-level security). Model ini efisien operasional—satu skema untuk migrasi, satu strategi indeks untuk dikelola—tetapi paling menuntut untuk keamanan basis data dan isolasi kinerja.

Keamanan & tuning: paling sulit dilakukan dengan benar karena setiap query harus sadar tenant, dan masalah noisy neighbor lebih mungkin kecuali Anda menambahkan pembatas sumber daya dan indeks yang hati-hati.

Aturan berguna: semakin banyak Anda berbagi, semakin sederhana upgrade menjadi—tetapi semakin besar disiplin yang Anda butuhkan dalam kontrol isolasi tenant dan isolasi kinerja.

Bagaimana Multi-Tenancy Mengubah Model Ancaman Keamanan

Multi-tenancy bukan hanya berarti “banyak pelanggan di satu basis data.” Ia mengubah threat model Anda: risiko terbesar bergeser dari orang luar yang meretas menjadi pengguna yang diotorisasi secara tidak sengaja (atau sengaja) melihat data tenant lain.

Otentikasi vs otorisasi: konteks tenant adalah keputusan otorisasi

Otentikasi menjawab “siapa Anda?” Otorisasi menjawab “apa yang boleh Anda akses?” Dalam basis data multi-tenant, konteks tenant (tenant_id, account_id, org_id) harus ditegakkan saat otorisasi—tidak diperlakukan sebagai filter opsional.

Kesalahan umum adalah menganggap bahwa setelah pengguna diautentikasi dan Anda “tahu” tenant-nya, aplikasi akan secara alami menjaga query terpisah. Kenyataannya, pemisahan harus eksplisit dan ditegakkan pada titik kontrol yang konsisten (mis. kebijakan basis data atau lapisan query wajib).

Aturan inti: setiap baca dan tulis harus bertujuan untuk satu tenant

Aturan paling sederhana juga yang paling penting: setiap operasi baca dan tulis harus dibatasi untuk tepat satu tenant.

Itu berlaku untuk:

  • SELECT (termasuk halaman daftar dan ekspor)
  • UPDATE/DELETE
  • Pekerjaan background dan skrip ETL
  • Tooling admin dan alur kerja dukungan

Jika scoping tenant bersifat opsional, pada akhirnya akan terlewat.

Mode kegagalan umum yang menyebabkan akses lintas-tenant

Kebocoran lintas-tenant sering datang dari kesalahan kecil, rutin:

  • Filter tenant yang hilang di satu endpoint atau jalur kode
  • Join “rusak” di mana satu tabel diberi scope tetapi tabel yang dijoin tidak
  • Respons yang di-cache dengan kunci hanya oleh user atau URL, bukan oleh tenant
  • Prepared statement yang digunakan ulang yang secara tidak sengaja mengikat tenant_id yang salah

Mengapa “berhasil di tes” masih bisa bocor di produksi

Tes biasanya berjalan dengan dataset kecil dan asumsi bersih. Produksi menambahkan konkurensi, retry, cache, data tenant campur, dan edge case nyata.

Fitur bisa lolos tes karena hanya ada satu tenant di basis data tes, atau fixture tidak menyertakan ID yang tumpang tindih antar-tenant. Desain paling aman membuatnya sulit menulis query tanpa scope sama sekali, alih-alih bergantung pada reviewer untuk menangkapnya setiap kali.

Kontrol Isolasi yang Mencegah Akses Lintas-Tenant

Risiko keamanan inti di basis data multi-tenant sederhana: query yang lupa memfilter berdasarkan tenant bisa mengekspos data tenant lain. Kontrol isolasi yang kuat mengasumsikan kesalahan akan terjadi dan membuat kesalahan tersebut tidak berbahaya.

Identifier tenant dan pola scoping yang ketat

Setiap record milik tenant harus membawa identifier tenant (misalnya, tenant_id) dan lapisan akses Anda harus selalu melakukan scoping baca dan tulis berdasarkan itu.

Pola praktis adalah “konteks tenant dulu”: aplikasi menyelesaikan tenant (dari subdomain, org ID, atau klaim token), menyimpannya di konteks permintaan, dan kode akses data menolak berjalan tanpa konteks itu.

Guardrail yang membantu:

  • Meminta tenant_id dalam primary/unique key di mana cocok (untuk mencegah tabrakan antar-tenant).
  • Menambahkan foreign key yang menyertakan tenant_id sehingga relasi lintas-tenant tidak dapat dibuat secara tidak sengaja.

Row-level security (RLS) dan akses berbasis kebijakan

Jika didukung (terutama PostgreSQL), row-level security dapat memindahkan pengecekan tenant ke dalam basis data. Kebijakan dapat membatasi setiap SELECT/UPDATE/DELETE sehingga hanya baris yang cocok dengan tenant saat ini yang terlihat.

Ini mengurangi ketergantungan pada “setiap developer mengingat klausa WHERE,” dan juga dapat melindungi terhadap beberapa skenario injeksi atau penyalahgunaan ORM. Anggap RLS sebagai kunci kedua, bukan satu-satunya.

Pemisahan skema/database sebagai alat isolasi

Jika tenant memiliki sensitivitas lebih tinggi atau kebutuhan kepatuhan lebih ketat, memisahkan tenant berdasarkan skema (atau bahkan database) dapat mengurangi blast radius. Tradeoff-nya adalah overhead operasional yang meningkat.

Default aman: deny-by-default dan least privilege

Rancang izin sehingga default adalah “tidak ada akses”:

  • Peran aplikasi harus hanya memiliki akses tabel minimum yang diperlukan.
  • Alur kerja admin harus menggunakan akun terpisah dan elevasi yang diaudit.
  • Hindari koneksi “superuser” bersama di kode aplikasi.

Kontrol ini bekerja paling baik bersama: scoping tenant yang kuat, kebijakan yang ditegakkan basis data bila mungkin, dan hak akses konservatif yang membatasi kerusakan saat sesuatu terlewat.

Enkripsi dan Manajemen Kunci di Penyimpanan Bersama

Enkripsi adalah salah satu kontrol yang masih membantu bahkan ketika lapisan isolasi lain gagal. Di datastore bersama, tujuannya adalah melindungi data saat bergerak, saat diam, dan saat aplikasi membuktikan tenant mana yang sedang diwakili.

Mengenkripsi data dalam transit dan saat disimpan

Untuk data dalam transit, wajibkan TLS untuk setiap hop: klien → API, API → basis data, dan panggilan layanan internal apa pun. Tegakkan di level basis data bila memungkinkan (misalnya menolak koneksi non-TLS) sehingga “pengecualian sementara” tidak diam-diam menjadi permanen.

Untuk data at rest, gunakan enkripsi tingkat basis data atau penyimpanan (managed disk encryption, TDE, backup terenkripsi). Ini melindungi terhadap media yang hilang, eksposur snapshot, dan beberapa kelas kompromi infrastruktur—tetapi tidak akan menghentikan query buggy mengembalikan baris milik tenant lain.

Kunci bersama vs kunci per-tenant

Satu kunci enkripsi bersama lebih sederhana dioperasikan (lebih sedikit kunci untuk diputar, lebih sedikit mode kegagalan). Kekurangannya adalah blast radius: jika kunci itu terekspos, semua tenant terekspos.

Kunci per-tenant mengurangi blast radius dan dapat membantu memenuhi kebutuhan pelanggan (beberapa enterprise ingin kontrol kunci per-tenant). Tradeoff-nya adalah kompleksitas: manajemen lifecycle kunci, jadwal rotasi, dan alur dukungan (mis. apa yang terjadi jika tenant menonaktifkan kuncinya).

Solusi praktis adalah envelope encryption: kunci master mengenkripsi kunci data per-tenant, menjaga rotasi tetap terkelola.

Manajemen rahasia untuk kredensial basis data

Simpan kredensial basis data di secrets manager, bukan variabel lingkungan dalam konfigurasi yang berumur panjang. Pilih kredensial sementara atau rotasi otomatis, dan scope akses berdasarkan peran layanan sehingga kompromi di satu komponen tidak otomatis mencapai setiap basis data.

Penanganan token dan sesi: mencegah pemalsuan konteks tenant

Perlakukan identitas tenant sebagai kritis-keamanan. Jangan pernah menerima tenant_id mentah dari klien sebagai “kebenaran.” Ikat konteks tenant ke token yang ditandatangani dan pemeriksaan sisi server, dan validasi pada setiap permintaan sebelum panggilan basis data apa pun.

Audit, Monitoring, dan Kesiapan Insiden

Uji Isolasi Lebih Awal
Buat tes negatif yang mencoba baca/tulis lintas-tenant dan cegah perubahan berisiko.

Multi-tenancy mengubah apa yang terlihat sebagai “normal”. Anda tidak hanya mengawasi satu basis data—Anda mengawasi banyak tenant yang berbagi sistem yang sama, di mana satu kesalahan bisa menjadi eksposur lintas-tenant. Audit dan monitoring yang baik mengurangi kemungkinan dan blast radius insiden.

Audit log: catat cerita lengkap

Minimal, log setiap tindakan yang dapat membaca, mengubah, atau memberi akses ke data tenant. Peristiwa audit paling berguna menjawab:

  • Siapa: identitas user/service, metode auth, peran, IP/device sumber
  • Apa: operasi (SELECT/UPDATE/DELETE), objek yang terpengaruh, kelas query (tidak harus SQL penuh), before/after untuk perubahan bernilai privilese
  • Kapan: timestamp dengan timezone, request/trace ID untuk korelasi
  • Tenant: tenant ID sebagai field kelas satu (jangan diinfer kemudian)

Juga catat tindakan administratif: pembuatan tenant, perubahan kebijakan isolasi, modifikasi row-level security, rotasi kunci, dan perubahan connection string.

Alerting untuk anomali lintas-tenant dan privilese

Monitoring harus mendeteksi pola yang tidak lazim dalam penggunaan SaaS yang sehat:

  • Query yang mengembalikan baris untuk banyak tenant ID, atau lonjakan mendadak pada penolakan "tenant mismatch"
  • Akses dari akun service ke tenant yang biasanya tidak disentuhnya
  • Perubahan cepat peran/izin, admin baru, kebijakan keamanan yang dinonaktifkan, atau upaya bypass RLS

Hubungkan alert ke runbook yang dapat ditindaklanjuti: apa yang diperiksa, bagaimana menahan dampak, dan siapa yang dihubungi.

Kontrol admin dan prosedur break-glass

Perlakukan akses privilese seperti perubahan produksi. Gunakan peran least-privilege, kredensial berumur pendek, dan persetujuan untuk operasi sensitif (perubahan skema, ekspor data, edit kebijakan). Untuk keadaan darurat, simpan akun break-glass yang sangat dikontrol: kredensial terpisah, tiket/izin wajib, akses berbatas waktu, dan logging ekstra.

Retensi dan akses log yang di-scope per-tenant

Atur retensi berdasarkan kebutuhan kepatuhan dan investigasi, tetapi scope akses agar staf dukungan hanya dapat melihat log untuk tenant mereka. Ketika pelanggan meminta ekspor audit, berikan laporan yang sudah difilter per-tenant alih-alih log mentah bersama.

Dasar-Dasar Kinerja dan Masalah Noisy Neighbor

Multi-tenancy meningkatkan efisiensi dengan membiarkan banyak pelanggan berbagi infrastruktur basis data yang sama. Tradeoff-nya adalah kinerja menjadi pengalaman bersama juga: apa yang dilakukan satu tenant dapat memengaruhi tenant lain, bahkan jika datanya sepenuhnya terisolasi.

Masalah “noisy neighbor” (dengan bahasa sederhana)

"Noisy neighbor" adalah tenant yang aktivitasnya begitu berat (atau berdentum) sehingga mengonsumsi sumber daya bersama lebih dari bagian yang adil. Basis data tidak “rusak”—hanya sibuk menangani beban kerja tenant itu, sehingga tenant lain menunggu lebih lama.

Bayangkan seperti gedung apartemen dengan tekanan air bersama: satu unit menyalakan banyak shower dan mesin cuci sekaligus, dan semua orang lain merasakan aliran yang melemah.

Apa yang sebenarnya dibagi?

Bahkan ketika tiap tenant memiliki baris atau skema terpisah, banyak komponen kritis kinerja tetap dibagi:

  • CPU: eksekusi query, pengurutan, join, enkripsi/dekripsi, pemeliharaan latar
  • Memori: halaman buffer/cache, working memory query, antrean internal
  • Disk / I/O: membaca file data, menulis log, flush checkpoint, kompak/vacuum
  • Koneksi: batas koneksi basis data dan thread pool
  • Cache: plan cache, buffer cache, dan kadang cache sisi aplikasi yang memberi beban ke basis data

Saat pool bersama ini jenuh, latensi naik untuk semua orang.

Mengapa beban mendadak (bursty) merugikan tenant lain

Banyak beban kerja SaaS datang secara burst: impor, laporan akhir bulan, kampanye pemasaran, cron job yang berjalan di awal jam.

Burst dapat menciptakan "kemacetan" di dalam basis data:

  • Satu tenant menjalankan banyak query mahal sekaligus, mendorong CPU ke 100%.
  • Tulisan besar memicu I/O ekstra (penulisan log, pemeliharaan indeks), memperlambat baca untuk lainnya.
  • Lonjakan koneksi memenuhi pool, sehingga tenant lain tidak cepat mendapat slot.

Bahkan jika burst hanya berlangsung beberapa menit, ia dapat menyebabkan delay knock-on saat antrean mengosongkan.

Apa yang biasanya dirasakan pengguna

Dari perspektif pelanggan, masalah noisy-neighbor terasa acak dan tidak adil. Gejalanya meliputi:

  • Timeout saat login, pencarian, checkout, atau pembuatan laporan
  • Halaman lambat yang sebelumnya cepat, terutama tampilan daftar dan dashboard
  • Kecepatan yang tidak konsisten (cepat pada 10:05, lambat pada 10:10, cepat lagi pada 10:20)
  • Pekerjaan background tertunda (ekspor memakan waktu lebih lama, webhook tertunda)

Gejala ini adalah tanda awal bahwa Anda perlu teknik isolasi kinerja, bukan hanya "lebih banyak hardware."

Teknik Isolasi Sumber Daya dan Throttling

Sesuaikan Stack SaaS Anda
Hasilkan frontend React dan backend Go dengan PostgreSQL agar sesuai stack produksi yang diinginkan.

Multi-tenancy bekerja paling baik ketika satu pelanggan tidak bisa "meminjam" lebih dari bagian yang adil dari kapasitas basis data. Isolasi sumber daya adalah serangkaian guardrail yang menjaga agar tenant berat tidak memperlambat semua orang.

Batas pooling koneksi dan kuota per-tenant

Mode kegagalan umum adalah koneksi tak terbatas: lonjakan lalu lintas satu tenant membuka ratusan sesi dan membuat basis data kelaparan. Tetapkan batas keras di dua tempat:

  • Di pool aplikasi: batasi max connections per instance layanan dan sisakan minimum untuk pekerjaan background.
  • Per tenant: terapkan kuota seperti “N permintaan konkuren” atau “M sesi DB konkuren” yang dipetakan dari paket tenant.

Bahkan jika basis data Anda tidak dapat menegakkan "koneksi per tenant" langsung, Anda bisa memperkirakannya dengan merutekan setiap tenant melalui pool khusus atau partisi pool.

Rate limiting dan shaping beban (app + DB)

Rate limiting tentang keadilan sepanjang waktu. Terapkan di tepi (API gateway/app) dan, bila didukung, di dalam basis data (resource groups/workload management).

Contoh:

  • Token-bucket per-tenant pada endpoint mahal (ekspor, pencarian)
  • Tier prioritas sehingga permintaan interaktif menang atas batch
  • Shaping berbasis antrean untuk meratakan burst daripada mendorongnya langsung ke DB

Timeout query, batas per-statement, dan circuit breaker

Lindungi DB dari query yang "lari":

  • Timeout query/statement untuk menghentikan full scan panjang
  • Batas maksimum baris/byte untuk endpoint yang bisa meledak ukuran hasilnya
  • Circuit breaker yang sementara memblokir fitur mahal tenant saat error rate atau latensi melewati ambang

Kontrol ini harus gagal dengan anggun: kembalikan error yang jelas dan sarankan retry/backoff.

Replica baca dan caching untuk mengurangi kontensi

Pindahkan trafik baca yang berat dari primary:

  • Read replica untuk dashboard, laporan, dan query bergaya analytics
  • Caching (kunci per-tenant, TTL pendek) untuk lookup berulang dan data konfigurasi

Tujuannya bukan hanya kecepatan—tetapi mengurangi tekanan lock dan kontensi CPU sehingga tenant bising punya lebih sedikit cara memengaruhi lainnya.

Pilihan Pemodelan Data yang Mempengaruhi Kecepatan

Masalah kinerja multi-tenant sering terlihat seperti "basis data lambat", tetapi akar masalah biasanya model data: bagaimana data tenant di-key, difilter, diindeks, dan ditata secara fisik. Pemodelan yang baik membuat query bertujuan tenant jadi cepat; pemodelan buruk memaksa DB bekerja terlalu keras.

Pengindeksan untuk query bertujuan tenant

Sebagian besar query SaaS harus menyertakan identifier tenant. Modelkan itu secara eksplisit (mis. tenant_id) dan rancang indeks yang dimulai darinya. Praktik umum: indeks komposit seperti (tenant_id, created_at) atau (tenant_id, status) jauh lebih berguna daripada mengindeks created_at atau status saja.

Ini juga berlaku untuk unik: jika email hanya unik per-tenant, tegakkan dengan (tenant_id, email) daripada constraint global email.

Hindari full-table scan (filter tenant yang hilang)

Polanya query lambat yang umum adalah scan lintas-tenant tak sengaja: query lupa filter tenant dan menyentuh bagian besar tabel.

Buat jalur aman menjadi mudah:

  • Wajibkan filter tenant di lapisan query (scope ORM, metode repository)
  • Gunakan proteksi basis data bila tersedia (mis. view default tenant atau kebijakan) sehingga akses tanpa scope gagal dengan cepat

Partitioning dan sharding: berdasarkan tenant atau waktu

Partitioning dapat mengurangi jumlah data yang harus dipertimbangkan tiap query. Partisi berdasarkan tenant ketika tenant besar dan tidak merata. Partisi berdasarkan waktu ketika akses sebagian besar ke data terbaru (events, log, invoice), sering dengan tenant_id sebagai kolom indeks terdepan di tiap partisi.

Pertimbangkan sharding ketika satu basis data tidak dapat memenuhi throughput puncak, atau ketika beban satu tenant mengancam semua orang.

Mengelola tenant "hot"

"Hot tenants" muncul sebagai volume baca/tulis yang tidak proporsional, kontensi lock, atau indeks yang terlalu besar.

Deteksi dengan melacak waktu query per-tenant, baris yang dibaca, dan laju tulis. Ketika satu tenant dominan, isolasi mereka: pindah ke shard/database terpisah, bagi tabel besar berdasarkan tenant, atau perkenalkan cache dedikasi dan rate limit sehingga tenant lain tetap cepat.

Praktik Operasional yang Melindungi Keamanan dan Kinerja

Multi-tenancy jarang gagal karena basis data "tidak mampu". Ia gagal ketika operasi harian memungkinkan inkonsistensi kecil berkembang menjadi celah keamanan atau regresi kinerja. Tujuannya adalah membuat jalur aman menjadi default untuk setiap perubahan, job, dan deploy.

Standarkan kunci tenant (dan tegakkan di mana-mana)

Pilih identifier tenant tunggal, kanonik (mis., tenant_id) dan gunakan secara konsisten di seluruh tabel, indeks, log, dan API. Konsistensi mengurangi kesalahan keamanan (mengquery tenant yang salah) dan kejutan kinerja (hilangnya indeks komposit yang tepat).

Pengaman praktis:

  • Wajibkan tenant_id di semua jalur akses utama (query, repository, scope ORM)
  • Tambahkan indeks komposit yang dimulai dengan tenant_id untuk lookup umum
  • Lebih suka constraint basis data bila memungkinkan (foreign key yang menyertakan tenant_id, atau check constraint) untuk menangkap penulisan buruk lebih awal

Cegah campur tenant di pekerjaan background

Worker async sering menjadi sumber insiden lintas-tenant karena berjalan "di luar band" dari permintaan yang menetapkan konteks tenant.

Polap operasi yang membantu:

  • Sertakan tenant_id secara eksplisit di setiap payload job; jangan andalkan konteks ambient
  • Sertakan kunci tenant di idempotency key dan cache key
  • Log tenant_id pada mulai/selesai job dan pada setiap retry agar investigasi cepat mensekali dampak

Buat migrasi aman-tenant saat desain

Migrasi skema dan data harus dapat dideploy tanpa rollout yang sempurna dan sinkron.

Gunakan perubahan bertahap:

  • Strategi expand/contract (tambahkan kolom/indeks baru, dual-write/read, lalu hapus jalur lama)
  • Hindari operasi blocking panjang; backfill batch per tenant untuk mengendalikan beban
  • Pastikan setiap query backfill memiliki scope tenant dan dibatasi kecepatannya untuk mencegah efek noisy-neighbor yang dibuat sendiri

Uji kegagalan isolasi—bukan hanya skenario bahagia

Tambahkan tes negatif otomatis yang sengaja mencoba mengakses data tenant lain (baca dan tulis). Perlakukan ini sebagai penghalang rilis.

Contoh:

  • Coba ambil record yang diketahui milik Tenant A saat diautentikasi sebagai Tenant B
  • Jalankan tes job background dengan tenant_id mismatched dan verifikasi kegagalan keras
  • Tes regresi untuk setiap helper query guna memastikan scoping tenant selalu diterapkan

Backup, Restore, dan Operasi Data Level-Tenant

Pertahankan Kepemilikan Penuh
Mulai cepat di Koder.ai, lalu ekspor kode sumber saat saatnya mengamankan.

Backup mudah dijelaskan ("copy the database") dan mengejutkan sulit dijalankan aman di multi-tenant. Saat banyak pelanggan berbagi tabel, Anda perlu rencana bagaimana memulihkan satu tenant tanpa mengekspos atau menimpa tenant lain.

Strategi backup/restore: satu tenant vs semua

Backup full-database tetap dasar untuk pemulihan bencana, tetapi tidak cukup untuk kasus dukungan sehari-hari. Pendekatan umum:

  • Full backups + point-in-time recovery untuk insiden yang memengaruhi "semua" (korupsi, outage region)
  • Ekspor terfokus tenant (dump logis difilter oleh tenant_id) untuk merestore data satu tenant
  • Penyimpanan terpisah per-tenant (jika memungkinkan) agar restore secara natural berbatas tenant

Jika mengandalkan ekspor logis, perlakukan job ekspor seperti kode produksi: harus menegakkan isolasi tenant (mis. via RLS) daripada hanya mengandalkan klausa WHERE yang ditulis sekali lalu dilupakan.

Ekspor/hapus level-tenant (permintaan privasi)

Permintaan privasi (ekspor, hapus) adalah operasi level-tenant yang menyentuh keamanan dan kinerja. Bangun alur kerja yang dapat diulang dan diaudit untuk:

  • Mengekspor data tenant dalam snapshot konsisten
  • Menghapus data tenant tanpa meninggalkan baris yatim piatu
  • Membuktikan penyelesaian via log dan checksum

Mencegah restore lintas-tenant yang tak disengaja

Risiko terbesar bukan peretas—melainkan operator yang terburu-buru. Kurangi kesalahan manusia dengan guardrail:

  • Perlukan identifier tenant plus konfirmasi sekunder (nama tenant, ID tagihan)
  • Validasi jumlah baris dan distribusi tenant_id sebelum impor
  • Restore ke lingkungan karantina dulu, lalu promosikan

Latihan DR dan verifikasi batas-batas setelahnya

Setelah drill pemulihan bencana, jangan berhenti pada “aplikasi hidup.” Jalankan pengecekan otomatis yang mengonfirmasi isolasi tenant: sample query lintas tenant, tinjau audit log, dan verifikasi spot bahwa kunci enkripsi dan peran akses masih ter-scope dengan benar.

Ketika Multi-Tenancy Tidak Lagi Tepat

Multi-tenancy sering menjadi default terbaik untuk SaaS, tetapi bukan keputusan permanen. Seiring produk dan campuran pelanggan berkembang, pendekatan "satu datastore bersama" dapat mulai menciptakan risiko bisnis atau memperlambat pengiriman.

Sinyal bahwa saatnya meningkatkan isolasi

Pertimbangkan berpindah dari fully shared ke isolasi lebih tinggi ketika satu atau lebih dari ini muncul secara konsisten:

  • Dampak pertumbuhan/skalabilitas: beberapa tenant menyumbang porsi traffic, storage, atau job background yang tidak proporsional, dan penyetelan untuk semua orang menjadi lebih sulit
  • Kepatuhan dan persyaratan kontraktual: pelanggan meminta environment dedikasi, kontrol residency, kepemilikan kunci enkripsi, atau batas audit yang lebih ketat daripada yang bisa model bersama berikan
  • Tenant berat dengan pola unik: impor besar, laporan burst, atau integrasi kustom menyebabkan kontensi berulang yang tidak dapat dipecahkan hanya dengan tuning dan throttle

Model hybrid yang menjaga biaya tetap wajar

Anda tidak harus memilih antara “semua bersama” dan “semua khusus.” Hybrid umum termasuk:

  • Mencadangkan sejumlah kecil tenant top-tier ke database atau cluster terpisah sambil mempertahankan ekor panjang di infrastruktur bersama
  • Penawaran bertingkat: shared secara default, terisolasi untuk paket enterprise
  • Isolasi fungsional: tetap berbagi untuk transaksi, tetapi pindahkan analytics/reporting tenant berat ke store terpisah

Biaya dan kompleksitas untuk dijelaskan ke pemangku kepentingan

Lebih banyak isolasi biasanya berarti belanja infrastruktur lebih tinggi, overhead operasional lebih besar (migrasi, monitoring, on-call), dan koordinasi rilis lebih rumit (perubahan skema di banyak environment). Tradeoff-nya adalah jaminan kinerja yang lebih jelas dan pembicaraan kepatuhan yang lebih sederhana.

Langkah berikutnya

Jika Anda mengevaluasi opsi isolasi, tinjau panduan terkait di /blog atau bandingkan paket dan opsi deployment di /pricing.

Jika Anda ingin mem-prototype SaaS dengan cepat dan menguji asumsi multi-tenant lebih awal (scoping tenant, skema ramah RLS, throttling, dan alur operasi), platform vibe-coding seperti Koder.ai dapat membantu Anda memutar aplikasi React + Go + PostgreSQL yang bekerja dari chat, iterasi di mode planning, dan deploy dengan snapshot dan rollback—lalu ekspor kode sumber saat Anda siap mengeraskan arsitektur untuk produksi.

Pertanyaan umum

What is a multi-tenant database in plain terms?

Sebuah basis data multi-tenant adalah pengaturan di mana beberapa pelanggan berbagi infrastruktur basis data yang sama (dan seringkali skema yang sama), sementara aplikasi dan/atau basis data menegakkan bahwa setiap tenant hanya dapat mengakses data mereka sendiri. Persyaratan inti adalah pembatasan tenant yang ketat pada setiap operasi baca dan tulis.

Why do SaaS teams choose multi-tenancy?

Multi-tenancy sering dipilih karena:

  • Biaya per pelanggan lebih rendah (komputasi/penyimpanan/lisensi bersama)
  • Operasi lebih sederhana pada skala besar (lebih sedikit basis data untuk dipatch, di-upgrade, dan dimonitor)
  • Onboarding lebih cepat (tidak perlu menyediakan tumpukan basis data penuh untuk setiap pelanggan)

Tukarannya adalah Anda harus sengaja membangun batasan isolasi dan pengaman kinerja.

What are the main multi-tenant database models?

Model umum (dari isolasi paling kuat ke yang paling banyak berbagi) meliputi:

  • Database-per-tenant: batas isolasi terkuat, operasi lebih berat.
  • Schema-per-tenant: pemisahan baik, migrasi masih berulang.
  • Table-per-tenant: bisa bekerja sementara, seringkali sulit diskalakan.
  • Shared-table (kolom tenant_id): operasi paling sederhana, paling sulit diamankan/disetel.

Pilihan Anda menentukan batas isolasi dan beban operasional.

How does multi-tenancy change the security threat model?

Risiko terbesar bergeser menuju akses lintas-tenant yang disebabkan oleh kesalahan rutin, bukan hanya penyerang eksternal. Konteks tenant (seperti tenant_id) harus diperlakukan sebagai persyaratan otorisasi, bukan filter opsional. Anda juga perlu mempertimbangkan realitas produksi seperti konkurensi, caching, retry, dan pekerjaan background.

What typically causes cross-tenant data leaks?

Penyebab paling umum termasuk:

  • Filter tenant yang hilang di satu jalur kode
  • Join di mana satu tabel diberi scope tetapi tabel yang dijoin tidak
  • Cache yang diberi kunci oleh URL/user tetapi bukan tenant
  • Prepared statement yang mengikat tenant_id yang salah
  • Pekerjaan background yang kehilangan konteks tenant

Desain guardrail agar query tanpa scope sulit (atau tidak mungkin) dijalankan.

When should you use row-level security (RLS), and what does it protect against?

Row-level security (RLS) memindahkan pengecekan tenant ke dalam basis data menggunakan kebijakan yang membatasi SELECT/UPDATE/DELETE hanya ke baris yang cocok dengan tenant saat ini. Ini mengurangi ketergantungan pada "semua orang mengingat klausa WHERE", tetapi harus dipasangkan dengan scoping di lapisan aplikasi, prinsip least privilege, dan pengujian kuat. Anggap RLS sebagai kunci tambahan, bukan satu-satunya kunci.

What are the most important isolation controls to prevent cross-tenant access?

Ambang praktis meliputi:

  • tenant_id kanonik pada tabel yang dimiliki tenant
  • Unikitas komposit dan foreign key yang menyertakan tenant_id
  • Izin deny-by-default dan peran DB least-privilege
  • Akses admin terpisah dan diaudit (hindari superuser di kode aplikasi)
  • Tes negatif yang mencoba baca/tulis lintas-tenant

Tujuannya adalah membuat kesalahan gagal dengan aman.

How does encryption and key management work in a shared datastore?

Enkripsi membantu, tetapi menutup risiko berbeda:

  • Dalam transit (TLS): lindungi data antara layanan.
  • At rest: lindungi snapshot/disk/backup, tetapi bukan query yang buggy.
  • Kunci per-tenant mengurangi blast radius tapi menambah kompleksitas operasi.

Juga perlakukan identitas tenant sebagai hal krusial-keamanan: jangan percaya tenant_id mentah dari klien; ikat ke token yang ditandatangani dan pemeriksaan server-side.

What is the noisy neighbor problem, and how do you mitigate it?

Masalah noisy neighbor terjadi ketika satu tenant mengonsumsi sumber daya bersama (CPU, memori, I/O, koneksi), meningkatkan latensi untuk tenant lain. Mitigasi praktis meliputi:

  • Batas pool koneksi yang ketat (dan kuota per-tenant jika memungkinkan)
  • Rate limiting dan shaping beban untuk endpoint mahal
  • Timeout query, batas maksimum baris/byte, dan circuit breaker
  • Read replica dan kunci cache per-tenant

Tujuannya adalah keadilan, bukan sekadar throughput mentah.

When should you move away from full multi-tenancy, and what hybrid options exist?

Waktunya tingkatkan isolasi ketika Anda melihat konsisten:

  • Sebagian kecil tenant mendominasi traffic/storage dan menyebabkan kontensi
  • Permintaan kepatuhan untuk environment terdedikasi, residency, atau kontrol kunci
  • Pola beban berat yang tidak bisa diatasi hanya dengan throttle/tuning

Hybrid umum: memisahkan tenant top-tier ke DB/cluster terpisah, penawaran ber-tier (shared vs dedicated), atau memindahkan analytics/reporting ke store terpisah.

Related posts