Security Best Practice di API Gateway Blibli.com
Salah satu tantangan yang ada saat kita menggunakan arsitektur Microservices adalah seputar Security (seperti Authentication dan Authorization). Saat kita mulai membuat service, akan ada pertanyaan, bagaimana cara mengamankan service yang kita buat? Paling tidak ada 3 cara untuk mengamankan service yang kita buat, diantaranya:
- Membuat fitur Authentication dan Authorization di service tersebut. Ini adalah cara yang paling mudah, namun paling banyak ceremony nya, karena jika kita punya 100 service, kita harus membuat fitur Authentication dan Authorization di 100 service tersebut.
- Membuat API Gateway untuk melakukan Authentication dan Authorization, dimana semua request harus melewati API Gateway tersebut, sebelum akhirnya diteruskan ke target service nya. Ini adalah cara paling sulit diawal, karena kita perlu membuat service tambahan, namun mudah diakhir karena semua service tidak perlu membuat fitur Authentication dan Authorization lagi.
- Membuat plugin untuk melakukan pengecekan Authentication dan Authorization, lalu meng-include plugin tersebut ke semua service. Investasi untuk melakukan hal ini hanya perlu membuat plugin nya saja. Tapi sayangnya cara ini hanya bisa dilakukan jika kita menggunakan stack teknologi yang sama untuk semua service. Jika tiap service punya stack teknologi berbeda-beda, maka hal ini akan sulit dilakukan, karena kita perlu membuat plugin untuk semua stack.
Di Blibli.com, kita melakukan cara yang ke-2 dan ke-3. Tapi pada artikel ini kita akan membahas tentang cara yang ke-2 saja, apa saja tantangannya dan bagaimana cara kerja sistemnya di Blibli.com. Untuk cara yang ke-3, akan kita bahas di artikel berbeda.
Kenapa API Gateway?
Sebenarnya di Blibli.com bukan hanya Authentication dan Authorization yang dilakukan di API Gateway. Kita juga melakukan load balancing, backpressure process dan log monitoring di API Gateway. Diharapkan dengan itu, hal-hal perintilan tadi tidak perlu dilakukan lagi di semua service nya, cukup dilakukan di API Gateway.
Saat ini di Blibli.com, semua request dari luar pasti harus melewati API Gateway, tidak ada yang bisa melakukan direct request ke service yang dituju. Hal ini juga memudahkan tim Infra dan Security, karena tidak harus semua service dibuka ke public, cukup 1 service saja, yaitu API Gateway.
Multi Tenant Platform
Semua service yang dibuat di Blibli.com, kita persiapkan untuk menjadi sebuah Platform ECommerce yang Multi Tenant. Dalam artian, jika suatu saat Blibli.com punya ECommerce dengan brand berbeda, kita tidak perlu melakukan setup ulang untuk itu, karena dari awal sistem di Blibli.com sudah disiapkan sebagai sistem yang multi tenant / multi merchant.
Jika diperhatikan, semua data di Blibli.com selalu diikuti dengan identitas partner, yaitu identitas pemilik data tersebut. Bahkan di semua API yang dibuat di setiap service, wajib memberi tahu identitas partner yang melakukan request. Maka dari itu partner Blibli, jika ingin menggunakan sistem Blibli.com, dapat langsung menggunakan tanpa harus develop ulang. Contoh beberapa partner Blibli.com yang menggunakan Platform sistem Blibli.com adalah:
- Supersoccer.tv, sistem pembayaran di supersoccer.tv menggunakan sistem payment nya Blibli.com, dan ini dilakukan tanpa harus menginstall sistem Blibli.com di server supersoccer.tv.
- Samsung Galaxy Launchpack, sudah 2 kali Samsung bekerja sama dan menggunakan Platform Blibli.com untuk melakukan pre-order Samsung Galaxy Note 8 dan Samsung Galaxy S9.
- Dan banyak yang lainnya.
Authentication di API Gateway
Salah satu yang perlu dilakukan di API Gateway adalah Authentication pastinya. Kita perlu melakukan Authentication untuk mengetahu, siapa yang melakukan request ke sistem. Apakah merchant A, B atau bahkan bukan merchant.
Blibli.com menyimpan semua informasi tentang merchantnya di sebuah service, disana disimpan semua informasi merchant beserta API key yang digunakan untuk proses Authentication. Dan setiap request yang dilakukan ke target service, wajib menyisipkan informasi merchant yang melakukan request tersebut. Jika tidak, request tersebut akan di tolak oleh target service.
Berikut tahapan yang terjadi ketika ada request yang terjadi ke sistem Blibli.com.
- Client melakukan HTTP request ke sistem Blibli.com. Client wajib memasukkan API Key sebagai sandi untuk proses Authentication.
- API Gateway akan menerima request dari client tersebut. Selanjutnya API Gateway akan melakukan pengecekan dengan cara bertanya ke merchant service.
- Jika API Key tersebut valid, maka merchant service akan mengembalikan informasi merchant tersebut untuk nanti di forward ke target service nya.
- Jika merchant service menganggap API Key tersebut valid, maka API Gateway akan mem-forward HTTP Request tersebut menuju target service yang dituju. HTTP Request yang di-forward akan disisipkan informasi merchant yang melakukan request tersebut. Sehingga target service tidak perlu lagi melakukan cek data merchant, karena semua request yang sampai ke target service dianggap request yang sudah valid.
Authorization di API Gateway
Authentication sebenarnya adalah hal yang mudah, hal yang paling sulit di lakukan adalah Authorization. Saat ada request dari client, dan ternyata request tersebut valid. Maka tidak bulat-bulat API Gateway akan mem-forward request tersebut ke target service nya. Perlu dilakukan proses Authorization, dimana akan di cek, apakah client tersebut berhak untuk mengakses service tersebut, atau apakah berhak untuk melakukan operasi tersebut.
Authorization Rules menggunakan URL
Karena proses Authorization harus dilakukan di API Gateway, karena jika dilakukan di target service nya, terlalu banyak duplikasi, maka yang kita lakukan adalah membuat Authorization Rules berdasarkan URL yang di-request oleh client. Client akan memiliki role, dan tiap role hanya bisa mengakses URL tertentu yang diperbolehkan saja.
Tantangan saat menggunakan URL sebagai rules nya adalah, URL yang terlalu dinamis. Misal, API untuk mengakses detail resource berdasarkan ID-nya, bisa menghasilkan jutaan kombinasi URL, seperti:
- GET /api/payments/{paymentId}
- GET /api/orders/{orderId}
- GET /api/products/{productId}
Dan karena tidak mungkin kita menyimpan setiap kombinasi URL di sistem kita, oleh karena itu Authorization Rules yang kita buat haruslah mendukung regex.
Kenapa Tidak Menggunakan Database untuk Authorization Rules?
Awalnya, kita berpikir bahwa untuk URL rules dapat kita simpan di database. Hal ini agar jika ada URL rules baru, cukup dengan menyimpan satu record baru saja di database. Tapi permasalahannya, karena URL rules yang kita simpan dalam bentuk regex, maka agak sulit untuk melakukan query nya.
Hampir semua database mendukung regex. Tapi sayangnya dukungan operasi regex nya adalah untuk mencari URL yang sesuai dengan regex, bukan kebalikannya.
- Jika kita menggunakan database, yang biasa kita lakukan adalah membuat query regex “SELECT * FROM X WHERE URL LIKE ‘%REGEX%’” hasilnya adalah URL nya.
- Sedangkan yang kita butuhkan adalah kebalikannya, kita ingin melakukan query “SELECT * FROM X WHERE URL = ‘URL’” dan hasilnya adalah REGEX nya :D
Membuat Authorization Rules menggunakan Ant Matcher
Karena agak sulit jika menggunakan database, akhirnya yang kita lakukan adalah membuat Authorization Rules sendiri tanpa menggunakan database. Kita menyimpan rules tersebut di konfigurasi aplikasi. Dan agar mendukung regex, kita menggunakan Ant Matcher yang terdapat di Spring Framework.
Sekarang pertanyaannya? Bagaimana agar rules dapat diubah secara dinamis, tanpa harus me-restart service API Gateway-nya?
Hot Reload Authorization
Agar mendukung hot reload, kita menggunakan Spring Cloud Consul untuk menyimpan semua konfigurasi Authorization Rules nya. Dengan begitu, jika terjadi perubahan rules, kita hanya perlu mengubah rules-nya di Consul, dan secara otomatis Authorization Rules akan berubah di API Gateway tanpa harus melakukan restart.
Technology Stack
Selanjutnya, teknologi apa saja yang digunakan oleh Blibli.com untuk membuat API Gateway nya? Tidak terlalu aneh teknologi yang kita gunakan, semua teknologinya adalah teknologi yang sudah banyak digunakan di pasaran.
- Java, yup hampir 99% backend sistem kita dibuat menggunakan bahasa pemrograman Java.
- Netflix Zuul, sebagai core API Gateway yang digunakan.
- Consul, untuk menyimpan semua konfigurasi API Gateway termasuk Authorization Rules.
- OpenFeign dan Ribbon, digunakan sebagai http client yang digunakan untuk menembak service dari API Gateway, menggunakan ini karena sudah mendukung client side load balancer, sehingga tidak perlu mengguakan server side load balancer lagi seperti HaProxy atau Nginx.
- Spring Boot dan Spring Framework, digunakan sebagai framework untuk membuat aplikasi API Gateway.
- Redis, digunakan untuk mem-cache hasil Authentication, agar tidak terlalu membebani merchant service jika setiap request harus menembak merchant service.
Tertantang untuk berkolaborasi menjadi Backend Engineer di Blibli.com? Kamu bisa hubungi saya, Eko Kurniawan Khannedy via email eko.k.khannedy@gdn-commerce.com atau telegram @khannedy.
Regards.