Menggunakan kunci simetris (HMAC) untuk memvalidasi JSON Web Token (JWT) di arsitektur microservices memicu risiko keamanan horizontal yang masif. Satu layanan konsumen yang terkompromi dapat mengekstraksi shared secret tersebut dan menggunakannya untuk menerbitkan token palsu dengan hak akses arbitrer ke layanan lain. Solusi standar industri untuk mengisolasi batas kepercayaan (trust boundary) ini adalah penandatanganan asimetris (RS256/ES256) yang dipadukan dengan validasi JSON Web Key Set (JWKS) publik.
Risiko Kebocoran Shared Secret pada Sistem Terdistribusi
Pada skema simetris (HS256), entitas penerbit (Authorization Server) dan entitas verifikator (Resource Servers) memegang kunci rahasia yang identik. Konsekuensinya:
- Blast radius maksimal: Jika satu microservice pihak ketiga atau servis non-kritis berhasil dibobol via remote code execution (RCE) atau inspeksi memori, kunci rahasia tersebut bocor untuk seluruh kluster.
- Ketiadaan non-repudiation: Layanan otentikasi tidak dapat membuktikan secara kriptografis bahwa token bukan dibuat oleh salah satu service internal yang memegang secret tersebut.
- Kompleksitas rotasi: Mengganti secret membutuhkan deployment serentak di semua service tanpa jeda, yang hampir selalu menimbulkan race condition atau downtime parsing token.
Analogi ideal arsitektur ini menyerupai sistem paspor fisik: instansi imigrasi pusat mencetak paspor dengan stempel segel tak tertiru (private key), sementara petugas di setiap perbatasan negara independen cukup membawa katalog spesimen cap resmi (public key) untuk memverifikasi keaslian tanpa pernah mampu menduplikasi alat stempel aslinya.
Skema Asimetris: RS256 vs ES256
Otentikasi lintas layanan modern menggunakan kunci publik-privat. Authorization Server menandatangani payload menggunakan private key, sedangkan microservice konsumen hanya perlu mengambil public key dari endpoint JWKS (biasanya diakses via /.well-known/jwks.json).
- RS256 (RSA Signature with SHA-256): Ukuran key 2048-bit hingga 4096-bit. Kompatibilitas sangat luas di berbagai legacy runtime, namun payload token berukuran besar dan operasi verifikasi memakan CPU cycles lebih tinggi.
- ES256 (ECDSA using P-256 and SHA-256): Menggunakan kurva eliptik. Menyediakan tingkat keamanan setara RS256-3072 bit hanya dengan ukuran key 256-bit. Sangat direkomendasikan untuk throughput tinggi dan komunikasi antar microservice berlatensi rendah.
Mitigasi Celah Kriptografis: Alg Confusion & Key Spoofing
Mengimplementasikan verifikasi berbasis remote public key membawa dua vektor serangan utama yang harus ditutup secara eksplisit di level kode:
1. Algorithm Confusion Attack
Penyerang mengubah header token dari "alg": "RS256" menjadi "alg": "HS256", lalu menandatangani token menggunakan kunci publik RS256 Auth Server yang tersedia terbuka. Jika library verifikator tidak mengunci algoritma secara kaku, library akan memperlakukan string kunci publik sebagai secret HMAC mentah, sehingga token palsu dianggap valid. Mitigasi: Wajib deklarasikan parameter algoritma yang diizinkan (whitelisting) secara statis di verifikator.
2. Key Spoofing via Header Injection (jku / jwk)
Penyerang menyisipkan field jku (JWK Set URL) atau jwk (inline public key) di header JWT yang mengarah ke server pengendali mereka. Mitigasi: Abaikan header jku atau jwk yang dikirim dari request klien. Service konsumen hanya boleh mengambil kunci dari URI JWKS internal yang sudah di-hardcode atau dikonfigurasi melalui environment variable tepercaya.
Implementasi Verifikasi JWKS dan In-Memory Caching
Mengambil JWKS via HTTP pada setiap request akan mengakibatkan denial of service (DoS) internal pada Auth Server dan menambah latensi jaringan secara signifikan. Kunci publik harus di-cache di memori dengan mekanisme rate-limiting saat cache-miss terjadi (ketika token memiliki kid baru).
Berikut implementasi minimal, aman, dan efisien menggunakan Node.js dan library standar jose:
import { createRemoteJWKSet, jwtVerify } from 'jose';
// Inisialisasi JWKS client dengan built-in caching dan request throttling
const JWKS_URI = new URL(process.env.AUTH_JWKS_URI || 'https://auth.internal.corp/.well-known/jwks.json');
// ponytail: caching memory terpusat; jika multi-instance per node butuh shared cache, gunakan Redis
const JWKS = createRemoteJWKSet(JWKS_URI, {
cooldownDuration: 30_000, // Minimal delay 30s sebelum mencoba fetch ulang kid yang tidak dikenal (Cegah DoS)
cacheMaxAge: 600_000, // Cache key di memori selama 10 menit
});
export async function authenticateToken(jwtString) {
try {
const { payload, protectedHeader } = await jwtVerify(jwtString, JWKS, {
issuer: 'https://auth.internal.corp', // Klaim wajib: iss
audience: 'order-service.internal.corp', // Klaim wajib: aud
algorithms: ['ES256', 'RS256'], // Mitigasi Alg-Confusion: Kunci algoritma eksplisit
});
return { valid: true, identity: payload };
} catch (err) {
// Tangani token kedaluwarsa, signature mismatch, atau issuer salah
return { valid: false, error: err.code || err.message };
}
}
Catatan Validasi Klaim Wajib: Selalu evaluasi klaim
iss(penjamin identitas),aud(tujuan spesifik layanan Anda), danexp(kedaluwarsa). Layanan pembayaran tidak boleh menerima token yang diterbitkan untuk microservice inventaris, meskipun token tersebut valid secara kriptografis.
Prosedur Rotasi Key Tanpa Downtime
Untuk memutar kunci privat tanpa memutus sesi pengguna aktif atau request antarlayanan, terapkan pola Dual-Key Rollover:
- Generate Key Baru: Buat pasangan kunci baru (misal:
kid: "auth-key-2026-v2"). Masukkan public key baru ke endpoint JWKS. Pada fase ini, JWKS mempublikasikan dua kunci publik sekaligus (kunci lamav1dan kunci baruv2). - Tunggu Propagasi Cache: Biarkan konfigurasi berjalan setidaknya sepanjang nilai
cacheMaxAgepada service verifikator terlama agar cache public key terisi datav2. - Alihkan Penandatanganan: Ubah konfigurasi Auth Server untuk mulai menandatangani token keluar menggunakan private key
v2. Microservice konsumen langsung memvalidasi token baru karena public keyv2telah tersedia di cache lokal masing-masing. - Pensiunkan Kunci Lama: Setelah seluruh token bertanda tangan
v1melewati batas kedaluwarsanya (max(token.exp)), hapus public keyv1dari endpoint JWKS.
Ringkasan Trade-Off
Validasi JWKS publik menghilangkan risiko penyebaran secret secara mutlak dan memungkinkan rotasi kredensial independen. Trade-off arsitekturalnya berada pada kompleksitas manajemen cache verifikator dan dependensi jaringan pada JWKS fetch awal saat cold-start service. Pastikan mekanisme fallback atau retrying diterapkan pada inisialisasi verifikator untuk menghindari kegagalan startup massal saat Auth Server sedang cold boot.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!