🔐 Sertifikat & SNI
certificates:
- cert: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
key: "${TLS_PRIVATE_KEY}"
snis:
- name: api.contoh.com
- name: mitra.contoh.com
SNI (Server Name Indication) memungkinkan satu simpul Kong menyajikan sertifikat berbeda untuk domain berbeda pada IP yang sama. Kong memilih sertifikat berdasarkan nama host yang diminta klien saat jabat tangan TLS.
Sertifikat kedaluwarsa adalah penyebab pemadaman yang sepenuhnya dapat dihindari, dan tetap terjadi berulang kali di banyak organisasi. Gunakan cert-manager bila Kong berjalan di Kubernetes, atau ACME client yang terjadwal di luar itu. Pasang juga alert yang berbunyi 14 hari sebelum kedaluwarsa sebagai jaring pengaman.
🤝 Mutual TLS
ca_certificates:
- cert: |
-----BEGIN CERTIFICATE-----
... sertifikat CA internal ...
-----END CERTIFICATE-----
id: ca-internal
plugins:
- name: mtls-auth
service: layanan-mitra
config:
ca_certificates: ["ca-internal"]
skip_consumer_lookup: false
revocation_check_mode: STRICT
TLS biasa membuktikan bahwa server adalah pihak yang benar. mTLS menambahkan arah sebaliknya: klien juga harus menunjukkan sertifikat yang ditandatangani CA yang Anda percayai. Ini tepat untuk integrasi mitra bernilai tinggi, komunikasi antar layanan internal, dan lingkungan dengan kewajiban kepatuhan.
Harganya adalah pengelolaan siklus hidup sertifikat klien — penerbitan, distribusi, rotasi, dan pencabutan. Bila proses itu belum ada, mTLS akan menjadi sumber pemadaman baru.
🛡️ Header Keamanan Seragam
plugins:
- name: response-transformer
config:
add:
headers:
- "Strict-Transport-Security:max-age=31536000; includeSubDomains"
- "X-Content-Type-Options:nosniff"
- "X-Frame-Options:DENY"
- "Referrer-Policy:strict-origin-when-cross-origin"
remove:
headers:
- "Server"
- "X-Powered-By"
Memasangnya di gateway berarti setiap layanan di belakangnya langsung terlindungi, termasuk layanan lama yang tidak akan diperbarui lagi.
🌐 CORS yang Tidak Membocorkan
plugins:
- name: cors
config:
origins: ["https://aplikasi.contoh.com"] # BUKAN "*"
methods: ["GET", "POST", "PUT", "DELETE"]
headers: ["Authorization", "Content-Type"]
exposed_headers: ["X-Request-Id"]
credentials: true
max_age: 3600
Kombinasi ini adalah kesalahan konfigurasi serius. Spesifikasi CORS melarangnya, dan implementasi yang longgar dapat membuat situs mana pun mengirim permintaan dengan cookie pengguna Anda dan membaca responsnya. Bila memakai credentials: true, daftarkan origin secara eksplisit — tanpa pengecualian.
✅ Daftar Periksa Sebelum Produksi
| Periksa | Kenapa |
|---|---|
| Admin API tidak terjangkau publik | Kendali penuh atas gateway ada di sana |
| Admin API dilindungi (mTLS/VPN/RBAC) | Lapisan kedua bila isolasi jaringan bocor |
| Semua rute produksi memakai HTTPS | Kredensial tidak melintas dalam bentuk polos |
key_in_query: false | Kunci di URL bocor ke log dan Referer |
exp ada di claims_to_verify | Tanpa ini token kedaluwarsa tetap diterima |
anonymous tidak disetel tanpa ACL | Membuat autentikasi menjadi opsional |
| CORS memakai origin eksplisit | Wildcard + credentials membuka celah |
| Rate limiting memakai policy terpusat | Policy local tidak akurat di banyak simpul |
| Layanan hanya menerima koneksi dari Kong | Mencegah pemalsuan header identitas |
| Sertifikat diperbarui otomatis + alert | Kedaluwarsa adalah pemadaman yang dapat dicegah |
request-size-limiting aktif | Mencegah unggahan raksasa membanjiri layanan |
| Rahasia dari variabel lingkungan/vault | Tidak ada kredensial di Git |