Episode ini mengubah NGINX menjadi gerbang autentikasi: memahami auth_request sebagai sub-request verifikasi, membangun lokasi internal untuk endpoint Authelia, meneruskan header X-Original-URL dan Remote-User, serta mengatur redirect ke portal saat permintaan belum terautentikasi.

Di episode 12 kalian mengelola sisi pengguna — password, reset, hingga menonaktifkan akun. Namun seluruh fitur itu baru berarti jika ada sesuatu yang benar-benar menjaga pintu. Mulai episode ini kita masuk fase baru: integrasi reverse proxy. Dan kita mulai dari proxy yang paling banyak dipakai di ekosistem self-hosted: NGINX.
Authelia tidak pernah menjadi pengganti reverse proxy. Ia adalah penjaga yang bertanya dulu, meloloskan kemudian. Peran ini dijalankan lewat pola forward authentication: sebelum permintaan diteruskan ke aplikasi, proxy mengirim sub-request ke Authelia untuk bertanya "apakah user ini boleh masuk?". Jawaban 2xx berarti lanjut; 401 berarti tolak.
Analogi: kalian bekerja di gedung yang pintunya dijaga satpam (NGINX). Setiap tamu datang, satpam menelpon resepsionis (Authelia) untuk memastikan nama tamu terdaftar. Hanya jika resepsionis menjawab "aman", satpam mempersilakan masuk. NGINX menyediakan fitur ini lewat direktif auth_request.
auth_request adalah direktif NGINX yang mengirim sub-request ke sebuah lokasi internal. Cara kerjanya sederhana dan tegas:
Penting: sub-request ini tidak mengubah status respons yang diterima browser, dan NGINX menandai lokasi endpoint verifikasi sebagai internal agar tidak bisa diakses langsung dari internet.
Endpoint verifikasi Authelia untuk pola ini adalah /api/authz/auth-request. Kita sembunyikan di balik lokasi internal:
set $upstream_authelia http://authelia:9091/api/authz/auth-request;
location /internal/authelia/authz {
internal;
proxy_pass $upstream_authelia;
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Original-URL $scheme://$host$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Content-Length "";
proxy_set_header Connection "";
proxy_pass_request_body off;
proxy_http_version 1.1;
}Beberapa hal yang perlu dipahami:
internal; — lokasi ini hanya bisa dipanggil dari dalam NGINX (oleh auth_request), bukan dari browser.X-Original-URL dan X-Original-Method — memberi tahu Authelia apa yang sedang diminta user. Authelia memakai nilai ini untuk mengevaluasi access control rules (episode 6) dan menentukan URL redirect.proxy_pass_request_body off; — sub-request verifikasi tidak perlu membawa body permintaan asli. Ini menghemat resource sekaligus mencegah data permintaan bocor ke endpoint verifikasi.Header X-Forwarded-* di lokasi ini juga penting: Authelia membaca skema, host, dan IP asli untuk menilai kebijakan berbasis jaringan. Tanpa header ini, semua permintaan tampak datang dari alamat internal NGINX — dan aturan berbasis IP yang kita pelajari di episode 6 tidak akan bekerja.
Sekarang blok server untuk aplikasi yang dilindungi:
server {
listen 443 ssl;
server_name app.example.com;
include /etc/nginx/snippets/ssl.conf;
set $upstream_app http://app:8080;
set $upstream_authelia http://authelia:9091/api/authz/auth-request;
location /internal/authelia/authz {
internal;
proxy_pass $upstream_authelia;
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Original-URL $scheme://$host$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Content-Length "";
proxy_set_header Connection "";
proxy_pass_request_body off;
proxy_http_version 1.1;
}
location / {
proxy_pass $upstream_app;
proxy_set_header Host $host;
auth_request /internal/authelia/authz;
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
auth_request_set $name $upstream_http_remote_name;
auth_request_set $email $upstream_http_remote_email;
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
proxy_set_header Remote-Name $name;
proxy_set_header Remote-Email $email;
auth_request_set $redirection_url $upstream_http_location;
error_page 401 =302 $redirection_url;
}
}Bagian-bagian penting dari blok di atas:
auth_request /internal/authelia/authz; — titik yang menghubungkan aplikasi ke endpoint verifikasi.auth_request_set — menyimpan header respons dari Authelia ke variabel NGINX. Authelia mengembalikan identitas user pada header Remote-User, Remote-Groups, Remote-Name, dan Remote-Email.error_page 401 =302 $redirection_url; — saat Authelia menolak, NGINX melempar redirect 302 ke URL yang dikirim Authelia lewat header Location (portal login dengan parameter rd untuk kembali ke halaman semula).Tip
Aturan penting: proxy_set_header Host $host; harus ada agar aplikasi di belakangnya menerima nama domain yang benar. Tanpa itu, beberapa aplikasi menganggap permintaan datang dari alamat internal dan menolak atau salah merender link.
Aplikasi yang dilindungi tidak pernah melihat password atau sesi Authelia — mereka hanya melihat header. Inilah yang disebut Trusted Header SSO: aplikasi mempercayai nilai Remote-User sebagai identitas user karena hanya proxy yang bisa memasangnya.
Dampaknya besar bagi aplikasi yang mendukung pola ini: Grafana, Gitea, dan banyak aplikasi lain bisa otomatis login berdasarkan header Remote-User tanpa pernah menyediakan form loginnya sendiri. Kalian mendapatkan SSO sejati — satu login di portal Authelia, lalu semua aplikasi menganggap user sudah dikenal.
Namun kekuatannya adalah tanggung jawab: header ini bisa dipalsukan jika aplikasi dapat dijangkau langsung, melewati NGINX. Pastikan aplikasi hanya bisa diakses lewat proxy, dan pastikan NGINX menimpa nilai Remote-* dari klien — dengan proxy_set_header, nilai palsu dari luar tidak akan lolos ke backend.
Setelah konfigurasi aktif, uji dengan alur yang tenang:
/api/authz/auth-request mengembalikan 200.Remote-User terisi — misalnya dengan aplikasi sederhana yang menampilkan seluruh request header.Masalah yang paling sering terjadi bukan di Authelia, melainkan di header: lupa X-Original-URL membuat redirect rd salah, lupa proxy_set_header Host membuat aplikasi bingung, dan tanpa error_page 401 browser hanya melihat halaman kosong 401 alih-alih portal. Sebelum memuat ulang, uji sintaks konfigurasi dengan nginx -t.
Important
Ingat pola dari episode 6: access control rules dievaluasi terhadap URL asli yang dikirim lewat X-Original-URL. Jika aturan menolak, Authelia mengembalikan 401 dan alur redirect bekerja. Jika yang keluar adalah 403 terus-menerus untuk user yang seharusnya boleh masuk, periksa domain di rules — bukan konfigurasi NGINX.
Episode ini mengubah NGINX menjadi gerbang autentikasi: memahami auth_request sebagai sub-request verifikasi, membangun lokasi internal untuk endpoint /api/authz/auth-request, meneruskan header X-Original-URL dan X-Forwarded-*, mengambil identitas user dari header Remote-*, serta mengarahkan permintaan yang ditolak ke portal lewat error_page 401.
Pola yang kalian kuasai di sini — proxy bertanya, Authelia menjawab, proxy meneruskan — adalah bahasa yang sama yang dipakai seluruh episode fase ini. Di episode 14, kita menerapkan bahasa itu pada proxy yang populer di dunia container: Traefik, dengan middleware forwardAuth dan konfigurasi berbasis Docker labels. Sampai jumpa!