Nodeflux Central
Otentikasi

Otentikasi

Panduan JWT, refresh token, API key, integration lock, WebSocket, dan header X-User-Permissions untuk integrasi dengan backend API.

Pengenalan

Backend API mendukung dua mekanisme otentikasi utama: Bearer Token (JWT) yang diperoleh dari login username/password, dan API Key untuk kebutuhan service-to-service atau automasi. Setiap request ke API harus menyertakan salah satunya. Untuk arsitektur multi-instance (federation), terdapat mekanisme tambahan berupa header X-User-Permissions yang memungkinkan Federation Module meneruskan konteks izin pengguna ke remote instance secara aman tanpa harus replay JWT user asli.

Sesi pengguna kini berbasis server (session-backed): setiap login membuat satu record sesi, access_token berumur pendek (30 menit) dan diperbarui lewat refresh_token yang dirotasi setiap kali dipakai. Selain itu, request Bearer Token dari luar dashboard dilindungi integration lock — sehingga jalur yang didukung untuk integrasi pihak ketiga adalah API Key.

Halaman ini mencakup seluruh alur otentikasi secara teknis — cara mendapatkan token, siklus hidup sesi, cara menyertakan kredensial di request HTTP maupun WebSocket, hingga alur federation antar-instance backend.

Jika Anda hanya operator yang memakai dashboard Lenz, baca Memulai. Halaman ini ditujukan untuk integrator yang memanggil API langsung dari aplikasi atau skrip mereka.

Tipe Otentikasi

TipeHeader yang DipakaiUse Case
Bearer Token (JWT)Authorization: Bearer <jwt>Sesi pengguna login
API KeyX-Api-Key: <key>Service-to-service / automasi / CI-CD
FederatedX-Api-Key: <remote_key> + X-User-Permissions: <jwt>Federation Module → remote instance (multi-instance)

Nama header X-Api-Key bersifat case-insensitive sesuai HTTP spec. Klien Lenz internal mengirim header dengan huruf kecil (x-api-key) — keduanya valid. Ketiga kredensial di atas juga diterima sebagai query parameter dengan nama yang sama (?authorization=, ?x-api-key=, ?x-user-permissions=) — dipakai untuk handshake WebSocket yang tidak bisa membawa header kustom. Lihat Otentikasi WebSocket.

Untuk integrator, gunakan API Key. Request dengan Authorization: Bearer dari luar dashboard Lenz wajib menyertakan X-Integration-Signature (lihat Integration Lock), sedangkan request X-Api-Key tanpa header Authorization dikecualikan dari kewajiban itu.

Jalur Mana yang Harus Saya Pakai?

Aturannya sederhana: kalau yang memanggil API bukan manusia yang sedang login di browser, pakai X-Api-Key. Bearer token hanya untuk aplikasi yang menampilkan halaman login Lenz kepada penggunanya sendiri.

Kasus di LenzContoh request
Sinkronisasi daftar kamera ke sistem inventaris / NOCGET /api/streams
HRIS mendaftarkan wajah karyawan baru secara otomatisPOST /api/enrollment
Skrip harian mengekspor event LPR ke data warehousePOST /api/event-history/lpr/export
Dashboard SOC pihak ketiga menampilkan alert real-timewss://…/api/alert_channel?x-api-key=…
Sistem tiket membaca detail alert saat dibuat follow-upGET /api/alert-history/{id}
Monitoring uptime memeriksa kesehatan backendGET /api/auth/ping
Federation Module memanggil remote instanceX-Api-Key + X-User-Permissions (otomatis)
Satu header, tanpa login
curl "${API_URL}/api/streams" -H "X-Api-Key: ${API_KEY}"

Tidak ada login, refresh, X-Integration-Signature, DPoP, maupun kebijakan satu sesi. Izin mengikuti role pemilik API key — buat key dari akun dengan role yang sesuai kebutuhan integrasi, bukan dari superadmin.

Kasus di LenzMengapa Bearer
Lenz Dashboard itu sendiriOperator login dengan akun masing-masing
Aplikasi mobile/kiosk buatan Anda yang menampilkan form login Lenz dan meneruskan kredensial penggunaSetiap pengguna harus melihat data sesuai role & site-nya sendiri, dan tercatat di audit log atas namanya
Login → Bearer di setiap request
curl -X POST "${API_URL}/api/auth/token" -d '{"user_access":"…","password":"…"}'
curl "${API_URL}/api/streams" -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "X-Integration-Signature: ${SIG}"

Konsekuensinya: wajib menyertakan X-Integration-Signature (secret hanya tersedia di server), refresh token setiap 30 menit, menangani 409 active-session-exists dan 401 session-revoked, serta DPoP jika diaktifkan admin. Jika daftar ini terasa berlebihan untuk kasus Anda, kemungkinan besar Anda seharusnya memakai API key.

Jangan campur keduanya. Mengirim X-Api-Key dan Authorization: Bearer sekaligus diperlakukan sebagai request Bearer — integration lock tetap berlaku dan API key-nya diabaikan.


Login Cepat (Untuk Operator)

Jika Anda hanya perlu masuk ke dashboard Lenz, buka browser dan kunjungi alamat Lenz yang sudah dikonfigurasi admin Anda. Masukkan username dan password pada halaman login — tidak diperlukan konfigurasi tambahan.


Login dengan Username & Password

Kirim kredensial ke /api/auth/token

Gunakan field user_access untuk username atau alamat email, dan password untuk kata sandi. Dua field opsional:

FieldDefaultKeterangan
remember_mefalsePerpanjang masa sesi dari 1 hari menjadi 3 hari
force_loginfalseAmbil alih akun yang sedang login di tempat lain (lihat langkah berikutnya)
Login dengan username dan password
curl -X POST "${API_URL}/api/auth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "user_access": "[email protected]",
    "password": "your-password",
    "remember_me": false
  }'
Login (fetch)
const res = await fetch(`${API_URL}/api/auth/token`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    user_access: "[email protected]",
    password: "your-password",
  }),
});
const { access_token, refresh_token, name } = await res.json();
Login (requests)
import requests

res = requests.post(
    f"{API_URL}/api/auth/token",
    json={"user_access": "[email protected]", "password": "your-password"},
    timeout=10,
)
data = res.json()
access_token = data["access_token"]

Tangani 409 jika akun sudah login di tempat lain

Lenz menerapkan kebijakan satu sesi aktif per akun (superadmin dikecualikan). Jika kredensial benar tetapi akun sudah memiliki sesi hidup, server menjawab HTTP 409 dengan informasi sesi yang sedang aktif:

Respons 409 active-session-exists
{
  "ok": false,
  "code": "active-session-exists",
  "message": "An active session already exists for this account",
  "data": {
    "session_count": 1,
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0",
    "ip_address": "10.0.4.21",
    "last_used_at": "2026-09-16T08:12:44Z"
  }
}

Untuk mengambil alih, kirim ulang request login dengan "force_login": true. Semua sesi lama akan di-revoke dan browser lama akan langsung ter-logout pada request berikutnya (401 session-revoked).

Pengecekan ini hanya berjalan setelah password terverifikasi, sehingga respons 409 tidak bisa dipakai untuk menebak apakah suatu akun ada atau sedang login. Login via API key tidak tunduk pada kebijakan ini.

Terima respons berisi token

Jika kredensial valid, server mengembalikan HTTP 201 dengan objek JSON berikut:

Respons login berhasil
{
  "ok": true,
  "message": "Successfull Login",
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "name": "Admin Utama"
}

Simpan keduanya: access_token dipakai di setiap request dan berlaku 30 menit; refresh_token dipakai untuk memperoleh pasangan token baru tanpa login ulang (lihat Refresh Token).

Field name berisi nama tampilan pengguna. Untuk mendapatkan detail profil lengkap (role, permissions, email, default homepage), gunakan GET /api/account/profile dan GET /api/account/role setelah login.

Sertakan access_token di setiap request

Kirim token di header Authorization dengan format Bearer <token>:

Request dengan Bearer Token
curl "${API_URL}/api/streams" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Login dengan API Key

API key cocok untuk integrasi backend, skrip otomatis, CI/CD pipeline, atau layanan tanpa konteks pengguna interaktif. API key dibuat oleh admin di Administration → Configuration → API Key pada dashboard Lenz.

Halaman API Key di Administration → Configuration tempat membuat dan mengelola key untuk integrasi service-to-service.
Halaman API Key di Administration → Configuration tempat membuat dan mengelola key untuk integrasi service-to-service.

Untuk mendapatkan access_token menggunakan API key, kirim POST /api/auth/token tanpa body, namun sertakan header X-Api-Key:

Login dengan API key
curl -X POST "${API_URL}/api/auth/token" \
  -H "X-Api-Key: YOUR_API_KEY_HERE"

Server mengembalikan respons dalam format yang sama dengan login username/password (HTTP 201). Sesi dari login API key berlaku 7 hari (bukan 1/3 hari), tidak tunduk pada kebijakan satu sesi aktif, dan tidak mengenal remember_me.

Cara yang direkomendasikan untuk integrasi adalah memakai API key langsung di setiap request lewat header X-Api-Key, tanpa menukarnya menjadi access_token. Begitu Anda memakai Authorization: Bearer dari luar dashboard, request tersebut wajib membawa X-Integration-Signature (lihat Integration Lock) — sedangkan request X-Api-Key murni dikecualikan.

Pola integrasi yang didukung — API key per request
curl "${API_URL}/api/streams" \
  -H "X-Api-Key: YOUR_API_KEY_HERE"

Jangan menyimpan API key langsung di source code atau commit ke repository publik. Simpan di environment variable, secret manager (Vault, AWS Secrets Manager, GCP Secret Manager), atau file .env yang sudah masuk .gitignore.


Verifikasi Kredensial

Untuk memastikan token atau API key masih diterima, kirim GET /api/auth/ping. Endpoint ini ringan (tidak menyentuh data) dan menerima kedua jenis kredensial:

Verifikasi kredensial aktif
curl "${API_URL}/api/auth/ping" \
  -H "Authorization: Bearer ${TOKEN}"
# atau
curl "${API_URL}/api/auth/ping" \
  -H "X-Api-Key: ${API_KEY}"
  • HTTP 200 — { "ok": true, "message": "pong" }. Kredensial valid.
  • HTTP 401 not-authenticate — Token tidak valid atau kedaluwarsa → lakukan refresh.
  • HTTP 401 session-revoked — Sesi sudah di-revoke (logout di tempat lain, take-over, atau deteksi replay) → refresh tidak akan berhasil, login ulang.

Jika Anda juga membutuhkan profil pengguna (role, permissions, email), gunakan GET /api/account/profile — endpoint tersebut memvalidasi kredensial dengan cara yang sama.


Siklus Hidup Token & Sesi

Setiap login membuat satu sesi di server. access_token memuat ID sesi pada claim sid; bila sesi di-revoke, token tersebut ditolak meskipun belum kedaluwarsa. Tiga potongan berikut menggambarkan alur yang harus ditangani klien Bearer token.

1. Sesi yang berjalan normal

Satu sesi berisi banyak access token yang saling menggantikan lewat refresh, sampai batas waktu sesi tercapai:

kedaluwarsa →401 not-authenticate kedaluwarsa batas sesi tercapai1 hari · 3 hari · 7 hari Login201 access_token #1berlaku 30 menit POST /auth/refresh access_token #2berlaku 30 menit POST /auth/refresh … dst Login ulang

Setiap refresh mengembalikan pasangan baru (access_token + refresh_token); pasangan lama hangus. Batas sesi tidak bergeser karena refresh.

2. Respons yang harus ditangani klien

ResponsArtinyaTindakan
401 not-authenticateAccess token kedaluwarsa atau tidak validPOST /api/auth/refresh, lalu ulangi request
401 session-revokedSesi sudah dimatikan (lihat potongan 3)Jangan refresh — hapus token lokal, login ulang
401 dari /api/auth/refreshRefresh token hangus / sesi lewat batasLogin ulang
409 active-session-existsAkun sedang login di tempat lainKonfirmasi ke pengguna → login ulang dengan force_login: true
403 integration_lockBearer tanpa X-Integration-Signature validBeralih ke X-Api-Key (integrasi) atau perbaiki signature

3. Apa yang mengakhiri sesi

LogoutPOST /auth/logout Sesi di-revoke Take-overlogin lain dengan force_login Replayrefresh_token lama dipakai lagi Batas sesi1 · 3 · 7 hari access_token & refresh_token ditolak401 session-revoked → login ulang

Replay paling sering terjadi bukan karena pencurian, melainkan dua proses di klien yang sama-sama memakai refresh_token lama secara bersamaan. Akibatnya seluruh sesi pengguna di-revoke. Pastikan refresh berjalan single-flight.

access_tokenrefresh_token
FungsiMengotorisasi request APIMemperoleh pasangan token baru
Masa berlaku30 menitMengikuti sesi: 1 hari (default), 3 hari (remember_me), 7 hari (login via API key)
SifatStateless JWT dengan claim sidSekali pakai — dirotasi pada setiap refresh
Bila kedaluwarsa401 not-authenticate → refreshLogin ulang

Admin dapat mengubah durasi lewat environment variable gateway (sintaks durasi Go, mis. 45s, 12h):

Env varDefaultMengatur
ACCESS_TOKEN_TTL30mMasa berlaku access token
SESSION_TOKEN_TTL24hSesi login username/password tanpa remember_me
REMEMBER_ME_TOKEN_TTL72hSesi login dengan remember_me: true
REFRESH_TOKEN_TTL168hSesi login via API key

Selain batas di atas, dashboard Lenz juga menerapkan idle timeout di sisi klien (dikonfigurasi admin di Preferences). Idle timeout memicu logout eksplisit — bukan mekanisme server — sehingga tidak berpengaruh pada integrasi API.


Refresh Token

Ketika access_token kedaluwarsa (401 not-authenticate), tukarkan refresh_token dengan pasangan token baru lewat POST /api/auth/refresh. Endpoint ini tidak memerlukan header Authorization.

Refresh token
curl -X POST "${API_URL}/api/auth/refresh" \
  -H "Content-Type: application/json" \
  -d '{ "refresh_token": "'"${REFRESH_TOKEN}"'" }'
Respons refresh berhasil
{
  "ok": true,
  "message": "Token refreshed",
  "access_token": "eyJ...baru...",
  "refresh_token": "eyJ...baru...",
  "name": "Admin Utama"
}

Aturan yang perlu diperhatikan:

  • Rotasi — refresh token lama langsung tidak berlaku; selalu simpan pasangan yang baru dikembalikan.
  • Tidak memperpanjang sesi — pasangan baru mewarisi batas waktu sesi semula (1/3/7 hari). Setelah itu, login ulang.
  • Deteksi replay — mengirim refresh token yang sudah pernah dirotasi dianggap sebagai token bocor dan merevoke seluruh sesi pengguna tersebut (superadmin: hanya sesi yang bersangkutan). Refresh token yang di-revoke lewat logout/take-over hanya ditolak.
  • Single-flight — jika aplikasi Anda menjalankan request paralel, pastikan hanya satu proses refresh berjalan pada satu waktu dan request lain menunggu hasilnya; dua refresh bersamaan dengan token yang sama akan memicu deteksi replay di atas.
GET /api/streams (Authorization: Bearer access_lama) 401 not-authenticate (access token kedaluwarsa) POST /api/auth/refresh { refresh_token: refresh_lama } Validasi jti, rotasi sesi 200 { access_baru, refresh_baru } GET /api/streams (Authorization: Bearer access_baru) 200 refresh_lama kini tidak berlaku — mengirimnya lagi = revoke semua sesi Klien Backend API

Logout

Untuk mengakhiri sesi di server, kirim POST /api/auth/logout dengan refresh_token pada body. Endpoint ini tidak memerlukan header Authorization — dengan begitu logout tetap bisa dilakukan meski access token sudah kedaluwarsa.

Logout dan revoke sesi
curl -X POST "${API_URL}/api/auth/logout" \
  -H "Content-Type: application/json" \
  -d '{ "refresh_token": "'"${REFRESH_TOKEN}"'" }'

Setelah logout, refresh token tersebut dan access token yang terikat pada sesi yang sama ditolak (401 session-revoked). Endpoint ini idempoten — token yang sudah di-revoke, kedaluwarsa, tidak dikenal, atau body kosong tetap dijawab 200.


Integration Lock (X-Integration-Signature)

Route privat /api/* dilindungi integration lock: request yang membawa Authorization: Bearer harus menyertakan header X-Integration-Signature berisi JWT HS256 pendek yang ditandatangani dengan secret per-deployment. Dashboard Lenz melakukannya otomatis. Tujuannya menutup penyalahgunaan API memakai kredensial login pengguna yang "dipinjam" dari browser.

PemanggilPerlu X-Integration-Signature?
Integrasi API key (X-Api-Key, tanpa header Authorization)Tidak — inilah jalur yang didukung
Dashboard / sesi pengguna (Authorization: Bearer)Ya — otomatis oleh dashboard
Skrip yang memakai Bearer token penggunaYa — inilah yang dicegah
Federation (X-Api-Key + X-User-Permissions, tanpa Bearer)Tidak
Route publik (login, refresh, logout, auth/status, version, ping, channel WebSocket, image reads)Tidak

Request Bearer tanpa signature yang valid dijawab HTTP 403:

Respons 403 integration_lock
{ "ok": false, "code": "integration_lock", "message": "integration signature required" }

Secret integration lock tidak dapat diperoleh lewat API — ia dibuat ulang setiap container Lenz dijalankan dan hanya bisa dibaca oleh dashboard atau operator dengan akses shell ke server. Karena itu, jangan membangun integrasi di atas Bearer token pengguna; gunakan API key per request. Jika Anda menukar API key menjadi access_token lalu memakainya sebagai Bearer, request Anda kembali terkena kewajiban signature.

Untuk memeriksa apakah signature yang Anda pegang masih sinkron (mis. setelah redeploy), gunakan endpoint publik GET /api/auth/status — ia selalu menjawab 200 dengan flag integration: true|false dan tidak pernah membocorkan secret.


Otentikasi WebSocket

Browser tidak bisa mengirim header kustom pada handshake WebSocket, sehingga middleware otentikasi menerima kredensial yang sama melalui query parameter: authorization, x-api-key, dan x-user-permissions. Nilai authorization boleh berupa token mentah maupun berawalan Bearer . Channel WebSocket juga dikecualikan dari integration lock.

ChannelEndpointOtentikasi
Event Channel/api/event_channelTidak ada — publik, difilter lewat query (stream_ids, analytic_id, instance, …)
System Channel/api/system_channelTidak ada — publik
Alert Channel/api/alert_channelWajib: ?authorization=<access_token> atau ?x-api-key=<key>
Alert channel dengan API key
const url = new URL(`wss://${BASE_URL}/api/alert_channel`);
url.searchParams.set('x-api-key', API_KEY);
url.searchParams.set('disable_base64_image', 'true');

const ws = new WebSocket(url.toString());
ws.onmessage = (e) => console.log(JSON.parse(e.data));
Alert channel dengan access token
const url = new URL(`wss://${BASE_URL}/api/alert_channel`);
url.searchParams.set('authorization', accessToken); // tanpa awalan "Bearer " juga diterima
url.searchParams.set('disable_base64_image', 'false');

const ws = new WebSocket(url.toString());

Access token hanya berlaku 30 menit. Handshake yang sudah berhasil tidak diputus saat token kedaluwarsa, tetapi reconnect membutuhkan token yang masih valid — refresh token Anda sebelum menyambung ulang.

Klien non-browser boleh memakai header
import WebSocket from 'ws';

const ws = new WebSocket(`wss://${BASE_URL}/api/alert_channel`, {
  headers: { 'X-Api-Key': API_KEY },
});

Token pada query string dapat tercatat di log proxy/akses. Untuk klien non-browser, kirim kredensial lewat header. Untuk browser, pakai API key dengan scope minimal, atau access token berumur pendek.

Detail parameter filter dan format payload setiap channel dibahas di Events — WebSocket Protocol.


DPoP (Opsional)

Backend mendukung DPoP (RFC 9449, sender-constrained tokens): access/refresh token diikat ke kunci privat non-extractable di browser, sehingga token yang bocor tidak berguna tanpa proof dari browser asal. Fitur ini dikendalikan admin lewat env DPOP_MODE (off — default, monitor, require) dan hanya memengaruhi jalur Authorization: Bearer. Login via API key dan request federated tidak pernah terikat DPoP.

Jika deployment Anda menjalankan DPOP_MODE=require, klien kustom yang memakai Bearer token harus mengimplementasikan proof DPoP (header DPoP, nonce dari header DPoP-Nonce, respons 401 use-dpop-nonce / invalid-dpop-proof). Ini adalah alasan tambahan mengapa integrasi pihak ketiga sebaiknya memakai API key.


Header Federation: X-User-Permissions

Dalam arsitektur multi-instance Lenz, ada satu Federation Module (Core) yang berperan sebagai aggregator, dan satu atau lebih remote instance (instance backend tambahan). Saat Federation Module meneruskan request pengguna ke remote instance, ia tidak menggunakan Bearer Token pengguna secara langsung. Sebagai gantinya, Federation Module:

  1. Mengautentikasi dirinya ke remote instance menggunakan API key remote instance (X-Api-Key).
  2. Mengemas informasi pengguna dan izin yang sudah difilter ke dalam JWT baru.
  3. Menandatangani JWT tersebut menggunakan API key remote instance sebagai HMAC secret.
  4. Menyertakan JWT tersebut di header X-User-Permissions.

Remote instance kemudian memvalidasi tanda tangan JWT menggunakan API key-nya sendiri, mengekstrak izin pengguna, dan menjalankan access control berbasis data JWT — tanpa perlu lookup role ke database lokalnya.

Authorization: Bearer <user_jwt> Validasi token, ambil profil & permissions user Filter permissions untuk target remote instance Sign JWT baru pakai API key remote instance (HMAC-SHA256) X-Api-Key: <remote_key>X-User-Permissions: <signed_jwt> Validasi X-Api-Key Validasi signature JWT pakai API key yang sama Ekstrak user info + permissions dari JWT Terapkan access control (site/stream level) Response sesuai permissions user Agregasi response dari semua remote instance User Federation Module Remote Instance

Struktur Payload JWT X-User-Permissions

Payload JWT X-User-Permissions
{
  "sub": "federer:123",
  "email": "[email protected]",
  "role_id": "operator-role",
  "role_name": "operator-role",
  "permissions": {
    "[remote]core": {
      "site_id|1": ["stream-abc", "stream-def"],
      "site_id|2": ["*"],
      "no_site": ["stream-xyz"]
    }
  },
  "iat": 1705123456,
  "exp": 1705123756
}
FieldDeskripsi
subSubject identifier dalam format "federer:{user_id}"
emailAlamat email pengguna
role_id / role_nameNama role (bukan ID database)
permissionsIzin pengguna yang sudah difilter untuk remote instance target, dengan key diubah menjadi [remote]core
iat / expTimestamp issued-at dan expiration (TTL 5 menit)

Header X-User-Permissions hanya boleh dikirim oleh Federation Module yang sudah terdaftar dan memiliki API key remote instance yang valid. Jangan gunakan header ini untuk integrasi pihak ketiga — request semacam itu akan ditolak karena JWT tidak akan bisa divalidasi tanpa API key yang tepat sebagai secret HMAC.

Skenario Tanpa API Key Remote Instance (Mode Internal)

Jika Federation Module dijalankan satu cluster dengan remote instance dan tidak ingin pakai API key, secret JWT default PERMISSIONS_JWT_SECRET (env var) digunakan oleh kedua sisi. Mode ini tidak direkomendasikan untuk produksi karena tidak memberi isolasi per instance — bocornya secret di satu tempat berarti seluruh cluster terkompromi.


Pesan Error Umum

Respons error otentikasi selalu menyertakan field code yang bisa dibaca mesin — gunakan code, bukan message, untuk percabangan logika di klien.


Tips Integrasi

Best practice untuk integrator:

  • Integrasi server-to-server: pakai X-Api-Key per request tanpa header Authorization. Tidak ada login, refresh, integration lock, DPoP, maupun kebijakan satu sesi yang perlu dipikirkan.
  • Jika Anda tetap memakai Bearer token: simpan access_token dan refresh_token di memori atau secure storage, implementasikan handler 401 yang membedakan not-authenticate (→ refresh, lalu ulangi request) dari session-revoked (→ login ulang), dan pastikan refresh berjalan single-flight.
  • Gunakan API key terpisah per integrasi, dan rotasi berkala sesuai kebijakan keamanan organisasi Anda.
  • Untuk WebSocket dari browser, kirim kredensial lewat query parameter (x-api-key atau authorization); dari klien non-browser, lebih aman lewat header.
  • Untuk federated requests, perhatikan TTL JWT X-User-Permissions yang hanya 5 menit — Federation Module membuat JWT baru untuk setiap batch request.
  • Jangan hardcode token atau API key di kode sumber. Gunakan environment variable atau secret manager.
  • Saat federation aktif, sertakan parameter instance di setiap request ke endpoint yang scope-nya per-instance, agar data tidak tercampur.

Selanjutnya

On this page