Reverse Proxy + CORS Produksi
Reverse Proxy + CORS Produksi
Halaman ini membahas dua hal yang wajib dikonfigurasi sebelum anda mengekspos OmniStream ke internet publik:
- Reverse proxy Nginx + TLS untuk membungkus
api-gateway,ws-server, dan frontend. - Mengganti
CorsLayer::permissive()yang saat ini di-hardcode di backend menjadi allowlist yang ketat.
1. Reverse proxy Nginx
Topologi yang disarankan:
Code
Contoh server block (minimalis):
Code
Rate limiter tower_governor di api-gateway memakai PeerIpKeyExtractor.
Pastikan Nginx meneruskan X-Forwarded-For dan backend anda
dikonfigurasi untuk mempercayainya, supaya rate limit dihitung per-IP
klien asli — bukan per-IP proxy. Jika tidak, seluruh traffic akan
terlihat datang dari 127.0.0.1 dan saling "mencuri" token.
2. CORS produksi — mengapa permisif itu salah
Kondisi saat ini (2026-04-11): baris
crates/api-gateway/src/main.rs:253 menggunakan
CorsLayer::permissive():
Code
CorsLayer::permissive() dari tower-http memasang header:
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCHAccess-Control-Allow-Headers: *
Di produksi ini bermasalah:
- Cookie httpOnly login tidak akan dikirim untuk request cross-origin
ketika
Allow-Origin: *— browser menolak mengirim credentials ke origin wildcard. Artinya fitur cookie auth (dokumentasikan dideveloper/autentikasi/cookies) akan gagal secara diam-diam. - Allowlist wildcard membuka JWT Bearer dari situs manapun yang menyimpan/mencuri token. Meskipun JWT di header sulit dicuri tanpa XSS, praktik ini merusak defense-in-depth.
- Dokumentasi publik yang memberi contoh
CorsLayer::permissive()mengajarkan pola yang salah untuk produksi.
Catatan ruang lingkup
Halaman ini hanya mendokumentasikan masalah dan rekomendasi
perbaikannya. Perubahan kode backend bukan bagian dari plan
docs-site v1 — tracking-nya ada di docs-site/SCOPE.md Section 4
(Backend follow-up register, item BE1). Perbaikan kode adalah
tugas pemilik backend api-gateway.
3. Rekomendasi: allowlist eksplisit
Ganti CorsLayer::permissive() dengan builder yang membaca allowlist
dari FRONTEND_URL (sudah ada di config):
Code
Hal-hal penting:
allow_credentials(true)tidak boleh dikombinasikan dengan origin wildcard — browser menolaknya. Karena itu anda wajib memakaiAllowOrigin::list(...)dengan origin konkret.Authorizationharus masukallow_headersagar JWT Bearer lewat.- Methods yang di-allow harus mencakup semua verb yang benar-benar anda
pakai — jangan include
TRACEatau method eksotis. - Tambahkan origin lain yang sah hanya setelah didiskusikan — setiap origin baru memperluas attack surface.
4. Origin mana yang perlu di-allow?
Biasanya hanya 1–2 origin:
- Frontend produksi anda:
https://crm.example.com(sama denganFRONTEND_URL). - Dokumentasi Try-It playground (jika anda meng-host docs site
yang memanggil
api-gatewaydari browser, misal untuk memverifikasi OpenAPI Try-It secara live). Jangan tambahkan ini kecuali memang perlu.
Origin tidak perlu di-allow jika traffic-nya sudah lewat reverse proxy yang sama (same-origin) — kasus paling umum di deployment "frontend + backend di balik 1 Nginx" di atas.
5. Ringkasan follow-up backend
Tugas backend yang docs-site hanya dokumentasikan:
- BE1 — Ganti
CorsLayer::permissive()dicrates/api-gateway/src/main.rs:253dengan allowlist berbasisFRONTEND_URL. Prioritas HIGH sebelum anda membuka API ke internet publik.
Lihat docs-site/SCOPE.md Section 4 untuk daftar lengkap backend
follow-up lainnya.