Skip to content

Changelog — sauth-server

Semua perubahan versi library ini dicatat di sini, urutan terbaru di atas.


v0.4.0 (2026-08-03)

TL;DR

Perubahan:

  • 🔥 Breaking: MicroserviceTokenClaimsProviderInterface::getClaimsForUser() — parameter kedua string $clientId wajib (Breaking)
  • ✨ New: Custom claims — host dapat menyisipkan claim root-level tambahan di JWT, identik di OAuth flow maupun ticketbooth flow (High)

Impact: 🔴 Breaking: 1 | ✨ New: 1

Backward Compatible: ❌ Tidak — implementasi MicroserviceTokenClaimsProviderInterface lama (satu parameter) fatal error saat class di-load; token consumer (sauth-client di resource server) tidak terpengaruh sama sekali


🔴 Breaking Changes

getClaimsForUser() — Parameter $clientId

MicroserviceTokenClaimsProviderInterface::getClaimsForUser() kini menerima parameter kedua string $clientId — identifier client OAuth yang meminta token. Ini bukan perubahan behavior halus: PHP akan fatal error (Declaration must be compatible) untuk implementasi lama yang masih satu parameter, sehingga app tidak akan boot sama sekali sampai diperbaiki.

php
// Before (v0.3.x)
public function getClaimsForUser(?Authenticatable $user): array

// After (v0.4.0) — wajib tambah parameter kedua
public function getClaimsForUser(?Authenticatable $user, string $clientId): array

Fix:

  1. Tambahkan parameter kedua string $clientId ke signature GwaClaimsProvider/GwcClaimsProvider (boleh diabaikan di body jika tidak butuh scoping per-client)
  2. Deploy sauth-server v0.4.0 bersama update implementasi ini dalam release window yang sama
  3. sauth-client di resource server tidak perlu di-upgrade — unknown JWT claim sudah diabaikan secara default

✨ New

Custom Claims

Host app (GWA/GWC) sekarang dapat menyisipkan claim tambahan di luar ecosystem contract — misalnya gender — untuk dibaca client tertentu saja. Key apa pun yang dikembalikan getClaimsForUser() di luar sid/snm/fet otomatis jadi claim root-level (flat, tanpa wrapper). Mekanisme ini berlaku identik baik token diterbitkan lewat OAuth/Passport flow (AccessTokenRepository) maupun ticketbooth flow (ServiceTokenIssuer) — keduanya divalidasi lewat helper yang sama, Bpmlib\SauthServer\Support\ReservedClaims.

Poin utama:

  • Default: terlihat oleh semua client kecuali host membatasi via parameter $clientId baru — tidak ada allow/deny config di level library
  • Key yang collide dengan claim ter-reservasi (iss, aud, iat, exp, nbf, sub, jti, sid, snm, fet, scope, act, fp, scopes) melempar Bpmlib\SauthServer\Exceptions\ReservedClaimException saat issuance
  • Tidak ikut terbawa di token exchange (TokenExchangeGrant) — delegated token hanya membawa sid/snm/fet/fp dari subject token
  • sauth-client tidak berubah — consumer decode payload JWT sendiri setelah middleware verifikasi signature

Lihat: Custom Claims


v0.3.8 (2026-06-29)

TL;DR

Perubahan:

  • 🐛 Fixed: bpm:sauth:apikey issue/list/revoke tidak bisa dipanggil — semua tiga command terdaftar dengan nama yang sama di Artisan; hanya revoke yang aktif (Low)

Impact: 🔵 Low: 1

Backward Compatible: ✅ Ya — command baru sepenuhnya menggantikan yang lama; tidak ada perubahan behavior


🔵 Low Impact

Perubahan:

  • Command signature diubah dari space-separated (bpm:sauth:apikey issue) ke colon-separated (bpm:sauth:apikey:issue, bpm:sauth:apikey:list, bpm:sauth:apikey:revoke) — Laravel Parser::name() hanya membaca token pertama dari signature, sehingga semua tiga command sebelumnya terdaftar sebagai bpm:sauth:apikey; command terakhir yang diregister (ApiKeyRevokeCommand) menang, sehingga php artisan bpm:sauth:apikey issue memanggil ApiKeyRevokeCommand dengan jti = "issue"ModelNotFoundException

v0.3.7 (2026-06-13)

TL;DR

Perubahan:

  • 🔧 Improved: client_credentials grant — parameter resource untuk targeting aud per-call (Low)

Impact: 🔵 Low: 1

Backward Compatible: ✅ Ya — caller tanpa resource mendapat aud = default_audience seperti sebelumnya


🔵 Low Impact

Perubahan:

  • AccessTokenRepository membaca parameter resource dari request 1p M2M — jika ada dan non-empty, digunakan sebagai aud di JWT; default ke sauth-server.default_audience

v0.3.6 (2026-06-08)

TL;DR

Perubahan:

  • 🐛 Fixed: JWKS — kid tidak ada di response /.well-known/jwks.json (Low)

Impact: 🔵 Low: 1

Backward Compatible: ✅ Ya


🔵 Low Impact

Perubahan:

  • JwksController kini mengembalikan kid dihitung sebagai RFC 7638 JWK thumbprint (SHA-256, base64url-encoded) — stabil selama key tidak dirotasi

v0.3.5 (2026-06-08)

TL;DR

Perubahan:

  • 🐛 Fixed: OIDC nonce tidak diteruskan dari authorization request ke id_token (Low)

Impact: 🔵 Low: 1

Backward Compatible: ✅ Ya — auto-approve path tidak ada perubahan; manual-approve path butuh satu baris tambahan


🔵 Low Impact

Perubahan:

  • OidcAuthCodeRepository menangkap nonce saat auth code dibuat dan menyimpannya ke cache (TTL 10 menit); OidcBearerTokenResponse membacanya sebelum IdTokenIssuer berjalan
  • Manual-approve path: tambahkan session(['oidc_nonce' => request()->query('nonce')]) di authorization view — lihat docs/oidc-gwa-req.md

v0.3.4 (2026-06-05)

TL;DR

Perubahan:

  • ✨ New: OIDC support opt-in — discovery, JWKS, /userinfo, id_token untuk client is_oidc=true (High)
  • 🔧 Improved: bpm:sauth:client --oidc — flag baru + validasi kombinasi flag (Low)
  • 🔧 Improved: ClientRegistrar — parameter $isOidc di create() dan update() (Low)
  • 🔧 Improved: AccessToken — getter getSid(), getSnm(); infrastruktur nonce setNonce()/getNonce() (Low)
  • 🐛 Fixed: UserInfoController — Eloquent user lookup gagal di Bearer token context (Low)

Impact: ✨ New: 1 | 🔵 Low: 4

Backward Compatible: ✅ Ya — semua fitur OIDC opt-in via SAUTH_OIDC_ENABLED=true; default false


✨ New

OIDC Support

OIDC support kini tersedia sebagai opt-in via SAUTH_OIDC_ENABLED=true, memungkinkan gateway bertindak sebagai OpenID Connect provider. Client yang ditandai is_oidc=true mendapat id_token di samping access_token saat authorization_code flow dengan scope openid — tanpa mengubah shape access token yang sudah ada. Tiga endpoint terdaftar otomatis oleh service provider.

Poin utama:

  • GET /.well-known/openid-configuration — discovery document
  • GET /.well-known/jwks.json — public key dalam format JWK Set
  • GET /userinfosub + name; tambahan via OidcClaimsProviderInterface opsional
  • Kolom is_oidc di oauth_clients dipublish oleh bpm:sauth:migration

Lihat: OIDC Support


🔵 Low Impact

Perubahan:

  • bpm:sauth:client --oidc — kombinasi --oidc --first dan --oidc tanpa --user ditolak; tanpa --oidc + --user meminta konfirmasi interaktif
  • ClientRegistrar::create() mendapat bool $isOidc = false; update() mendapat ?bool $isOidc = null
  • AccessToken — getter publik getSid(), getSnm(); setNonce()/getNonce() untuk infrastruktur nonce id_token
  • UserInfoController — diperbaiki menggunakan auth->createUserProvider(...)->retrieveById() di Bearer token context agar OidcClaimsProviderInterface dipanggil dengan Eloquent user

v0.3.3 (2026-06-01)

TL;DR

Perubahan:

  • 🔧 Improved: SAUTH_APIKEY_SIGN_ALGO + SAUTH_APIKEY_PRIVATE_KEY_FILE — key pair dan algoritma signing terpisah untuk API key JWT (Low)

Impact: 🔵 Low: 1

Backward Compatible: ✅ Ya — tanpa kedua env var, perilaku identik dengan v0.3.2


🔵 Low Impact

Perubahan:

  • ApiKeyIssuer kini mendukung key pair dan algoritma independen; fallback chain algo: SAUTH_APIKEY_SIGN_ALGOSAUTH_SIGN_ALGOSAUTH_ALGORS256; fallback chain key: SAUTH_APIKEY_PRIVATE_KEY_FILESAUTH_PRIVATE_KEY_FILEoauth-private.key
  • Dua key baru di config/sauth-server.php: apikey_sign_algorithm dan apikey_private_key_file
  • ApiKeyIssuer kini menggunakan KeyLoader — deteksi mismatch key/algo aktif untuk API key JWT juga

v0.3.2 (2026-05-26)

TL;DR

Perubahan:

  • 🔧 Improved: SAUTH_SIGN_ALGO — override algoritma signing sauth-server independen dari SAUTH_ALGO (Low)

Impact: 🔵 Low: 1

Backward Compatible: ✅ Ya — null default fallback ke SAUTH_ALGO; behavior identik dengan v0.3.1


🔵 Low Impact

Perubahan:

  • SAUTH_SIGN_ALGO override SAUTH_ALGO untuk signing + key generation di sauth-server saja — resource server tidak membacanya
  • bpm:sauth:keygen — argumen {algo} kini opsional; resolve dari SAUTH_SIGN_ALGOSAUTH_ALGORS256
  • Key baru sign_algorithm di config/sauth-server.php

v0.3.1 (2026-05-25)

TL;DR

Perubahan:

  • 🔥 Breaking: service_code di oauth_clients + validasi target ServiceTokenIssuer (Breaking)
  • ✨ New: bpm:sauth:keygen + KeyLoader — generate key EC/EdDSA, deteksi mismatch key/algo (High)
  • ✨ New: bpm:sauth:migration — command standalone untuk publish migrasi sauth (Medium)
  • 🔧 Improved: bpm:sauth:init — flag --algo, --path, --file-prefix; stop memanggil passport:keys (Medium)
  • 🔧 Improved: ClientRegistrar — parameter serviceCode di create() dan update() (Medium)
  • 🔧 Improved: bpm:sauth:client --first — prompt service code wajib saat membuat 1p client (Low)

Impact: 🔴 Breaking: 1 | ✨ New: 2 | 🟢 Medium: 2 | 🔵 Low: 1

Backward Compatible: ❌ Tidak — ServiceTokenIssuer menolak semua target tanpa service_code terdaftar


🔴 Breaking Changes

service_code Validation di ServiceTokenIssuer

ServiceTokenIssuer::issue() kini memvalidasi $targetService ke oauth_clients sebelum menerbitkan token — menolak target yang tidak terdaftar dengan InvalidArgumentException. Sebelumnya string apapun diterima sebagai aud tanpa validasi, memungkinkan frontend request token dengan aud sembarang.

php
// Before (v0.3.0) — target apapun diterima
$issuer->issue($user, 'service-apapun'); // OK

// After (v0.3.1) — harus terdaftar di oauth_clients dengan service_code
$issuer->issue($user, 'srf');            // OK jika service_code='srf' terdaftar
$issuer->issue($user, 'tidak-ada');      // throws InvalidArgumentException

Fix:

  1. Jalankan php artisan bpm:sauth:migration di GWA dan GWC
  2. Populate service_code di semua 1p client yang menjadi target ticketbooth sebelum deploy
  3. Update gateway ticketbooth controller untuk catch \InvalidArgumentException → return 422

✨ New

bpm:sauth:keygen + KeyLoader

Command baru bpm:sauth:keygen men-generate key pair untuk RS256/384/512, ES256/384/512, dan EdDSA, lalu menyimpannya ke storage/. KeyLoader mendeteksi format key otomatis (PEM vs base64) dan memvalidasi terhadap algoritma sebelum operasi kriptografi — mismatch melempar RuntimeException dengan instruksi bpm:sauth:keygen yang tepat.

Poin utama:

  • Format: PEM untuk RSA/EC; base64 single-line untuk EdDSA
  • Flag: --path, --file-prefix, --force (dengan konfirmasi prompt)
  • bpm:sauth:init mendelegasikan key generation ke internal logic yang sama

Lihat: bpm:sauth:keygen dan KeyLoader


bpm:sauth:migration

Command standalone yang mempublish dan menjalankan tiga migrasi sauth secara idempotent — tanpa meregenerasi key. Berguna untuk upgrade rolling di mana key generation tidak diperlukan. bpm:sauth:init kini mendelegasikan langkah migrasi ke command ini.

Poin utama:

  • Idempotent — aman dijalankan berulang kali, setiap langkah dicek terlebih dulu
  • Menangani fresh install (tambah is_first_party + service_code) dan upgrade path (service_code saja, hindari duplikasi kolom)

Lihat: bpm:sauth:migration


🟢 Medium Impact

Peningkatan:

  • bpm:sauth:init — flag --algo, --path, --file-prefix untuk key generation; algo dan key selalu konsisten dengan yang di-sign
  • ClientRegistrar::create() dan update() menerima ?string $serviceCode = null; update() dengan '' meng-clear ke null di DB

🔵 Low Impact

Perubahan:

  • bpm:sauth:client --first — prompt service code interaktif; input kosong abort dengan error; output summary menyertakan baris Service Code

v0.3.0 (2026-05-25)

TL;DR

Perubahan:

  • ✨ New: Claim fp — party marker eksplisit '1p'/'3p' di semua token (High)
  • 🔧 Improved: Claim iss untuk token 3p menggunakan APP_URL (High)
  • 🐛 Fixed: FetchesClientToken fake token — fet: [] salah + forUnsecuredSigner dihapus di lcobucci v5 (Medium)
  • 🐛 Fixed: ServiceTokenIssuerfp tidak di-emit untuk ticketbooth token (Medium)

Impact: ✨ New: 1 | 🟡 High: 1 | 🟢 Medium: 2

Backward Compatible: ⚠️ Partial — deploy sauth-client v0.3.0 ke resource server lebih dulu sebelum gateway


✨ New

Claim fp

Semua token yang diterbitkan kini menyertakan claim fp berisi '1p' (first-party) atau '3p' (third-party), menggantikan inferensi ambigu dari ada/tidaknya snm dan scope yang digunakan sauth-client sebelumnya. Di-set oleh AccessTokenRepository dari kolom is_first_party — tidak ada DB query tambahan.

Poin utama:

  • 1p user/M2M → '1p'; 3p user/M2M/API key JWT → '3p'
  • TokenExchangeGrant membaca fp dari subject token; fallback '1p' untuk token lama (pra-v0.3)
  • sauth-client v0.3.0 tetap menerima token lama tanpa fp — tidak ada hard failure

Lihat: Token Claim Structure


🟡 High Impact

Claim iss untuk Token 3p — APP_URL

Token 3p (user, M2M, API key JWT) kini menggunakan APP_URL gateway sebagai nilai iss, bukan short code (gwa/gwc), mengikuti RFC 9068. Token 1p tidak berubah. Resource server yang menerima token 3p harus upgrade ke sauth-client v0.3.0 dan menambahkan trusted_issuer_url_map ke konfigurasi sebelum gateway di-deploy.

Poin utama:

  • Token 1p: iss tetap gwa/gwc
  • Token 3p: iss menjadi https://admin.example.com
  • Resource server hanya menerima token 1p: tidak ada perubahan apapun

Lihat: Token Claim Structure


🟢 Medium Impact

Perbaikan:

  • FetchesClientToken — hapus fet: [] dari fake token M2M; ganti Configuration::forUnsecuredSigner() (dihapus di lcobucci v5) dengan symmetric signer throwaway
  • ServiceTokenIssuerfp='1p' kini di-set eksplisit di builder chain; sebelumnya ticketbooth token tidak membawa fp sama sekali

v0.2.0 (2026-05-22)

TL;DR

Perubahan:

  • ✨ New: ApiKeyIssuer + bpm:sauth:apikey:* — infrastruktur API key JWT untuk integrasi partner (High)
  • ✨ New: Claim scope di token 3p (High)
  • 🔧 Improved: 1p M2M token shape — fet: [] dihapus (High)
  • 🐛 Fixed: FetchesClientToken — cache key salah + TTL override hilang (Medium)

Impact: ✨ New: 2 | 🟡 High: 1 | 🟢 Medium: 1

Backward Compatible: ⚠️ Partial — deploy sauth-client v0.2.0 ke resource server lebih dulu


✨ New

ApiKeyIssuer + bpm:sauth:apikey:*

JWT long-lived untuk integrasi partner machine-to-machine tanpa OAuth flow. Token ditandatangani dengan private key gateway yang sama — resource server memvalidasinya identik dengan token OAuth biasa. Tidak ada exp; revokasi via blacklist jti di masing-masing resource server. Metadata tersimpan di tabel sauth_jti_tokens (encrypted).

Poin utama:

  • bpm:sauth:apikey:issue {app} {aud} — terbitkan; token ditampilkan sekali, tidak bisa diambil lagi tanpa endpoint webmaster
  • bpm:sauth:apikey:list — lihat semua key yang pernah diterbitkan
  • bpm:sauth:apikey:revoke {jti} — tandai revoked (audit); block di resource server secara terpisah via bpm:sauth:jti block
  • Event JtiTokenRevoked dilempar saat revoke — GWA dapat mendaftarkan listener untuk propagasi otomatis

Lihat: ApiKeyIssuer dan bpm:sauth:apikey:*


Claim scope di Token 3p

Token dari client third-party (user dan M2M) kini menyertakan claim scope berisi space-separated scopes yang di-grant. Token 1p tidak terpengaruh — scope tidak hadir di token 1p user maupun 1p M2M.

Poin utama:

  • 3p user: scope yang di-grant saat consent; 3p M2M: scope yang di-assign ke client; API key JWT: scope yang ditentukan saat issuance
  • Middleware sauth.scope di sauth-client dapat membaca langsung dari JWT claim

Lihat: Token Claim Structure


🟡 High Impact

1p M2M Token Shape — fet Dihapus

Token client_credentials dari client first-party sebelumnya membawa fet: [] yang tidak relevan — fet adalah permission set user, tidak bermakna untuk machine client. Claim ini kini dihapus sepenuhnya; 1p M2M token hanya membawa iss, aud, iat, exp, sid, fp. Trust di sisi resource server bersifat struktural: valid signature + correct aud.

Poin utama:

  • Worker/job yang menggunakan FetchesClientToken: tidak ada perubahan
  • sauth-client isFirstParty() berubah dari cek keberadaan fet menjadi ketidakhadiran scope
  • Wajib deploy sauth-client v0.2.0 lebih dulu — resource server lama gagal mendeteksi 1p M2M tanpa fet

Lihat: Token Claim Structure


🟢 Medium Impact

Perbaikan:

  • FetchesClientToken — cache key dibangun dari config('sauth-server.client_credentials.client_id') (bukan $response['client_id'] yang tidak ada); Cache::remember diganti ke Cache::get() ?? fetch() sehingga TTL 80% dari server tidak ditimpa

v0.1.3 (2026-05-21)

TL;DR

Perubahan:

  • 🔧 Improved: FetchesClientToken — parameter $audience opsional + dev bypass mode (High)
  • 🔧 Improved: Config key bypassSAUTH_BYPASS untuk local dev (Medium)

Impact: 🟡 High: 1 | 🟢 Medium: 1

Backward Compatible: ✅ Ya — clientToken() dan forgetClientToken() tanpa argumen tidak berubah


🟡 High Impact

FetchesClientToken$audience Parameter + Dev Bypass Mode

clientToken() dan forgetClientToken() kini menerima $audience opsional sehingga job yang memanggil beberapa service mendapat cache token terpisah per audience. Dev bypass mode (SAUTH_BYPASS=true + app()->isLocal()) membuat JWT palsu secara lokal tanpa memanggil GWA — cocok untuk development tanpa infrastruktur lengkap.

Poin utama:

  • Cache key: sauth_client_token_{client_id}_{audience} — per-audience, independent
  • Bypass: JWT dengan alg:none, claims iss/aud/sid/fp, di-cache 720 detik
  • Bypass hanya aktif saat app()->isLocal() — nilai true di production tidak berpengaruh

Lihat: FetchesClientToken


🟢 Medium Impact

Peningkatan:

  • Key baru bypass di config/sauth-server.php (backed by SAUTH_BYPASS, default false) — hanya mempengaruhi FetchesClientToken

v0.1.2 (2026-05-21)

TL;DR

Perubahan:

  • 🔧 Improved: SAUTH_PRIVATE_KEY_FILE — path private key relatif ke storage_path() untuk ServiceTokenIssuer (Medium)
  • 📦 Dependencies: bump bpmlib/sauth-client ke ^0.1.3 (Low)

Impact: 🟢 Medium: 1 | 🔵 Low: 1

Backward Compatible: ✅ Ya — default 'oauth-private.key' identik dengan konvensi Passport lama


🟢 Medium Impact

Peningkatan:

  • ServiceTokenIssuer membaca path private key dari config('sauth-server.private_key_file') (SAUTH_PRIVATE_KEY_FILE); memudahkan key rotation tanpa restart — ganti file, tidak perlu ubah .env

🔵 Low Impact

Perubahan:

  • Dependency bpmlib/sauth-client di-bump ke ^0.1.3

v0.1.1 (2026-05-20)

TL;DR

Perubahan:

  • ✨ New: ServiceTokenIssuer — reusable ticketbooth JWT issuance untuk GWA dan GWC (High)

Impact: ✨ New: 1

Backward Compatible: ✅ Ya


✨ New

ServiceTokenIssuer

Service yang memusatkan logika ticketbooth JWT issuance sehingga GWA dan GWC tidak lagi menduplikasi implementasi. issue($user, $targetService) menerbitkan signed JWT langsung via lcobucci/jwt tanpa Passport grant flow — tidak ada DB write, tidak ada refresh token karena session gateway adalah long-lived credential.

Poin utama:

  • Inject via constructor DI — auto-bound sebagai singleton oleh service provider
  • Claims konsisten dengan token Passport via MicroserviceTokenClaimsProviderInterface
  • RuntimeException jika sauth-server.issuer_code kosong; TTL mengikuti sauth-server.token_ttl.access

Lihat: ServiceTokenIssuer


v0.1.0 (2026-05-19)

TL;DR

Perubahan:

  • ✨ New: MicroserviceTokenClaimsProviderInterface — contract terpusat untuk claim injection (High)
  • ✨ New: bpm:sauth:init — setup satu langkah: migrasi, is_first_party, OAuth keys (High)
  • ✨ New: ClientRegistrar + bpm:sauth:client — manajemen lifecycle OAuth client (High)
  • ✨ New: FetchesClientToken — M2M token caching otomatis untuk workers/jobs (High)
  • ✨ New: TokenExchangeGrant RFC 8693 — token exchange untuk service chaining (High)
  • 🔧 Improved: Configurable signing algorithm — RS256, RS384, RS512, ES256, ES384, ES512 (Medium)
  • 🔧 Improved: Configurable token TTL via environment variables (Medium)
  • 🔧 Improved: 1st-party vs 3rd-party client via is_first_party di oauth_clients (Medium)
  • 📝 Docs: Published config/sauth-server.php (Low)
  • 📝 Docs: Auto-discovery service provider (Low)

Impact: ✨ New: 5 | 🟢 Medium: 3 | 🔵 Low: 2

Backward Compatible: ✅ Ya (initial release)


✨ New

MicroserviceTokenClaimsProviderInterface

Contract terpusat yang menggantikan copy-paste JWT issuance logic di setiap gateway. Setiap gateway implement interface ini satu kali; library memanggil dan meng-inject claim standar (iss, sid, snm, fet, act) ke setiap token yang diterbitkan Passport secara konsisten.

Poin utama:

  • User token: sid, snm, fet; 1p M2M: hanya sid
  • 'wm' pada fet bypass semua permission checks di sauth.gate
  • Bind di AppServiceProvider::register() sebelum SauthServerServiceProvider me-resolve-nya

Lihat: MicroserviceTokenClaimsProviderInterface


bpm:sauth:init

Setup satu langkah yang idempotent: publish Passport migrations, tambah kolom is_first_party ke oauth_clients, jalankan migrate, dan generate OAuth keys — menggantikan serangkaian langkah manual yang sebelumnya harus dilakukan di masing-masing gateway.

Poin utama:

  • Idempotent — aman dijalankan berulang kali
  • --force untuk regenerasi key (rotasi)
  • Migration is_first_party di-ship sebagai stub dalam library, di-copy langsung ke database/migrations/

Lihat: bpm:sauth:init


ClientRegistrar + bpm:sauth:client

Service yang memusatkan seluruh logika OAuth client lifecycle — create, update, delete, rotasi secret — sehingga gateway controller dan artisan command menggunakan implementasi yang sama. bpm:sauth:client adalah thin wrapper CLI dengan 4 kombinasi flag untuk 4 tipe client.

Poin utama:

  • 4 tipe: 3p M2M, 1p M2M, 3p user, 1p user via flag --first/--user
  • plainSecret hanya tersedia di instance yang dikembalikan — tidak bisa diambil lagi
  • Auto-bound sebagai singleton; inject via constructor DI di gateway controller

Lihat: ClientRegistrar dan bpm:sauth:client


FetchesClientToken

Trait untuk worker/job base class yang memanggil service lain menggunakan M2M token. Menangani siklus fetch → cache → refresh secara transparan; token di-cache hingga 80% TTL-nya untuk menghindari race condition expiry.

Poin utama:

  • $this->clientToken($aud) — cached M2M token; fetch otomatis ke GWA jika miss
  • $this->forgetClientToken($aud) — clear cache setelah menerima 401; retry once
  • Konfigurasi via sauth-server.client_credentials di .env

Lihat: FetchesClientToken


TokenExchangeGrant (RFC 8693)

Custom grant yang memungkinkan service menukar token user yang diterimanya dengan token baru bertarget service lain, tanpa kehilangan identitas user asli. Disabled by default; aktifkan via SAUTH_TOKEN_EXCHANGE_ENABLED=true di GWA saja.

Poin utama:

  • Parameter resource wajib (RFC 9700 — satu token, satu target)
  • Token hasil exchange membawa act.sub berisi client ID service pemanggil
  • GWA adalah satu-satunya exchange authority; GWC token diterima sebagai subject token

Lihat: TokenExchangeGrant


🟢 Medium Impact

Peningkatan:

  • Signing algorithm dikonfigurasi via SAUTH_ALGO — RS256, RS384, RS512, ES256, ES384, ES512; default RS256
  • Token TTL dikonfigurasi via SAUTH_ACCESS_TOKEN_TTL (default 900s) dan SAUTH_REFRESH_TOKEN_TTL (default 604800s)
  • 1st-party vs 3rd-party client dibedakan via kolom is_first_party di oauth_clients

🔵 Low Impact

Perubahan:

  • Published config/sauth-server.php via php artisan vendor:publish --tag=sauth-server-config
  • Auto-discovery service provider via Laravel package discovery