RBAC dengan API Gateway dan Open Policy Agent (OPA)

Bobur Umurzokov

Bobur Umurzokov

May 15, 2023

Technology

Dengan berbagai model kontrol akses dan metode implementasi yang tersedia, membangun sistem otorisasi untuk API layanan backend masih bisa menjadi tantangan. Namun, tujuan utamanya adalah memastikan bahwa individu yang tepat memiliki akses yang sesuai ke sumber daya yang relevan. Dalam artikel ini, kita akan membahas cara mengaktifkan model otorisasi Role-based access control (RBAC) untuk API Anda dengan menggunakan API Gateway open-source Apache APISIX dan Open Policy Agent (OPA).

Tujuan pembelajaran

Anda akan mempelajari hal-hal berikut sepanjang artikel:

  • Apa itu RBAC dan bagaimana cara kerjanya?
  • Apa itu OPA dan bagaimana cara kerjanya?
  • Bagaimana mengimplementasikan RBAC dengan OPA dan Apache APISIX?
  • Bagaimana mendefinisikan dan mendaftarkan kebijakan di OPA.
  • Bagaimana membuat upstream, rute, dan mengaktifkan plugin OPA.
  • Bagaimana peran dan izin pengguna diurai dari payload token JWT atau data konsumen.

Apa itu RBAC?

Role-Based Access Control (RBAC) dan Attribute-Based Access Control (ABAC) adalah dua model kontrol akses yang umum digunakan untuk mengelola izin dan mengontrol akses ke sumber daya dalam sistem komputer. RBAC menetapkan izin kepada pengguna berdasarkan peran mereka dalam suatu organisasi. Dalam RBAC, peran didefinisikan berdasarkan fungsi atau tanggung jawab pengguna, dan izin diberikan kepada peran tersebut. Pengguna kemudian ditugaskan ke satu atau lebih peran, dan mereka mewarisi izin yang terkait dengan peran tersebut. Dalam konteks API, misalnya, peran pengembang mungkin memiliki izin untuk membuat dan memperbarui sumber daya API, sementara peran pengguna akhir mungkin hanya memiliki izin untuk membaca atau mengeksekusi sumber daya API.

Pada dasarnya, RBAC menetapkan izin berdasarkan peran pengguna, sedangkan ABAC menetapkan izin berdasarkan atribut yang terkait dengan pengguna dan sumber daya.

Dalam RBAC, kebijakan didefinisikan oleh kombinasi peran yang ditetapkan kepada pengguna, tindakan yang mereka diizinkan untuk dilakukan, dan sumber daya di mana mereka dapat melakukan tindakan tersebut.

Apa itu OPA?

OPA (Open Policy Agent) adalah mesin kebijakan dan seperangkat alat yang menyediakan pendekatan terpadu untuk penegakan kebijakan di seluruh sistem terdistribusi. Ini memungkinkan Anda untuk mendefinisikan, mengelola, dan menegakkan kebijakan secara terpusat dari satu titik. Dengan mendefinisikan kebijakan sebagai kode, OPA memungkinkan peninjauan, pengeditan, dan roll-back kebijakan yang mudah, memfasilitasi manajemen kebijakan yang efisien.

Contoh gambar Open Policy Agent

OPA menyediakan bahasa deklaratif yang disebut Rego, yang memungkinkan Anda untuk membuat dan menegakkan kebijakan di seluruh stack Anda. Ketika Anda meminta keputusan kebijakan dari OPA, ia menggunakan aturan dan data yang telah Anda berikan dalam file .rego untuk mengevaluasi kueri dan menghasilkan respons. Hasil kueri kemudian dikirim kembali kepada Anda sebagai keputusan kebijakan. OPA menyimpan semua kebijakan dan data yang dibutuhkan dalam cache memorinya. Akibatnya, OPA mengembalikan hasil dengan cepat. Berikut adalah contoh file OPA Rego sederhana:

package example default allow = false allow { input.method == "GET" input.path =="/api/resource" input.user.role == "admin" }

Dalam contoh ini, kami memiliki paket yang disebut "example" yang mendefinisikan aturan yang disebut "allow". Aturan "allow" menentukan bahwa permintaan diizinkan jika metode input adalah "GET", jalur yang diminta adalah /api/resource, dan peran pengguna adalah "admin". Jika kondisi ini terpenuhi, maka aturan "allow" akan dievaluasi sebagai "true", memungkinkan permintaan untuk dilanjutkan.

Mengapa menggunakan OPA dan API Gateway untuk RBAC?

API Gateway menyediakan lokasi terpusat untuk mengkonfigurasi dan mengelola API, serta konsumen API. Ini dapat digunakan sebagai gateway autentikasi terpusat dengan menghindari setiap layanan individu mengimplementasikan logika autentikasi di dalam layanan itu sendiri. Di sisi lain, OPA menambahkan lapisan otorisasi dan memisahkan kebijakan dari kode dengan menciptakan manfaat yang berbeda untuk otorisasi. Dengan kombinasi ini, Anda dapat menambahkan izin untuk sumber daya API ke suatu peran. Pengguna mungkin terkait dengan satu atau lebih peran pengguna. Setiap peran pengguna mendefinisikan serangkaian izin (GET, PUT, DELETE) pada sumber daya RBAC (didefinisikan oleh jalur URI). Di bagian selanjutnya, mari kita pelajari cara mencapai RBAC menggunakan kedua alat ini.

Open Policy Agent dengan Apache APISIX API Gateway

Bagaimana mengimplementasikan RBAC dengan OPA dan Apache APISIX

Di Apache APISIX, Anda dapat mengkonfigurasi rute dan plugin untuk mendefinisikan perilaku API Anda. Anda dapat menggunakan plugin opa APISIX untuk menegakkan kebijakan RBAC dengan meneruskan permintaan ke OPA untuk pengambilan keputusan. Kemudian OPA membuat keputusan otorisasi berdasarkan peran dan izin pengguna secara real-time.

Asumsikan bahwa kami memiliki Conference API di mana Anda dapat mengambil/mengedit sesi acara, topik, dan informasi pembicara. Seorang pembicara hanya dapat membaca sesi dan topik mereka sendiri sementara admin dapat menambah/mengedit lebih banyak sesi dan topik. Atau peserta dapat memberikan umpan balik tentang sesi pembicara melalui permintaan POST ke /speaker/speakerId/session/feedback dan pembicara hanya dapat melihat dengan meminta metode GET dari URI yang sama. Diagram di bawah ini menggambarkan seluruh skenario:

Open Policy Agent dengan Apache APISIX

  1. Konsumen API meminta rute di API Gateway dengan kredensialnya seperti token JWT di header authorization.
  2. API Gateway mengirimkan data konsumen dengan header JWT ke mesin OPA.
  3. OPA mengevaluasi apakah konsumen memiliki hak untuk mengakses sumber daya dengan menggunakan kebijakan (peran dan izin) yang kami tentukan dalam file .rego.
  4. Jika keputusan OPA diizinkan, maka permintaan akan diteruskan ke layanan Conference upstream.

Selanjutnya, kami menginstal, mengkonfigurasi APISIX, dan mendefinisikan kebijakan di OPA.

Prasyarat

  • Docker digunakan untuk menginstal etcd dan APISIX yang dikontainerisasi.
  • curl digunakan untuk mengirim permintaan ke API Admin APISIX. Anda juga dapat menggunakan alat seperti Postman untuk berinteraksi dengan API.

Langkah 1: Instal Apache APISIX

APISIX dapat dengan mudah diinstal dan dijalankan dengan skrip quickstart berikut:

curl -sL https://run.api7.ai/apisix/quickstart | sh

Langkah 2: Konfigurasi layanan backend (upstream)

Untuk mengarahkan permintaan ke layanan backend untuk Conference API, Anda perlu mengkonfigurasinya dengan menambahkan server upstream di Apache APISIX melalui Admin API.

curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -X PUT -d ' { "name":"Conferences API upstream", "desc":"Register Conferences API as the upstream", "type":"roundrobin", "scheme":"https", "nodes":{ "conferenceapi.azurewebsites.net:443":1 } }'

Langkah 3: Buat konsumen API

Selanjutnya, kami membuat konsumen (pembicara baru) dengan nama pengguna jack di Apache APISIX. Ini mengatur plugin jwt-auth untuk konsumen dengan kunci dan rahasia yang ditentukan. Ini akan memungkinkan konsumen untuk melakukan autentikasi menggunakan JSON Web Token (JWT).

curl http://127.0.0.1:9180/apisix/admin/consumers -X PUT -d ' { "username": "jack", "plugins": { "jwt-auth": { "key": "user-key", "secret": "my-secret-key" } } }'

Langkah 4: Buat endpoint publik untuk menghasilkan token JWT

Anda juga perlu menyiapkan Rute baru yang menghasilkan dan menandatangani token menggunakan plugin public-api. Dalam skenario ini, API Gateway bertindak sebagai server penyedia identitas untuk membuat dan memverifikasi token dengan kunci konsumen jack kami. Penyedia identitas juga dapat berupa layanan pihak ketiga lainnya seperti Google, Okta, Keycloak, dan Ory Hydra.

curl http://127.0.0.1:9180/apisix/admin/routes/jas -X PUT -d ' { "uri": "/apisix/plugin/jwt/sign", "plugins": { "public-api": {} } }'

Langkah 5: Klaim token JWT baru untuk konsumen API

Sekarang kita bisa mendapatkan token baru untuk pembicara kami Jack dari API Gateway menggunakan endpoint publik yang kami buat. Perintah curl berikut menghasilkan token baru dengan kredensial Jack dan menetapkan peran, dan izin dalam payload.

curl -G --data-urlencode 'payload={"role":"speaker","permission":"read"}' http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key -i

Setelah Anda menjalankan perintah di atas, Anda akan menerima token sebagai respons. Simpan token ini di suatu tempat, nanti kita akan menggunakan token ini untuk mengakses endpoint API Gateway baru kami.

Langkah 6: Buat konfigurasi plugin baru

Langkah ini melibatkan pengkonfigurasian 3 plugin APISIX, proxy-rewrite, jwt-auth dan opa.

curl "http://127.0.0.1:9180/apisix/admin/plugin_configs/1" -X PUT -d ' { "plugins":{ "jwt-auth":{ }, "proxy-rewrite":{ "host":"conferenceapi.azurewebsites.net" } } }'
  • Plugin proxy-rewrite dikonfigurasi untuk memproksi permintaan ke host conferenceapi.azurewebsites.net.
  • Plugin autentikasi OPA dikonfigurasi untuk menggunakan mesin kebijakan OPA yang berjalan di http://localhost:8181/v1/data/rbacExample. Juga, APISIX mengirim semua informasi terkait konsumen ke OPA. Kami akan menambahkan file kebijakan .rego ini di bagian konfigurasi Opa.

Langkah 7: Buat Rute untuk sesi Conference

Langkah terakhir adalah membuat rute baru untuk sesi pembicara Conference API:

curl "http://127.0.0.1:9180/apisix/admin/routes/1" -X PUT -d ' { "name":"Conferences API speaker sessions route", "desc":"Create a new route in APISIX for the Conferences API speaker sessions", "methods": ["GET", "POST"], "uris": ["/speaker/*/topics","/speaker/*/sessions"], "upstream_id":"1", "plugin_config_id":1 }'

Payload berisi informasi tentang rute, seperti namanya, deskripsi, metode, URI, ID upstream, dan ID konfigurasi plugin. Dalam kasus ini, rute dikonfigurasi untuk menangani permintaan GET dan POST untuk dua URI yang berbeda, /speaker/topics dan /speaker/sessions. Bidang "upstream_id" menentukan ID layanan upstream yang akan menangani permintaan masuk untuk rute ini, sementara bidang "plugin_config_id" menentukan ID konfigurasi plugin yang akan digunakan untuk rute ini.

Langkah 8: Uji pengaturan tanpa OPA

Sejauh ini, kami telah menyiapkan semua konfigurasi yang diperlukan untuk APISIX untuk mengarahkan permintaan masuk ke endpoint Conference API, hanya mengizinkan konsumen API yang berwenang. Sekarang, setiap kali konsumen API ingin mengakses endpoint, mereka harus menyediakan token JWT untuk mengambil data dari layanan backend Conference. Anda dapat memverifikasi ini dengan mengakses endpoint dan alamat domain yang kami minta sekarang adalah API Gateway kustom kami tetapi bukan layanan Conference yang sebenarnya:

curl -i http://127.0.0.1:9080/speaker/1/topics -H 'Authorization: {API_CONSUMER_TOKEN}'

Langkah 9: Jalankan layanan OPA

Dua langkah lainnya adalah kami menjalankan layanan OPA menggunakan Docker dan mengunggah definisi kebijakan kami menggunakan API-nya yang dapat digunakan untuk mengevaluasi kebijakan otorisasi untuk permintaan masuk.

docker run -d --network=apisix-quickstart-net --name opa -p 8181:8181 openpolicyagent/opa:latest run -s

Perintah Docker ini menjalankan kontainer dari gambar OPA dengan versi terbaru. Ini membuat kontainer baru di jaringan APISIX yang ada apisix-quickstart-net dengan nama opa dan mengekspos port 8181. Jadi, APISIX dapat mengirim permintaan pemeriksaan kebijakan ke OPA langsung menggunakan alamat [http://opa:8181](http://opa:8181) Perhatikan bahwa OPA dan APISIX harus berjalan di jaringan docker yang sama.

Langkah 10: Definisikan dan daftarkan kebijakan

Langkah kedua di sisi OPA adalah Anda perlu mendefinisikan kebijakan yang akan digunakan untuk mengontrol akses ke sumber daya API. Kebijakan ini harus mendefinisikan atribut yang diperlukan untuk akses (Pengguna mana yang memiliki peran mana) dan izin (Peran mana yang memiliki izin mana) yang diizinkan atau ditolak berdasarkan atribut tersebut. Misalnya, dalam konfigurasi di bawah ini, kami mengatakan kepada OPA untuk memeriksa tabel user_roles apa peran untuk jack. Informasi ini dikirim oleh APISIX di dalam input.consumer.username. Juga, kami memverifikasi izin konsumen dengan membaca payload JWT dan mengekstrak token.payload.permission dari sana. Komentar menjelaskan langkah-langkahnya dengan jelas.

curl -X PUT '127.0.0.1:8181/v1/policies/rbacExample' \ -H 'Content-Type: text/plain' \ -d 'package rbacExample # Menetapkan peran pengguna user_roles := { "jack": ["speaker"], "bobur":["admin"] } # Penetapan izin peran role_permissions := { "speaker": [{"permission": "read"}], "admin": [{"permission": "read"}, {"permission": "write"}] } # Fungsi JWT Pembantu bearer_token := t { t := input.request.headers.authorization } # Dekode token otorisasi untuk mendapatkan peran dan izin token = {"payload": payload} { [_, payload, _] := io.jwt.decode(bearer_token) } # Logika yang mengimplementasikan RBAC default allow = false allow { # Cari daftar peran untuk pengguna roles := user_roles[input.consumer.username] # Untuk setiap peran dalam daftar tersebut r := roles[_] # Cari daftar izin untuk peran r permissions := role_permissions[r] # Untuk setiap izin p := permissions[_] # Periksa apakah izin yang diberikan kepada r cocok dengan permintaan pengguna p == {"permission": token.payload.permission} }'

Langkah 11: Perbarui konfigurasi plugin yang ada dengan plugin OPA

Setelah kami mendefinisikan kebijakan di layanan OPA, kami perlu memperbarui konfigurasi plugin yang ada untuk rute agar menggunakan plugin OPA. Kami menentukan dalam atribut policy dari plugin OPA.

curl "http://127.0.0.1:9180/apisix/admin/plugin_configs/1" -X PATCH -d ' { "plugins":{ "opa":{ "host":"http://opa:8181", "policy":"rbacExample", "with_consumer":true } } }'

Langkah 12: Uji pengaturan dengan OPA

Sekarang kita dapat menguji semua pengaturan yang kami lakukan dengan kebijakan OPA. Jika Anda mencoba menjalankan perintah curl yang sama untuk mengakses endpoint API Gateway, pertama-tama akan memeriksa token JWT sebagai proses autentikasi dan mengirim data konsumen dan token JWT ke OPA untuk memverifikasi peran dan izin sebagai proses otorisasi. Setiap permintaan tanpa token JWT atau peran yang diizinkan akan ditolak.

curl -i http://127.0.0.1:9080/speaker/1/topics -H 'Authorization: {API_CONSUMER_TOKEN}'

Kesimpulan

Dalam artikel ini, kami belajar bagaimana mengimplementasikan RBAC dengan OPA dan Apache APISIX. Kami mendefinisikan logika kebijakan kustom sederhana untuk mengizinkan/menolak akses sumber daya API berdasarkan peran dan izin konsumen API kami. Juga, tutorial ini menunjukkan bagaimana kami dapat mengekstrak informasi terkait konsumen API dalam file kebijakan dari payload token JWT atau objek konsumen yang dikirim oleh APISIX.

Sumber daya terkait

Konten yang direkomendasikan

Tags: