Keamanan bagi kami bukan lapisan yang ditambahkan belakangan, melainkan inti arsitektur. Isolasi data, pemisahan identitas, dan penulisan idempoten tertanam di lapisan terbawah kode — bukan pengaturan yang dapat dimatikan, melainkan cara kerja sistem.
Isolasi tingkat baris
Penulisan idempoten
Kueri terparameter
Isolasi loopback
Isolasi data
Isolasi tingkat baris — fail-closed
Pada setiap tabel yang tercakup dalam tenant, PostgreSQL Row-Level Security FORCE selalu aktif; kebijakan mengikat setiap baris pada kondisi "tenant_id = current_setting('app.current_tenant')".
Kueri yang datang tanpa terbentuknya tenant context mengembalikan nol baris — bahkan bukan kesalahan, secara diam-diam kosong. Melihat data satu klinik dengan sesi klinik lain mustahil secara arsitektural.
Uji isolasi lintas-tenant wajib hijau dalam integrasi berkelanjutan (CI); jika merah, kode tidak digabungkan.
Penulisan atomik
Identitas transaction-local, transaksi atomik
Identitas tenant ditetapkan PALING AWAL dalam setiap operasi tulis di dalam transaction dan hanya berlaku selama transaction tersebut; identitas ini tidak menempel pada connection pool dan tidak bocor ke permintaan lain.
Transaksi multi-entitas (faktur + item + pembayaran + pengurangan stok) atomik dalam satu transaction: entah semuanya ditulis bersama atau tidak sama sekali. Tidak ada catatan setengah jadi yang tidak konsisten.
Wewenang
Wewenang berbasis peran (RBAC) ditegakkan di server
Kontrol wewenang dilakukan di lapisan API; klien atau front-end tidak pernah dipercaya. Menyembunyikan menu di peramban hanya soal tampilan — keputusan sebenarnya ada di server.
Mutasi inti (Fase 1) dilindungi menurut peran admin, sekretaris, dan dokter. Meski peran tanpa wewenang memanggil endpoint, permintaan tersebut ditolak.
Perlindungan pengulangan
Penulisan idempoten — tanpa transaksi ganda
Setiap permintaan penulisan membawa satu Idempotency-Key; kunci di sisi server mencegah transaksi kedua yang datang dengan kunci yang sama.
Bahkan ketika jaringan terputus atau klien mengirim ulang permintaan yang sama, penagihan atau faktur kedua tidak akan terbentuk. Hasilnya selalu tunggal dan dapat diprediksi.
Keamanan kueri
SQL injection mustahil — kueri terparameter
Semua kueri basis data adalah pernyataan yang sepenuhnya terparameter, dihasilkan pada waktu kompilasi dengan sqlc. Tidak ada satu baris pun di basis kode yang membangun SQL dengan menggabungkan string secara manual menggunakan masukan pengguna.
Ini menghilangkan kelas serangan SQL injection secara struktural — bertumpu pada cara kueri dibangun, bukan pada upaya "penyaringan" atau "escape".
Permukaan jaringan
Isolasi loopback — inti tertutup dari luar
API inti hanya mendengarkan 127.0.0.1 (loopback). Setiap upaya mengikat ke 0.0.0.0 atau IP publik ditolak sejak awal; inti tidak pernah terbuka ke internet dalam kondisi apa pun.
Satu-satunya permukaan publik adalah gerbang tipis (BFF): ia tidak menyimpan logika bisnis selain sesi, render, dan CSRF. Browser tidak pernah dapat melihat atau mengalamatkan API inti secara langsung.
Identitas & sesi
Kata sandi argon2id, kunci sesi opaque
Kata sandi di-hash dengan argon2id yang berat-memori dan menjadi standar industri; hash polos atau lemah tidak pernah digunakan.
Kunci sesi adalah nilai opaque acak-kripto sepanjang 32 byte, disimpan di Redis, dan kedaluwarsa melalui TTL. Ke browser hanya dipantulkan cookie HttpOnly + Secure + SameSite; kunci tidak pernah terekspos ke JavaScript.
Audit
Catatan audit tak terubah (append-only)
Tindakan penting ditulis ke catatan audit append-only dalam transaction yang SAMA dengan mutasi yang memicunya. Jika transaksi dibatalkan, catatan audit pun tidak ditulis — keduanya tak terpisahkan.
Wewenang UPDATE/DELETE telah dicabut dari tabel audit; catatan tidak dapat diubah atau dihapus kemudian. Riwayat tetap sebagaimana adanya.
Privacy
Penyamaran data sensitif
TCKN, kata sandi, kunci sesi, dan data kesehatan sama sekali tidak masuk ke log. Bahkan pada keluaran debugging, bidang-bidang ini dimasker.
Bila diperlukan, bidang sensitif dienkripsi di tingkat kolom. Data kesehatan berkategori khusus dilindungi dengan aturan yang tertanam dalam desain sejak awal.
Integritas uang
Keamanan uang — numeric, jurnal balik
Uang di mana pun disimpan dengan numeric(14,2); perhitungan uang tidak dilakukan dengan float. Pembulatan terjadi di satu titik saja, di server — tidak ada pergeseran sen atau selisih pembulatan.
Pembatalan dan pengembalian diproses sebagai jurnal balik alih-alih menghapus catatan. Saldo piutang tidak ditulis manual; selalu diturunkan dari total faktur dan pembayaran. Riwayat tidak rusak.
Transfer
Transfer & keamanan peramban
Seluruh lalu lintas dibawa melalui HTTPS/TLS dan HSTS aktif; peramban hanya membangun koneksi dalam bentuk terenkripsi.
Content Security Policy (CSP) yang ketat memblokir inline script; X-Frame-Options DENY mencegah clickjacking, X-Content-Type-Options nosniff mencegah pengaburan tipe. Referrer-Policy dan Permissions-Policy juga diterapkan.
Penting
Pemisahan tier identitas + bidang manajemen terpisah
Pengguna klinik, portal pasien, dan operator platform adalah tier identitas yang TERPISAH: header terpisah, ruang sesi terpisah. Kunci satu tier tidak berfungsi di tier lain — batas otorisasi terpisah secara tegas.
Endpoint platform dan administrasi (penyediaan tenant, penagihan, manajemen otomasi/plugin, pembuatan kunci API) TIDAK TERSEDIA di API publik.
Fungsi-fungsi ini berjalan pada bidang kontrol yang terpisah, internal, dengan pola identitas berbeda (kunci manajemen khusus); tidak dapat diakses maupun ditemukan dari luar. Dengan demikian, permukaan serangan mengecil secara signifikan.
CARA KERJA
Transaksi tunggal, isolasi fail-closed
Alur konseptual berikut menunjukkan bagaimana setiap penulisan dikunci ke tenant dan tetap idempoten. Hanya untuk tujuan penjelasan.
# 1) Tenant context dibangun PALING AWAL dalam transaction (khusus untuk tx ini saja)
BEGIN;
SELECT set_config('app.current_tenant', :session_tenant_id, true);
# 2) Kunci Idempotency-Key — transaksi kedua dengan kunci yang sama tidak akan terbentukSELECT lock_idempotency(:idempotency_key);
# 3) Penulisan multi-entitas — semuanya atomik dalam satu txINSERT INTO invoices ...; # RLS: tenant_id tercakup otomatisINSERT INTO payments ...;
INSERT INTO audit_log ...; # append-only, tx yang sama
COMMIT;
# Jika context tidak dibentuk, kebijakan RLS tidak mengembalikan satu baris pun:SELECT * FROM patients; --> 0 baris (bukan kesalahan, secara diam-diam kosong)
Dapat diverifikasi secara independen
Sebagian keamanan transfer dapat diamati dari luar: Anda dapat memeriksa sendiri sertifikat HTTPS/TLS pada koneksi Anda, serta header keamanan respons seperti HSTS dan kebijakan keamanan konten, melalui alat pengembang peramban Anda. Klaim kami berlandaskan kontrol arsitektur, bukan kalimat pemasaran.
Punya pertanyaan tentang arsitektur keamanan?
Tim kami dengan senang hati membahas detail teknis dan kebutuhan kepatuhan Anda bersama Anda.