Pendahuluan

Layanan otentikasi Axum di Rust harus mampu menjaga credential yang sensitif sekaligus membatasi request berbahaya. Artikel ini menunjukkan bagaimana merangkai token/session yang aman, pengelolaan secret dan rotasi, validasi payload, proteksi upload, serta mekanisme rate limit dan monitoring abuse secara terintegrasi.

Langkah-langkah yang dibahas mencakup penerapan middleware Axum (Tower layer), penyimpanan terdistribusi seperti Redis, serta konfigurasi deployment supaya server tidak mudah diekspos terhadap brute force atau upload berbahaya.

Arsitektur Layanan Otentikasi Axum

Komponen inti

Desain layanan memerlukan beberapa komponen: endpoint auth (login/logout), penyimpanan secret/credential, middleware token/session, validator payload/upload, dan lapisan proteksi rate limit. Setiap komponen harus memegang prinsip defense in depth tanpa menurunkan pengalaman pengguna.

Token dan session yang aman

Gunakan token JWT dengan algoritma asymmetrically signed atau session ID acak yang disimpan bersama data di Redis. Saat aplikasi memverifikasi token, pastikan:

  • Nilai exp pendek (misal 15 menit) agar token cepat kedaluwarsa.
  • Token disimpan di cookie HttpOnly dan Secure untuk mencegah XSS, atau di header Authorization: Bearer jika strateginya stateless.
  • Session ID diverifikasi terhadap store (Redis) yang menyimpan IP/agent jika perlu.

Contoh pola validasi middleware:

async fn auth_middleware(req: Request, next: Next) -> Response {    if let Some(token) = req.headers().typed_get::>() {        if let Ok(claims) = verify_jwt(&token.token) {            req.extensions_mut().insert(claims);            return next.run(req).await;        }    }    Response::builder().status(StatusCode::UNAUTHORIZED).body(Body::empty()).unwrap()}

Penanganan token yang gagal harus terstandarisasi agar tidak bocor informasi tentang alasan kegagalan (misal, tetap balas 401).

Pengelolaan secret dan rotasi

Secret signing (RSA/ECDSA private key) tidak boleh disimpan di repo. Gunakan vault (Vault Hashicorp, AWS Secrets Manager) atau minimal environment variables dengan enkripsi saat disimpan. Rotasi secret dilakukan dengan strategi roll-forward:

  1. Siapkan secret baru di vault dan distribusikan ke instance.
  2. Biarkan middleware menerima secret lama dan baru selama waktu transisi.
  3. Setelah semua instance memperbarui, hapus secret lama dari rotasi.

Jangan lupa untuk mereplikasi secret ke storage session (misal, key untuk enkripsi session ID) dan perbarui library ke versi patch terakhir secara berkala.

Validasi Payload dan Proteksi Upload

Validasi request

Gunakan crate seperti serde dengan #[derive(Deserialize)] dan tambahkan validator manual untuk konten kritis. Periksa panjang string, tipe file, dan struktur JSON sebelum meneruskan ke logika inti.

Proteksi upload

Upload file harus melalui service yang membatasi ukuran, memeriksa MIME-type, serta menyimpan sementara di direktori terpisah dengan permission terbatas sebelum dipindahkan ke storage seperti S3.

Contoh validasi multipart Axum:

let multipart = Multipart::new(req.headers(), req.body()); while let Some(field) = multipart.next_field().await? {    let name = field.name().unwrap_or_default();    let content = field.bytes().await?;    if content.len() > MAX_UPLOAD_SIZE || !allowed_content(name) {        return Err(status::custom(StatusCode::BAD_REQUEST, "Upload tidak valid"));    }    // lanjutkan pemeriksaan ekstensi / signature file}

Tambahkan service deteksi malware atau checksum sederhana jika memungkinkan.

Rate Limit dan Mitigasi Abuse

Layer throttling dengan Tower

Gunakan tower::Layer untuk menyisipkan rate limit sebelum handler dijalankan. Terpopuler adalah tower::limit::RateLimitLayer atau implementasi custom berbasis Redis untuk agregasi multi-instance.

Contoh pattern custom:

async fn throttle(req: Request, next: Next) -> Response {    let key = format!("throttle:{}", req.extensions().get::().unwrap());    let allowed = redis.incr(key).await? <= MAX_PER_MINUTE;    if !allowed {        return Response::builder().status(StatusCode::TOO_MANY_REQUESTS).body(Body::empty()).unwrap();    }    next.run(req).await}

Jangan lupakan reset counter dengan TTL (misal 60 detik) di Redis agar rate limit kembali.

Monitoring abuse

Catat metrik rate limit dan kegagalan auth ke sistem observability (Prometheus, Grafana). Atur alert saat 429 meningkat drastis atau banyak kegagalan login dalam interval singkat.

Gunakan fitur block sementara untuk IP yang gagal berkali-kali (contoh: increment counter gagal login, blok selama 5 menit setelah 5 percobaan).

Menerapkan Middleware dan Penyimpanan

Stack middleware Axum

Susun middleware dengan urutan: 1) logging, 2) rate limit/throttle, 3) auth guard. Pastikan middleware tidak mengeksekusi handler jika validasi gagal.

Contoh registrasi:

let app = Router::new().route("/upload", post(upload_handler))    .layer(ServiceBuilder::new()        .layer(Extension(redis_client))        .layer(CompressionLayer::new())        .layer(TraceLayer::new_for_http())        .layer(RateLimitLayer::new(100, Duration::from_secs(60)))        .layer(RequireAuthLayer::new()));

RateLimitLayer di atas bisa digantikan implementasi custom yang memanfaatkan Redis.

Storage rekomendasi

Gunakan Redis untuk session store dan counter rate limit. Pilih mode clustering untuk skalabilitas, aktifkan persistence minimal agar tidak kehilangan state secara tiba-tiba. Pertimbangkan Redis ACL, firewall spesifik, dan enkripsi in-transit.

Alternatif: PostgreSQL bisa menangani session jika Anda membutuhkan query kompleks, namun Redis lebih cocok untuk operasi TTL cepat.

Deployment dan Hardening

Terakhir, deployment harus meminimalkan pembuangan brute force atau file berbahaya:

  • Pakailah TLS dari terminator (contoh: proxy Nginx/Envoy). Gunakan header Strict-Transport-Security dan Content-Security-Policy.
  • Selimuti endpoint auth dengan WAF sederhana yang memblokir pola SQL injection dan file upload mencurigakan.
  • Rotasi secret dan certificate secara otomatis—gunakan cron job atau tool orchestration (Ansible, Terraform).
  • Konfigurasi backup Redis (snapshotting) agar data session dan rate limit tidak hilang selama failover.
  • Gunakan logging detail untuk akses rate limit dan audit trail otentikasi; jangan log secret.

Gabungkan monitoring (Prometheus + Grafana) untuk metrik latency auth dan jumlah 429, sehingga Anda bisa responsif melihat abuse.