Episode ini membahas filter keamanan Envoy: external authentication dengan ext_authz, JWT authentication filter, filter otorisasi HTTP, serta content-based routing dan request inspection.

Episode 12 dan 13 menyentuh keamanan secara umum. Episode 14 memfokuskan pada filter keamanan: alat konkret yang dipasang di pipeline Envoy untuk menegakkan autentikasi dan otorisasi — ext_authz untuk keputusan eksternal, filter JWT untuk verifikasi token native, filter otorisasi HTTP, serta request inspection dan content-based routing.
ext_authz mengirimkan metadata request ke layanan autentikasi gRPC dan menunggu keputusan:
http_filters:
- name: envoy.filters.http.ext_authz
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
transport_api_version: V3
grpc_service:
envoy_grpc:
cluster_name: auth_service
failure_mode_allow: false
clear_route_cache: true
allowed_headers:
patterns:
- exact: authorization
- exact: cookie
buffer_limits:
max_request_bytes: 8192
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterDengan failure_mode_allow: false, jika layanan auth tidak bisa dijangkau, request ditolak — kebijakan fail-closed yang tepat. allowed_headers membatasi header yang boleh dilihat layanan auth, meminimalkan data sensitif yang keluar.
Layanan ext_authz mengikuti kontrak gRPC Check. Contoh minimal dengan bahasa Go:
func (s *server) Check(ctx context.Context, req *envoyservice.CheckRequest) (*envoyservice.CheckResponse, error) {
token := req.GetAttributes().GetRequest().GetHttp().GetHeaders()["authorization"]
if !validToken(token) {
return denied(), nil
}
return allowed(), nil
}Fungsi Check menerima metadata request dan mengembalikan allowed atau denied. Kode ini adalah kerangka yang bisa dikembangkan menjadi kebijakan apa pun.
Filter JWT memverifikasi token langsung di Envoy tanpa layanan eksternal:
http_filters:
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
oidc_provider:
issuer: https://auth.example.com/
audiences:
- orders-api
remote_jwks:
http_uri:
uri: https://auth.example.com/.well-known/jwks.json
cluster: auth_jwks
timeout: 5s
cache_duration: 300s
forward_payload_header: x-jwt-payload
rules:
- match:
prefix: "/orders"
requires:
provider_name: oidc_provider
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterProvider oidc_provider mendefinisikan issuer, audience, dan sumber JWKS. Filter mengambil kunci publik dari remote_jwks, memverifikasi tanda tangan token, dan menolak token dengan issuer yang tidak dikenal.
Aturan JWT diterapkan per path: semua path /orders wajib memiliki token valid dari oidc_provider. Path lain bebas. Pola ini memungkinkan API campuran: sebagian endpoint publik, sebagian dilindungi JWT.
forward_payload_header: x-jwt-payloadSetelah verifikasi sukses, payload JWT diteruskan di header x-jwt-payload. Service internal membaca klaim seperti sub dan scope tanpa perlu memverifikasi token lagi.
Otorisasi berbasis header cocok untuk aturan sederhana yang dievaluasi cepat:
http_filters:
- name: envoy.filters.http.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
action: ALLOW
policies:
admin_only:
permissions:
- any: true
principals:
- header:
name: X-User-Role
exact_match: admin
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterFilter rbac memeriksa nilai header X-User-Role. Hanya request dengan nilai admin yang diizinkan; sisanya mendapat 403. Kombinasi dengan JWT: token diverifikasi dulu, header role dihasilkan, lalu RBAC membacanya.
Selain keamanan, filter bisa dipakai untuk menginspeksi isi request dan me-route berdasarkan konten:
routes:
- match:
prefix: "/api/"
headers:
- name: X-Tenant
string_match:
exact: tenant-a
route:
cluster: tenant_a_backend
- match:
prefix: "/api/"
query_parameters:
- name: beta
string_match:
exact: "1"
route:
cluster: beta_backendAturan match.headers dan match.query_parameters memungkinkan routing berdasarkan isi request. Ini disebut content-based routing — berguna untuk mengarahkan traffic berdasarkan konteks.
Untuk menguji seluruh rangkaian filter, kirim request dengan token valid dan tanpa token:
curl -s -o /dev/null -w "%{http_code}\n" \
-H "Host: api.example.com" http://localhost:10000/orders
curl -s -o /dev/null -w "%{http_code}\n" \
-H "Host: api.example.com" -H "Authorization: Bearer <TOKEN>" \
-H "X-User-Role: admin" http://localhost:10000/ordersRequest pertama seharusnya ditolak (token hilang), request kedua diizinkan. Perintah curl -w "%{http_code}" tetap cara tercepat memverifikasi keputusan tiap filter.
Untuk pipeline keamanan, urutan yang umum adalah:
Setiap filter memperkecil permukaan yang dilihat filter berikutnya. JWT menghasilkan identitas, ext_authz dan RBAC mengonsumsi identitas itu untuk mengambil keputusan.
curl -s localhost:9901/config_dump | grep -E '"name": "envoy.filters.http'Grep envoy.filters.http pada config_dump menampilkan urutan filter yang sebenarnya dimuat — gunakan ini untuk memastikan urutan sesuai rencana.
Episode 14 melengkapi toolkit keamanan Envoy: ext_authz untuk keputusan eksternal, filter JWT untuk verifikasi token native, RBAC berbasis header, dan content-based routing untuk inspeksi request.
Inti yang harus dibawa pulang:
ext_authz mendelegasikan keputusan auth ke layanan gRPC eksternal.forward_payload_header meneruskan klaim ke service internal.match.headers dan query_parameters memungkinkan content-based routing.Di episode 15 selanjutnya kita akan membahas performance tuning dan resource management — threading model Envoy, worker threads, connection limits, buffer sizes, HTTP/2 pool tuning, serta optimasi CPU dan memori.