OmniStream Docs
  • Panduan Pengguna
  • Developer
  • API Reference
Developer Hub
Pendahuluan
Autentikasi
    JWT BearerAlur login dan cookie httpOnlyRBAC dan matriks izin
Model Data
Webhook
WebSocket
Self-Hosting
Error & Rate Limit
Autentikasi

JWT Bearer

JWT Bearer

OmniStream memakai JSON Web Token sebagai mekanisme autentikasi utama untuk REST API dan WebSocket. Setelah login, klien menerima token yang ditandatangani dengan HS256 dan dapat dikirim sebagai header Authorization: Bearer <token> di setiap request berikutnya.

Halaman ini menjelaskan struktur token, lifetime, dan cara memakainya dari klien non-browser (mis. skrip backend atau integrasi pihak ketiga). Untuk alur login dari browser yang memakai cookie httpOnly, lihat Cookie httpOnly.

Variabel lingkungan

Dari bagian JWT pada .env.example:

VariabelDefaultKegunaan
JWT_SECRET(wajib)Kunci simetris HS256 minimal 32 karakter. Jangan pakai nilai default; generate dengan openssl rand -hex 32.
JWT_EXPIRATION_HOURS24Umur token sejak iat. Token di luar rentang ini dianggap expired.

Validasi JWT dilakukan di omni_common::JwtValidator (crates/omni-common/src/jwt.rs). Validator membungkus jsonwebtoken::decode dengan Validation::default() — yang artinya algoritma HS256, verifikasi exp, dan leeway nol. Nilai aud/iss tidak diperiksa karena OmniStream single-tenant.

Struktur payload

Token berisi AgentClaims yang didefinisikan di crates/omni-common/src/models/agent.rs:

Code
pub struct AgentClaims { pub sub: Uuid, // id agent pub email: String, pub role: AgentRole, // "admin" | "supervisor" | "agent" pub exp: i64, // epoch seconds pub iat: i64, // epoch seconds }

Contoh payload setelah decode:

Code
{ "sub": "6b6ccfc1-7e77-4b0c-8b45-5d4f52a3c8d1", "email": "admin@omnistream.com", "role": "admin", "exp": 1776200000, "iat": 1776113600 }

Klaim role di-serialize sebagai snake_case melalui enum AgentRole — hanya tiga nilai valid: admin, supervisor, agent. Pengkodean lain akan ditolak saat deserialisasi.

Lifetime dan rotasi

  • Token berlaku JWT_EXPIRATION_HOURS jam sejak diterbitkan (default 24 jam).
  • Tidak ada refresh token. Klien harus login ulang saat token kedaluwarsa.
  • Saat ini tidak ada denylist/revocation: token yang sudah diterbitkan berlaku sampai exp meski agent dinonaktifkan. Untuk mencabut akses sebelum waktunya, rotasi JWT_SECRET (akan menginvalidasi semua token aktif).

Memakai Bearer dari klien API

Semua endpoint di bawah /api/* kecuali /api/auth/login dan /api/health memerlukan token. Contoh dengan curl:

TerminalCode
# 1. Login TOKEN=$(curl -sS -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@omnistream.com","password":"admin123"}' \ | jq -r '.token') # 2. Panggil endpoint yang dilindungi curl -sS http://localhost:3000/api/conversations \ -H "Authorization: Bearer $TOKEN" \ | jq '.'

Middleware JWT (crates/api-gateway/src/middleware/auth.rs) mencari token dengan urutan:

  1. Header Authorization: Bearer <token>
  2. Cookie access_token (dipakai browser)

Jika keduanya tidak ada, middleware mengembalikan 401 Unauthorized. Jika token ada tetapi tidak valid (signature salah, kedaluwarsa, payload rusak), middleware juga mengembalikan 401.

Setelah validasi, AgentClaims dimasukkan ke Request::extensions() sehingga handler rute bisa membacanya lewat ekstractor Axum. Enforcement per-peran dilakukan oleh middleware RBAC terpisah — lihat RBAC.

WebSocket

ws-server (/ws?token=<JWT>) memakai validator yang sama. Perbedaan hanya pada transport: token dilewatkan sebagai query string karena WebSocket browser tidak dapat menambahkan header custom. Lihat WebSocket → Koneksi untuk detailnya.

Error umum

  • 401 Unauthorized tanpa body — header Authorization tidak ada atau tidak dalam format Bearer <token>. Pastikan spasi tunggal antara Bearer dan token.
  • 401 Unauthorized dengan body { "error": "Invalid token" } — token kedaluwarsa atau signature tidak cocok. Login ulang dan pakai token baru.
  • Token berfungsi pada satu layanan tetapi tidak yang lain — JWT_SECRET berbeda antar proses. Semua crate (api-gateway, ws-server, dll.) harus memakai nilai yang sama dari .env.
  • JWT_SECRET must be at least 32 characters saat start — isi JWT_SECRET dengan minimal 32 karakter. Jangan pakai default your_jwt_secret_here_min_32_chars_long di produksi.

Catatan keamanan

  • Jangan menyimpan token mentah di localStorage pada browser. Frontend OmniStream memakai cookie httpOnly yang diset saat login (lihat Cookie httpOnly) supaya token tidak dapat dibaca JavaScript.
  • Gunakan HTTPS di produksi. Token Bearer yang melintasi HTTP dapat dicuri dengan sniffing.
  • Rotasi secret secara berkala. Setiap rotasi menginvalidasi semua token aktif dan memaksa login ulang — rencanakan perubahan pada jendela maintenance.
Last modified on June 8, 2026
QuickstartAlur login dan cookie httpOnly
On this page
  • Variabel lingkungan
  • Struktur payload
  • Lifetime dan rotasi
  • Memakai Bearer dari klien API
  • WebSocket
  • Error umum
  • Catatan keamanan
Rust
JSON