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 keduastring $clientIdwajib (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.
// 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): arrayFix:
- Tambahkan parameter kedua
string $clientIdke signatureGwaClaimsProvider/GwcClaimsProvider(boleh diabaikan di body jika tidak butuh scoping per-client) - Deploy
sauth-serverv0.4.0 bersama update implementasi ini dalam release window yang sama sauth-clientdi 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
$clientIdbaru — 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) melemparBpmlib\SauthServer\Exceptions\ReservedClaimExceptionsaat issuance - Tidak ikut terbawa di token exchange (
TokenExchangeGrant) — delegated token hanya membawasid/snm/fet/fpdari subject token sauth-clienttidak 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/revoketidak 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) — LaravelParser::name()hanya membaca token pertama dari signature, sehingga semua tiga command sebelumnya terdaftar sebagaibpm:sauth:apikey; command terakhir yang diregister (ApiKeyRevokeCommand) menang, sehinggaphp artisan bpm:sauth:apikey issuememanggilApiKeyRevokeCommanddenganjti = "issue"→ModelNotFoundException
v0.3.7 (2026-06-13)
TL;DR
Perubahan:
- 🔧 Improved:
client_credentialsgrant — parameterresourceuntuk targetingaudper-call (Low)
Impact: 🔵 Low: 1
Backward Compatible: ✅ Ya — caller tanpa resource mendapat aud = default_audience seperti sebelumnya
🔵 Low Impact
Perubahan:
AccessTokenRepositorymembaca parameterresourcedari request 1p M2M — jika ada dan non-empty, digunakan sebagaiauddi JWT; default kesauth-server.default_audience
v0.3.6 (2026-06-08)
TL;DR
Perubahan:
- 🐛 Fixed: JWKS —
kidtidak ada di response/.well-known/jwks.json(Low)
Impact: 🔵 Low: 1
Backward Compatible: ✅ Ya
🔵 Low Impact
Perubahan:
JwksControllerkini mengembalikankiddihitung 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
noncetidak diteruskan dari authorization request keid_token(Low)
Impact: 🔵 Low: 1
Backward Compatible: ✅ Ya — auto-approve path tidak ada perubahan; manual-approve path butuh satu baris tambahan
🔵 Low Impact
Perubahan:
OidcAuthCodeRepositorymenangkap nonce saat auth code dibuat dan menyimpannya ke cache (TTL 10 menit);OidcBearerTokenResponsemembacanya sebelumIdTokenIssuerberjalan- Manual-approve path: tambahkan
session(['oidc_nonce' => request()->query('nonce')])di authorization view — lihatdocs/oidc-gwa-req.md
v0.3.4 (2026-06-05)
TL;DR
Perubahan:
- ✨ New: OIDC support opt-in — discovery, JWKS,
/userinfo,id_tokenuntuk clientis_oidc=true(High) - 🔧 Improved:
bpm:sauth:client --oidc— flag baru + validasi kombinasi flag (Low) - 🔧 Improved:
ClientRegistrar— parameter$isOidcdicreate()danupdate()(Low) - 🔧 Improved:
AccessToken— gettergetSid(),getSnm(); infrastruktur noncesetNonce()/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 documentGET /.well-known/jwks.json— public key dalam format JWK SetGET /userinfo—sub+name; tambahan viaOidcClaimsProviderInterfaceopsional- Kolom
is_oidcdioauth_clientsdipublish olehbpm:sauth:migration
Lihat: OIDC Support
🔵 Low Impact
Perubahan:
bpm:sauth:client --oidc— kombinasi--oidc --firstdan--oidctanpa--userditolak; tanpa--oidc+--usermeminta konfirmasi interaktifClientRegistrar::create()mendapatbool $isOidc = false;update()mendapat?bool $isOidc = nullAccessToken— getter publikgetSid(),getSnm();setNonce()/getNonce()untuk infrastruktur nonceid_tokenUserInfoController— diperbaiki menggunakanauth->createUserProvider(...)->retrieveById()di Bearer token context agarOidcClaimsProviderInterfacedipanggil 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:
ApiKeyIssuerkini mendukung key pair dan algoritma independen; fallback chain algo:SAUTH_APIKEY_SIGN_ALGO→SAUTH_SIGN_ALGO→SAUTH_ALGO→RS256; fallback chain key:SAUTH_APIKEY_PRIVATE_KEY_FILE→SAUTH_PRIVATE_KEY_FILE→oauth-private.key- Dua key baru di
config/sauth-server.php:apikey_sign_algorithmdanapikey_private_key_file ApiKeyIssuerkini menggunakanKeyLoader— 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 dariSAUTH_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_ALGOoverrideSAUTH_ALGOuntuk signing + key generation di sauth-server saja — resource server tidak membacanyabpm:sauth:keygen— argumen{algo}kini opsional; resolve dariSAUTH_SIGN_ALGO→SAUTH_ALGO→RS256- Key baru
sign_algorithmdiconfig/sauth-server.php
v0.3.1 (2026-05-25)
TL;DR
Perubahan:
- 🔥 Breaking:
service_codedioauth_clients+ validasi targetServiceTokenIssuer(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 memanggilpassport:keys(Medium) - 🔧 Improved:
ClientRegistrar— parameterserviceCodedicreate()danupdate()(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.
// 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 InvalidArgumentExceptionFix:
- Jalankan
php artisan bpm:sauth:migrationdi GWA dan GWC - Populate
service_codedi semua 1p client yang menjadi target ticketbooth sebelum deploy - 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:initmendelegasikan 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_codesaja, hindari duplikasi kolom)
Lihat: bpm:sauth:migration
🟢 Medium Impact
Peningkatan:
bpm:sauth:init— flag--algo,--path,--file-prefixuntuk key generation; algo dan key selalu konsisten dengan yang di-signClientRegistrar::create()danupdate()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 barisService Code
v0.3.0 (2026-05-25)
TL;DR
Perubahan:
- ✨ New: Claim
fp— party marker eksplisit'1p'/'3p'di semua token (High) - 🔧 Improved: Claim
issuntuk token 3p menggunakanAPP_URL(High) - 🐛 Fixed:
FetchesClientTokenfake token —fet: []salah +forUnsecuredSignerdihapus di lcobucci v5 (Medium) - 🐛 Fixed:
ServiceTokenIssuer—fptidak 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' TokenExchangeGrantmembacafpdari 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:
isstetapgwa/gwc - Token 3p:
issmenjadihttps://admin.example.com - Resource server hanya menerima token 1p: tidak ada perubahan apapun
Lihat: Token Claim Structure
🟢 Medium Impact
Perbaikan:
FetchesClientToken— hapusfet: []dari fake token M2M; gantiConfiguration::forUnsecuredSigner()(dihapus di lcobucci v5) dengan symmetric signer throwawayServiceTokenIssuer—fp='1p'kini di-set eksplisit di builder chain; sebelumnya ticketbooth token tidak membawafpsama 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
scopedi 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 webmasterbpm:sauth:apikey:list— lihat semua key yang pernah diterbitkanbpm:sauth:apikey:revoke {jti}— tandai revoked (audit); block di resource server secara terpisah viabpm:sauth:jti block- Event
JtiTokenRevokeddilempar 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.scopedi 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 keberadaanfetmenjadi ketidakhadiranscope - 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 dariconfig('sauth-server.client_credentials.client_id')(bukan$response['client_id']yang tidak ada);Cache::rememberdiganti keCache::get() ?? fetch()sehingga TTL 80% dari server tidak ditimpa
v0.1.3 (2026-05-21)
TL;DR
Perubahan:
- 🔧 Improved:
FetchesClientToken— parameter$audienceopsional + dev bypass mode (High) - 🔧 Improved: Config key
bypass—SAUTH_BYPASSuntuk 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()— nilaitruedi production tidak berpengaruh
Lihat: FetchesClientToken
🟢 Medium Impact
Peningkatan:
- Key baru
bypassdiconfig/sauth-server.php(backed bySAUTH_BYPASS, defaultfalse) — hanya mempengaruhiFetchesClientToken
v0.1.2 (2026-05-21)
TL;DR
Perubahan:
- 🔧 Improved:
SAUTH_PRIVATE_KEY_FILE— path private key relatif kestorage_path()untukServiceTokenIssuer(Medium) - 📦 Dependencies: bump
bpmlib/sauth-clientke^0.1.3(Low)
Impact: 🟢 Medium: 1 | 🔵 Low: 1
Backward Compatible: ✅ Ya — default 'oauth-private.key' identik dengan konvensi Passport lama
🟢 Medium Impact
Peningkatan:
ServiceTokenIssuermembaca path private key dariconfig('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-clientdi-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 RuntimeExceptionjikasauth-server.issuer_codekosong; TTL mengikutisauth-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:
TokenExchangeGrantRFC 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_partydioauth_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: hanyasid 'wm'padafetbypass semua permission checks disauth.gate- Bind di
AppServiceProvider::register()sebelumSauthServerServiceProviderme-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
--forceuntuk regenerasi key (rotasi)- Migration
is_first_partydi-ship sebagai stub dalam library, di-copy langsung kedatabase/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 plainSecrethanya 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_credentialsdi.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
resourcewajib (RFC 9700 — satu token, satu target) - Token hasil exchange membawa
act.subberisi 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) danSAUTH_REFRESH_TOKEN_TTL(default 604800s) - 1st-party vs 3rd-party client dibedakan via kolom
is_first_partydioauth_clients
🔵 Low Impact
Perubahan:
- Published
config/sauth-server.phpviaphp artisan vendor:publish --tag=sauth-server-config - Auto-discovery service provider via Laravel package discovery