Episode ini mengamankan gateway dari sisi gerbang masuk: autentikasi request lewat API key dan JWT/OIDC, otorisasi akses per rute dan per tool invocation, plus keamanan transport dengan TLS, mTLS, dan koneksi terenkripsi ke provider.

Di episode 11 kalian belajar menyimpan kredensial dengan aman: API key provider masuk ke secret manager, dirotasi rutin, dan hanya diberi least privilege. Itu mengamankan sisi kredensial, tapi ada satu lapisan yang belum: gerbang masuk gateway itu sendiri. Request yang datang harus bisa membuktikan siapa pengirimnya, rute mana yang boleh diaksesnya, tool apa yang boleh dipanggilnya, dan semua percakapan antara client, gateway, dan provider harus berjalan di jalur terenkripsi.
Episode 12 menyatukan tiga pilar keamanan perimeter: autentikasi request masuk (API key, JWT, OIDC), otorisasi akses rute dan tool invocation, serta keamanan transport dan koneksi provider.
Sebelum sebuah request boleh masuk ke route engine, 9router harus tahu siapa yang mengirimnya. Ini disebut autentikasi — verifikasi identitas. Tanpa ini, semua orang bisa menembak endpoint model kalian dan menguras biaya, atau memakai gateway sebagai proxy publik gratis.
9router menempatkan autentikasi di level gateway, sebelum routing. Artinya semua rute mewarisi perlindungan yang sama, dan kalian tidak perlu menulis logika auth di setiap service. Setiap perubahan config diuji dulu dengan 9router validate. Konfigurasi dasar di 9router.yaml:
auth:
api_keys:
- name: mobile-app
key_env: API_KEY_MOBILE
- name: internal-service
key_env: API_KEY_INTERNAL
jwks_url: https://idp.example.com/.well-known/jwks.json
required_claims:
- sub
- scopeDua mekanisme utama yang paling umum dipakai: API key untuk machine-to-machine, dan JWT (JSON Web Token) untuk identitas yang dipegang end-user. Keduanya bisa aktif bersamaan.
API key adalah token rahasia yang dikirim client lewat header. Ia cocok untuk service internal, mobile app, dan CI/CD pipeline — di mana tidak ada "pengguna manusia" yang login. Kunci konfigurasinya: key tidak pernah di-hardcode di file config, melainkan dibaca dari environment, persis pola yang kalian pelajari di episode 11.
Client mengirim key lewat header Authorization:
curl https://gw.example.com/v1/chat \
-H "Authorization: Bearer ${API_KEY_MOBILE}" \
-d '{"messages": [{"role": "user", "content": "Halo"}]}'Di 9router, key yang diterima dicocokkan dengan daftar di auth.api_keys. Setiap key mendapat consumer identity tersendiri, yang nanti dipakai untuk rate limiting dan audit — dua topik yang akan dibahas di episode berikutnya. Jika key tidak dikenal, gateway menjawab 401 Unauthorized sebelum request menyentuh provider.
9router auth list
9router auth verify --key api_key_mobileProses verifikasi berjalan di layer terdepan, sehingga key yang bocor bisa di-revoke per consumer tanpa menghentikan gateway — cukup hapus dari daftar dan rotasi key pengganti. Jangan pernah menaruh key di URL atau di body; header adalah tempat yang benar.
Untuk aplikasi yang melayani manusia, API key kurang pas — tidak ada cara untuk memetakan key ke peran seorang user. Solusinya adalah JWT yang diterbitkan oleh Identity Provider (IdP) melalui OpenID Connect (OIDC). Token ini berisi klaim seperti sub (siapa usernya), scope (apa yang boleh), dan exp (kapan kedaluwarsa).
9router memvalidasi token dengan mengambil JWKS dari IdP, memeriksa tanda tangan dan masa berlaku, lalu mengekstrak klaim untuk dipakai di lapisan otorisasi:
auth:
jwks_url: https://idp.example.com/.well-known/jwks.json
issuer: https://idp.example.com
audiences:
- gateway-prod
claims_to_metadata:
- source: sub
target: request.consumer_id
- source: scope
target: request.scopesSetelah verifikasi, klaim sub dan scope menempel pada request sebagai metadata. Inilah bahan bakar untuk otorisasi rute dan tool di bagian berikutnya. Kegagalan validasi (token kedaluwarsa, issuer salah, signature tidak cocok) mengembalikan 401 atau 403 sesuai kasusnya.
Info
Untuk service-to-service di dalam cluster yang tidak memakai IdP, pertimbangkan mTLS atau service account token — jangan kembali ke mode tanpa autentikasi hanya karena "saling kenal". Perimeter dalam sama pentingnya dengan perimeter luar.
Autentikasi membuktikan identitas; otorisasi memutuskan apa yang boleh dilakukan identitas itu. Di 9router keduanya dipisahkan sehingga kebijakan bisa diekspresikan per rute dan per tool. Seorang user boleh memanggil rute chat, tapi tidak boleh memanggil rute yang mengeksekusi tool pembayaran.
Otorisasi rute dinyatakan sebagai bagian dari definisi route:
routes:
- name: chat-general
match:
intent: general_chat
model: gpt-4o-mini
provider: openai-prod
access:
require_scope: chat:read
- name: tools-execute
match:
intent: execute_action
model: gpt-4o
provider: openai-prod
access:
require_scope: tools:writeSementara otorisasi tool dipisahkan agar satu route dengan banyak tool tetap punya kontrol granular. Tool invocation hanya dieksekusi jika consumer memenuhi syarat:
tools:
- name: create-ticket
access:
require_scope: tickets:write
execute: false
- name: read-orders
access:
require_scope: orders:read
execute: trueJika request lolos autentikasi tapi tidak memenuhi require_scope, gateway menolak dengan 403 Forbidden dan mencatat percobaan tersebut. Pola ini mencegah satu kredensial bocor membuka semua tool sekaligus.
Dua gaya otorisasi yang umum dipakai bersama: RBAC (Role-Based Access Control) memetakan peran ke scope, sedangkan ABAC (Attribute-Based Access Control) memutuskan berdasarkan atribut request — region asal, department, waktu, atau level user. RBAC menjawab "kamu siapa, jabatan apa", ABAC menjawab "konteks ini mengizinkan atau tidak".
auth:
roles:
- name: support-agent
scopes: [chat:read, tickets:write]
- name: analyst
scopes: [chat:read, orders:read]
abac_rules:
- name: block-offshore-tools
condition: request.region != eu
action: deny
applies_to: tools-executeRule ABAC dievaluasi setelah RBAC. Jadi meski seorang support-agent punya scope tickets:write, aturan block-offshore-tools bisa menolak eksekusi ketika request datang dari region di luar Eropa — contoh persis yang akan kalian dalami saat membahas data residency di episode 14.
Lapisan terakhir adalah transport security: pastikan data tidak melayang dalam keadaan terbaca di perjalanan. Aturan dasarnya adalah TLS wajib di mana-mana. 9router hanya melayani request HTTPS, dan untuk lingkungan paling ketat, mTLS memaksa client juga menampilkan sertifikat — dua arah yang saling memverifikasi.
tls:
min_version: "1.3"
cert_file: /etc/9router/tls/cert.pem
key_file: /etc/9router/tls/key.pem
mtls:
enabled: true
ca_file: /etc/9router/tls/ca.pemKoneksi ke provider LLM juga harus dikunci. API key yang kalian simpan di secret manager dikirim hanya melalui TLS, base URL provider harus https, dan untuk jaringan internal gunakan VPC peering atau private link supaya traffic model tidak menyeberangi internet publik:
providers:
- name: openai-prod
type: openai
base_url: https://api.openai.com/v1
api_key_env: OPENAI_API_KEY
verify: true
- name: azure-private
type: azure_openai
base_url: https://dev-gw.azure.net/v1
api_key_env: AZURE_OPENAI_KEY
private_endpoint: trueverify: true memastikan sertifikat server provider diverifikasi, dan private_endpoint menegaskan bahwa koneksi hanya lewat jalur privat — gabungkan dengan kebijakan di episode 6 (blocked intent) dan 11 (least privilege), maka rantai keamanan tertutup dari client sampai model.
Episode 12 menutup perimeter gateway dengan tiga lapisan: autentikasi lewat API key untuk machine-to-machine dan JWT/OIDC untuk identitas manusia, otorisasi granular per rute dan per tool invocation dengan RBAC plus ABAC, serta keamanan transport berupa TLS, mTLS, dan koneksi provider yang terenkripsi. Kini setiap request harus punya identitas yang terbukti, izin yang sesuai, dan jalur yang aman.
Inti yang harus dibawa pulang:
Gateway kalian kini punya pintu terkunci. Di episode 13 kita berhadapan dengan sisi gelapnya: Safeguards Against Malicious Requests — mendeteksi prompt tak aman dan adversarial input, menegakkan kebijakan konten terlarang dan PII, plus circuit breaker dan rate limit untuk mencegah abuse terhadap provider. Sampai jumpa di sana!