Kontrak API untuk migrasi reverse proxy tanpa merusak auth berarti memperlakukan proxy sebagai bagian dari antarmuka sistem, bukan sekadar komponen jaringan. Dalam praktiknya, banyak insiden terjadi saat endpoint masih hidup, tetapi autentikasi gagal karena header berubah, aplikasi salah membaca scheme/host, signature callback menjadi tidak valid, atau kebijakan rate limit ikut berubah.
Jika Anda sedang memindahkan trafik dari Nginx ke API gateway, dari ingress lama ke baru, atau menambahkan lapisan CDN/WAF di depan API, fokus utamanya bukan hanya routing. Fokus utamanya adalah membekukan kontrak perilaku yang terlihat oleh klien dan backend: header apa yang sampai, URL apa yang dihitung aplikasi, bagaimana identitas klien ditentukan, dan kapan retry terjadi. Artikel ini membahas kontrak tersebut secara implementatif, termasuk checklist, strategi pengujian sebelum cutover, failure mode yang umum, dan langkah mitigasinya.
Mengapa migrasi reverse proxy sering merusak auth
Secara arsitektural, reverse proxy tampak seperti komponen yang bisa diganti tanpa efek besar. Namun secara implementasi, proxy sering ikut menentukan perilaku yang dianggap stabil oleh aplikasi dan klien. Di sinilah pendekatan evaluasi arsitektur vs implementasi penting: di diagram, dua proxy mungkin setara; di produksi, perilaku default-nya bisa berbeda dan cukup untuk memicu insiden.
Beberapa contoh perbedaan yang sering luput:
- Header auth diteruskan berbeda, misalnya
Authorizationtidak diteruskan, diubah kapitalisasinya oleh middleware tertentu, atau diganti ke header internal. - Trusted proxy salah konfigurasi, sehingga aplikasi membaca
X-Forwarded-Proto,X-Forwarded-Host, atauX-Forwarded-Fordari sumber yang tidak semestinya, atau justru mengabaikannya. - Redirect dan scheme berubah, misalnya backend mengira request datang lewat HTTP, lalu menghasilkan redirect ke URL berbeda; pada alur bertanda tangan, ini dapat membuat signature invalid.
- Callback URL berubah, baik dari sisi path, host, trailing slash, maupun port implisit, sehingga pihak ketiga menolak callback atau webhook verification gagal.
- Rate limit dan retry menjadi tidak konsisten, karena identitas klien dihitung dengan aturan baru atau gateway melakukan retry otomatis pada request yang seharusnya tidak diulang.
Masalah-masalah ini jarang muncul di uji kesehatan sederhana seperti GET /health. Mereka biasanya baru terlihat pada alur login, callback OAuth, webhook, HMAC validation, dan endpoint dengan rate limit ketat.
Kontrak API yang harus dibekukan sebelum migrasi
Sebelum mengganti reverse proxy, buat daftar kontrak yang dianggap tidak boleh berubah selama migrasi. Jangan mulai dari konfigurasi proxy lama atau baru; mulai dari apa yang dipakai aplikasi dan klien untuk tetap bekerja.
1. Kontrak header autentikasi dan identitas request
Bekukan definisi header yang wajib dipertahankan end-to-end:
Authorizationharus diteruskan apa adanya jika backend menggunakannya untuk Bearer token, Basic auth, atau signature lain.- Jika ada header auth khusus seperti
X-API-KeyatauX-Signature, tetapkan apakah nilainya diteruskan tanpa modifikasi, dihapus dari log, dan apakah boleh diduplikasi. - Tentukan header identitas seperti
X-Request-Id,X-Forwarded-For,X-Forwarded-Proto,X-Forwarded-Host, atauForwardedyang menjadi sumber kebenaran. - Jika ada header internal dari proxy lama, pastikan tidak dipakai diam-diam oleh aplikasi. Header semacam
X-Original-URIatauX-Client-IPsering menjadi ketergantungan tak terdokumentasi.
Kesalahan umum adalah menganggap semua proxy pasti meneruskan Authorization. Di beberapa jalur, header ini bisa hilang karena aturan eksplisit, integrasi auth di gateway, atau konfigurasi upstream yang tidak menyertakannya.
2. Kontrak URL eksternal yang dilihat klien dan aplikasi
Auth modern sangat sensitif pada URL yang dianggap canonical. Bekukan hal-hal berikut:
- Scheme: aplikasi harus tahu apakah URL publik adalah
https, bukanhttp. - Host: pastikan host publik tidak berubah kecuali seluruh ekosistem ikut diperbarui.
- Port implisit: beberapa signature memasukkan port, sebagian tidak; perubahan dari
:443implisit ke eksplisit dapat memicu mismatch. - Path dan trailing slash:
/callbackdan/callback/tidak selalu ekuivalen. - Case sensitivity pada path bila upstream atau aplikasi punya perlakuan berbeda.
Ini krusial untuk OAuth redirect URI, webhook callback, signed URL, dan HMAC yang menghitung signature dari metode, path, query string, atau host.
3. Kontrak trusted proxy
Aplikasi backend harus tahu proxy mana yang dipercaya untuk menyuntikkan header forwarding. Jika semua sumber dianggap tepercaya, klien bisa memalsukan X-Forwarded-Proto atau X-Forwarded-For. Jika terlalu ketat dan daftar proxy tidak diperbarui saat migrasi, aplikasi bisa salah menganggap request sebagai HTTP langsung dari proxy internal.
Bekukan dua hal:
- Daftar hop atau jaringan yang dianggap trusted proxy.
- Header mana yang dipakai aplikasi untuk menentukan client IP, scheme, dan host.
Catatan: trusted proxy adalah kontrak keamanan, bukan sekadar pengaturan kompatibilitas. Salah konfigurasi di sini bisa merusak auth sekaligus membuka celah spoofing.
4. Kontrak callback, redirect, dan signed request
Jika sistem Anda berinteraksi dengan OAuth provider, payment gateway, webhook provider, atau SSO, dokumentasikan dengan jelas:
- Daftar callback URL publik yang resmi.
- Aturan pembuatan redirect URL di backend.
- Komponen apa saja yang masuk ke proses signature: method, path, query, host, header, body, timestamp.
- Apakah gateway baru melakukan URL normalization, decode/encode ulang query, atau mengubah urutan parameter.
Urutan query string dan normalisasi encoding tampak kecil, tetapi untuk sebagian skema signature, perubahan ini cukup untuk menggagalkan verifikasi.
5. Kontrak rate limit, timeout, dan retry
Proxy baru hampir selalu membawa kebijakan operasional baru. Ini baik untuk reliabilitas, tetapi berbahaya jika tidak sinkron dengan asumsi aplikasi.
- Rate limit key: berdasarkan IP, API key, token subject, atau kombinasi lain?
- Timeout: apakah gateway punya timeout lebih pendek daripada backend, sehingga klien melihat kegagalan meski backend selesai memproses?
- Retry otomatis: metode apa yang boleh diulang? Jangan melakukan retry buta pada operasi non-idempoten seperti pembuatan transaksi tanpa idempotency key.
- Status code mapping: apakah upstream timeout diterjemahkan menjadi 502, 504, atau kode lain? Ini memengaruhi logika retry klien.
Failure mode nyata yang sering terjadi
Authorization hilang di jalur tertentu
Gejalanya sederhana: endpoint publik tetap normal, tetapi endpoint terproteksi tiba-tiba menghasilkan 401 atau 403 setelah sebagian trafik dipindahkan. Penyebabnya bisa karena route tertentu melewati filter auth di gateway, atau hanya path tertentu yang meneruskan header ke upstream.
Mitigasi: buat uji hitam-putih yang memverifikasi backend benar-benar menerima header auth pada path penting, bukan hanya memeriksa status code.
Signature callback invalid karena scheme berubah
Backend lama tahu bahwa request publik adalah HTTPS karena proxy menyetel header forwarding dengan benar. Di proxy baru, aplikasi tidak lagi menganggap hop tersebut tepercaya, lalu membangun URL canonical sebagai HTTP. Hasilnya, signed URL atau verifikasi callback gagal meskipun payload sama.
Mitigasi: verifikasi trusted proxy dan pastikan aplikasi menghitung URL eksternal dari sumber header yang benar. Uji dengan skenario callback nyata, bukan hanya request biasa.
Redirect OAuth mismatch
Setelah migrasi, login lewat OAuth gagal dengan pesan redirect_uri mismatch. Biasanya host, path, atau trailing slash berubah, atau backend menghasilkan URL dari host internal alih-alih host publik.
Mitigasi: bekukan redirect URI secara eksplisit. Hindari membangun callback URL dari request mentah jika konfigurasi base URL yang stabil lebih aman untuk alur auth tertentu.
Rate limit terasa lebih agresif setelah cutover
Sebelumnya limit dihitung per API key, sekarang gateway baru menghitung per IP. Jika banyak klien berada di belakang NAT atau perusahaan menggunakan egress IP bersama, banyak request sah akan terblokir bersamaan.
Mitigasi: samakan key rate limit dengan identitas bisnis yang benar. Jika harus memakai IP, dokumentasikan konsekuensinya dan pantau false positive.
Retry gateway menggandakan operasi tulis
Gateway baru bisa saja melakukan retry pada upstream timeout atau koneksi terputus. Jika request POST sebenarnya sudah diproses backend tetapi respons gagal kembali, retry dapat membuat operasi ganda.
Mitigasi: batasi retry ke operasi idempoten atau wajibkan idempotency key pada endpoint sensitif.
Checklist kontrak API sebelum cutover
Checklist berikut berguna sebagai dokumen pembekuan kontrak. Gunakan sebagai artefak review lintas backend, platform, dan security.
- Header auth: daftar header wajib, aturan pass-through, header yang harus dibuang, dan sanitasi logging.
- Forwarding headers: sumber kebenaran untuk proto, host, port, dan client IP.
- Trusted proxy: daftar jaringan/proxy yang dipercaya oleh aplikasi.
- Canonical URL: host publik, scheme, path normalization, trailing slash, dan query handling.
- Redirect/callback: seluruh URL yang dipakai OAuth, SSO, payment, webhook, signed URL.
- Rate limit: key, burst, perilaku 429, header respons yang dipakai klien bila ada.
- Retry/timeout: batas waktu di gateway, upstream, dan klien; metode yang boleh di-retry.
- Status code mapping: bagaimana gateway menerjemahkan error upstream atau policy rejection.
- Observabilitas: request ID, access log, metrik 401/403/429/5xx, dan tracing hop proxy.
- Rollback: cara mengembalikan trafik tanpa membuat state ganda atau sesi rusak.
Strategi pengujian sebelum migrasi reverse proxy
Pengujian yang efektif bukan sekadar membandingkan latensi. Tujuannya adalah membuktikan bahwa kontrak API tetap sama untuk skenario auth yang kritis.
1. Bangun matriks skenario, bukan hanya daftar endpoint
Kelompokkan skenario berdasarkan risiko kontrak:
- Request tanpa auth, dengan Bearer token, dengan API key, dengan signed header.
- Request yang memicu redirect, callback, dan webhook verification.
- Request dengan query string yang kompleks, karakter ter-encode, dan path yang sensitif.
- Request dari klien di belakang proxy/NAT untuk memeriksa client IP dan rate limit.
- Request write yang sensitif terhadap retry.
Dengan pendekatan ini, Anda menguji perilaku, bukan sekadar cakupan route.
2. Lakukan perbandingan respons lama vs baru
Jika memungkinkan, kirim request identik ke proxy lama dan baru pada lingkungan staging atau shadow. Bandingkan:
- Status code
- Header respons penting, terutama redirect dan rate limit
- Body error untuk endpoint auth
- Nilai yang dilihat backend: scheme, host, client IP, request ID, dan keberadaan header auth
Idealnya backend memiliki endpoint debug internal yang hanya aktif di lingkungan aman untuk menampilkan metadata request yang sudah disanitasi.
# Contoh pemeriksaan cepat dengan curl terhadap redirect dan header auth
curl -i \
-H 'Authorization: Bearer test-token' \
-H 'X-Request-Id: migration-check-001' \
'https://api-staging.example.com/oauth/start?provider=demo'Jangan berhenti pada hasil 200. Untuk alur auth, sering kali indikator pentingnya justru ada di header Location, host yang dipakai redirect, atau log backend yang menunjukkan apakah token sampai.
3. Uji signature dan callback secara end-to-end
Untuk endpoint yang memakai HMAC atau signed URL, siapkan fixture request yang diketahui valid. Kirim fixture yang sama melalui jalur lama dan baru. Bila verifikasi gagal hanya di proxy baru, fokuskan investigasi pada canonicalization: path, query, host, scheme, atau body buffering.
Jika Anda menerima webhook dari pihak ketiga, buat simulator internal yang meniru format request mereka. Ini lebih berguna daripada menunggu vendor mengirim webhook sungguhan saat masa cutover.
4. Verifikasi trusted proxy dari sisi aplikasi
Pengujian harus membuktikan dua hal sekaligus:
- Aplikasi membaca scheme/host/client IP yang benar saat request datang melalui proxy resmi.
- Aplikasi menolak spoofing dari klien yang mencoba menyuntikkan
X-Forwarded-*secara langsung.
Jika hanya menguji kasus pertama, Anda bisa lolos kompatibilitas tetapi gagal dari sisi keamanan.
5. Simulasikan timeout dan retry
Untuk endpoint tulis, sengaja buat upstream lambat atau putus di tengah respons pada lingkungan uji. Tujuannya adalah melihat apakah gateway melakukan retry, bagaimana status code diteruskan, dan apakah backend menerima request lebih dari sekali.
Pengujian ini sering diabaikan karena dianggap operasional, padahal efeknya langsung ke kontrak API dan integritas data.
Contoh konfigurasi dan pemeriksaan yang relevan
Nama direktif berbeda antar proxy, tetapi prinsipnya sama: teruskan header yang diperlukan, jangan percaya forwarding header dari sumber sembarang, dan pastikan aplikasi membaca metadata request dari hop yang benar.
# Pseudokonfigurasi: prinsip yang perlu dipenuhi di reverse proxy/gateway
forward Authorization to upstream
set X-Forwarded-Proto from actual client-facing scheme
set X-Forwarded-Host from public host
append client IP to X-Forwarded-For consistently
inject X-Request-Id if absent
avoid automatic retries for non-idempotent methods unless protected by idempotency keyDari sisi aplikasi, pastikan ada cara untuk memeriksa metadata request yang benar-benar diterima backend. Misalnya pada middleware internal:
// Pseudocode middleware untuk audit metadata request
log.info('request_meta', {
request_id: req.header('x-request-id'),
has_authorization: Boolean(req.header('authorization')),
forwarded_proto: req.header('x-forwarded-proto'),
forwarded_host: req.header('x-forwarded-host'),
client_ip_seen_by_app: req.ip,
method: req.method,
path: req.originalUrl
})Log seperti ini sangat membantu saat membandingkan perilaku jalur lama dan baru. Pastikan Anda tidak pernah mencatat nilai token atau secret mentah; cukup catat keberadaannya atau fingerprint yang aman bila benar-benar diperlukan.
Observabilitas untuk mendeteksi kerusakan auth secepat mungkin
Migrasi reverse proxy tanpa observabilitas yang tepat berarti Anda baru tahu ada masalah dari tiket pengguna. Untuk alur auth, itu terlambat.
Metrik minimum yang perlu dipantau
- Rasio
401,403, dan429per route dan per jalur proxy. - Rasio
3xxpada endpoint login atau callback. - Rasio kegagalan verifikasi signature atau webhook.
- Distribusi status code upstream vs status code yang dilihat klien.
- Timeout, reset connection, dan retry count di gateway.
Log dan tracing yang penting
- Request ID end-to-end yang konsisten dari gateway hingga backend.
- Access log gateway yang menyertakan route, upstream status, dan alasan policy rejection.
- Application log yang mencatat apakah auth header ada, scheme/host yang dilihat aplikasi, dan alasan penolakan auth secara terstruktur.
- Tracing lintas hop bila tersedia, terutama untuk membedakan kegagalan di gateway vs backend.
Trade-off-nya jelas: semakin detail observabilitas, semakin besar volume log dan tanggung jawab sanitasi data sensitif. Namun untuk fase migrasi, log terstruktur yang singkat tetapi tepat biasanya jauh lebih murah daripada investigasi insiden setelah cutover penuh.
Canary dan rollback yang aman
Canary berdasarkan persentase trafik saja sering tidak cukup
Jika hanya memindahkan 1% trafik acak, Anda mungkin tidak menyentuh alur auth yang penting. Lebih baik kombinasikan beberapa strategi:
- Canary berdasarkan route: pindahkan endpoint non-kritis dulu, lalu endpoint auth dengan pengawasan ketat.
- Canary berdasarkan tenant atau klien internal: pilih konsumen yang bisa memberi umpan balik cepat.
- Header-based canary: aktifkan jalur baru untuk request yang diberi header opt-in dari tim penguji.
Pendekatan ini memberi sinyal lebih bermakna daripada persentase trafik murni.
Siapkan rollback sebagai bagian dari desain
Rollback bukan sekadar mengembalikan routing. Anda juga perlu memastikan:
- Konfigurasi sesi, cookie, dan auth state tidak tergantung pada proxy baru.
- Rate limit state atau cache tidak menimbulkan perilaku aneh setelah balik ke jalur lama.
- Request yang sedang diproses tidak menjadi dobel jika perpindahan dilakukan saat ada retry otomatis.
Bila gateway baru menambahkan fitur seperti retry atau transformasi header, rollback harus menonaktifkan efek tersebut, bukan hanya memindahkan DNS atau load balancer.
Praktik yang aman: tetapkan indikator rollback yang objektif sebelum cutover, misalnya lonjakan 401 pada route tertentu, meningkatnya callback verification failure, atau mismatch redirect URL pada sampel transaksi uji.
Kesalahan umum saat mendokumentasikan kontrak API
- Terlalu fokus pada payload JSON dan melupakan header, scheme, host, serta redirect behavior.
- Mengandalkan default proxy baru tanpa membandingkan perilaku aktual dengan proxy lama.
- Menguji hanya happy path tanpa signed request, callback, timeout, dan retry.
- Tidak melibatkan tim aplikasi yang tahu dependency tersembunyi pada header atau host tertentu.
- Tidak punya baseline observabilitas sehingga perubahan 401/429 sulit diatribusikan ke migrasi.
Penutup
Kunci kontrak API untuk migrasi reverse proxy tanpa merusak auth adalah menganggap proxy sebagai bagian dari perilaku publik sistem. Jika Anda membekukan kontrak yang benar—header auth, canonical URL, trusted proxy, callback, serta rate limit dan retry—maka migrasi bisa diuji secara objektif, bukan berdasarkan asumsi bahwa dua komponen jaringan pasti setara.
Mulailah dari checklist kontrak, bangun uji yang menargetkan alur auth nyata, instrumentasikan observabilitas yang relevan, lalu lakukan canary dengan rollback yang sudah disiapkan. Dengan pendekatan itu, Anda tidak hanya memindahkan trafik, tetapi menjaga perilaku API tetap stabil saat lapisan proxy di bawahnya berubah.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!