Monosign yönetim API'si, SCIM 2.0 ve webhook'lar
Neler değişti
Her içerik güncellemesi sürümlenir. Bir sürümü seçerek öncekiyle karşılaştırın.
Sürüm 7 → 8
GüncellemeKursun MCIE sınavını kapsaması için iki modül eklendi: OAuth istemcileri ve belirteç süreleri, 403 yanıtını okuma, kiracılar, atama ve yetki uç noktaları, SCIM gönderiminin yaptığı çağrılar ve sonuçlarının okunması, Provision Services ve dead letter kayıtları. Yeni derslere diyagramlar ve ilk bakılacaklar listeleri eklendi.
5 ders güncellendisüre
İçerik güncellemesi. Kayıtlı öğrenciler bilgilendirildi.
Süre 30 dakikadan 34 dakikaya değişti.
Bir arka uç Monosign ile yalnızca `Rest API` anahtarıyla konuşmaz. Kendi API'niz Monosign'ın verdiği belirteçleri kabul edecekse çağıran taraf bir **OAuth istemcisidir** ve belirteç isteğinin çalışıp çalışmayacağını birkaç kural belirler.
### Bir anahtar bir istemcidir
İstemci; `OIDC/OpenID`, `OAuth 2.0` veya `JWT` türünde bir uygulama anahtarıdır. Anahtar `client_id`, anahtarın sırrı `client_secret` olur. Üç anahtar türü üç yol önekiyle sunulur: `/openid`, `/oauth` ve `/jwt`. Arkadaki işleyici aynıdır, ancak hangi anahtar türünün aranacağını önek belirler; bu yüzden istemci, oluşturulduğu türün önekini çağırmalıdır. Doğru kimlik ve sır yanlış öneke gönderilirse reddedilir.
### Client credentials isteği
Arka uç işinde kullanıcı da tarayıcı da yoktur, bu yüzden client credentials akışı kullanılır. İstek yalnızca akış türünü ve istemcinin kendi kimlik bilgilerini ister:
```
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=<anahtar>&client_secret=<anahtar sırrı>
```
Bu akışta yönlendirme adresi ve kullanıcı adı yoktur, çünkü kimse oturum açmaz.
::diagram api-client-credentials
### Public client bunu yapamaz
`Public Client` seçeneği açık olan anahtar tek sayfa, mobil ve komut satırı uygulamaları içindir. Sırrı yoktur, PKCE zorunlu olur ve client credentials akışı `The client_credentials grant is not allowed for public clients.` iletisiyle reddedilir. Arka uç işi çalışsın diye seçeneği kapatmayın. İş için kendi anahtarı ve sırrı olan ikinci, gizli (confidential) bir istemci kaydedin; böylece her çağıran tek başına döndürülebilir.
### Süreler dakika cinsindendir
| Ayar | Boş veya `0` ise | Birim |
| --- | --- | --- |
| `Access Token Lifetime` | 5 dakika | dakika |
| `Refresh Token Lifetime` | 30 dakika | dakika |
| `ID Token Lifetime` | 1 dakika | dakika |
v2026.07-hf02 sürümüne kadar client credentials yolu, formda `In minutes` yazmasına rağmen bu değerleri saniye olarak okuyordu. v2026.09'dan beri her yol dakika okur. Eski sürümde bir saat için `3600` girilmiş bir anahtar artık 3600 dakika, yani 60 saat yaşayan belirteçler verir. Yükseltmeden sonra `60` girin.
### Hangi belirtece ne yazılır
Anahtardaki `Audience` ve `Resource` yalnızca **erişim belirtecine** yazılır. ID belirteci istemcinin kendisine yöneliktir, bu yüzden `aud` değeri istemci kimliği olarak kalır. `aud` doğrulayan bir API bu nedenle ID belirtecini değil erişim belirtecini doğrulamalıdır.
### Kullanıcıyı devre dışı bırakmak belirteçleri geri çağırmaz
Verilmiş erişim belirteçleri `exp` anına kadar geçerli kalır. Duran şey bir sonraki yenilemedir: etkin olmayan veya `Enabled` durumunda olmayan kullanıcı için belirteç uç noktası `The refresh token is no longer valid.` yanıtını verir. İkisi arasındaki boşluk erişim belirtecinin ömrü kadardır; onu daraltan ayar kısa bir `Access Token Lifetime` değeridir.
### Token isteği başarısız olursa önce neye bakmalı
1. Yol öneki (`/openid`, `/oauth` ya da `/jwt`) anahtarın oluşturulduğu türle eşleşiyor mu?
2. `Public Client` açık mı? Böyle bir anahtar client credentials grant kullanamaz.
3. Bir yükseltmeden sonra token'lar planlanandan çok mu uzun yaşıyor? Ömür alanlarını dakika olarak okuyun.
Bir entegrasyonla ilgili destek kayıtlarının çoğu reddedilen tek bir çağrıyla başlar. Yanıtın tamamını okursanız ne yapmanız gerektiğini yanıt kendisi söyler.
### 403 yanıtı izni adıyla söyler
API Security açıkken, izni anahtara verilmemiş bir uç noktaya yapılan çağrı HTTP 403 döner. Gövde şuna benzer:
```
{
"Message": "Permission Denied",
"InternalMessage": "Permission denied for this API endpoint. You need to have one of the following permission(s): System.API.Users.View."
}
```
`InternalMessage`, uç noktanın kabul ettiği izinleri listeler. Çalışma yöntemi hep aynıdır:
1. İzin adını 403 yanıtından kopyalayın.
2. Uygulamayı, `Keys` bölümünü, anahtarı ve `Permissions` sekmesini açın.
3. Bu adı `Search` ile bulun ve `Grant` edin. Yalnızca 403 yanıtının söylediğini verin. Daha geniş bir izin, anahtarın çağırabildiklerini genişletir.
### Sonraki çağrı neden hâlâ başarısız olabilir
Her API süreci, güvenlik ayarlarının bellekteki kendi kopyasından yanıt verir. Değişiklik, süreç önbellekteki kaydı bıraktığında görülür; bu kısa süre sonra olur, anında değil. Yük dengeleyicinin arkasında iki örnek bu kısa aralıkta farklı yanıt verebilir. İzinden hemen sonra çağrı yine 403 dönerse biraz bekleyin ve örnekleri tek tek sınayın. Tepki olarak daha fazla izin vermeyin ve API Security'yi kapatmayın.
::diagram api-403-path
### v2026.09 varsayılanının dokunmadığı yerler
Güvenli varsayılan yalnızca tek bir anda yazılır: hiç ayarı olmamış bir uygulamada yeni bir `Rest API` anahtarı oluşturulduğunda. Müşteri mevcut entegrasyonlarını sorduğunda iki sonuç işinize yarar:
- Açık ya da kapalı, bilinçli bir seçimi olan uygulama bu seçimi korur.
- Mevcut bir anahtarı düzenlemek varsayılanı hiçbir zaman uygulamaz.
### Kiracılar
Bir anahtar tek bir kiracıya aittir. Müşteri kiracısının anahtarı başka bir kiracıda asla işlem yapamaz. v2026.10'dan beri desteklenen tek devir yolu vardır: **ana kiracının master `api` uygulamasının** anahtarı çağrısıyla birlikte bir ana kiracı devir başlığı gönderebilir ve çağrı isteğin kiracısı içinde çalışır. Bunu deneyen başka her anahtar `Invalid Application Key` yanıtı alır. Birden çok kiracıya hizmet veren otomasyon için seçim bu yüzden basittir: her hedef kiracının kendi anahtarını kullanın ya da ana kiracının master uygulamasını kullanın.
### API yazmaları kendiliğinden provizyon başlatmaz
Management'ta kullanıcı oluşturmak, kaydetmek veya kaldırmak, kullanıcıyı her zaman Provision Services kuyruğuna alır. API farklı davranır: kullanıcı oluşturma veya güncelleme çağrısı yalnızca `AutoProvision` ayarlandığında provizyonu kuyruğa alır. İK entegrasyonunun oluşturduğu kullanıcılar müşterinin provizyon uç noktasına hiç ulaşmıyor, elle oluşturulanlar ulaşıyorsa servise bakmadan önce istek gövdesine bakın.
Yaşam döngüsü otomasyonunun çoğunu üç kaynak ailesi taşır: uygulama atamaları, yetkiler (entitlement) ve denetim kayıtları. Her birinin entegrasyon geliştiricileri şaşırtan bir davranışı vardır.
### Uygulama atamaları
| Çağrı | İzin | Ne yapar |
| --- | --- | --- |
| `POST v1.4/application-users/detail` | `System.API.ApplicationUsers.View` | Bir atamayı okur |
| `PUT v1.4/application-users` | `System.API.ApplicationUsers.Edit` | Mevcut bir atamayı değiştirir |
| `DELETE v1.4/application-users/{id}` | `System.API.ApplicationUsers.Remove` | Tek bir atamayı kaldırır (v2026.10 ve sonrası) |
`PUT` hiçbir zaman atama oluşturmaz. Gönderdiğiniz `UserId` ve `ApplicationId` için etkin ve kaldırılmamış bir atama arar; yoksa 404 `Application user not found` döner.
### Bitiş tarihini doğru şekilde uzatmak
İstekte iki tarih alanı vardır ve işleri farklıdır. `NewExpirationDate` yeni bitiş tarihini **yazar**. Eski `ExpirationDate` ise yalnızca **aramayı daraltır**; yeni tarihi oraya gönderirseniz arama satırı bulamaz ve çağrı 404 döner.
```
PUT v1.4/application-users
{
"UserId": "<kullanıcı kimliği>",
"ApplicationId": "<uygulama kimliği>",
"NewExpirationDate": "2026-12-31T23:59:59Z"
}
```
`ExpirationDate` alanını göndermeyin. JSON kitaplığınızın ayarlanmamış bir tarih için ne gönderdiğine de bakın. `NewExpirationDate` bir değer taşıdığı her durumda uygulanır ve sunucuda geçmiş tarihlere karşı bir koruma yoktur: `0001-01-01T00:00:00` gibi varsayılan bir tarih atamayı anında sona erdirir. Bitiş tarihini değiştirmek istemiyorsanız `null` gönderin veya alanı hiç göndermeyin.
### v2026.10 ile değişenler
- Master yetkisi olmayan bir anahtar yalnızca **kendi uygulamasının** atamalarına ulaşır. Başka bir uygulamanın ataması için detail, `PUT` ve `DELETE` çağrıları 404 `Application user not found` döner. Birden çok uygulamayı yöneten entegrasyonun master yetkisine veya uygulama başına bir anahtara ihtiyacı vardır.
- `DELETE v1.4/application-users/{id}` eklendi. Atamayı geri alınabilir biçimde kaldırır, `Removed` tetikleyicisini çalıştırır ve geri alma olayını erişim zaman çizelgesine yazar. Yetki kaldırma (deprovisioning) için bunu kullanın. Geçmiş bir bitiş tarihi vermek atamayı yalnızca sona erdirir ve bu izi oluşturmaz.
### Yetkiler üzerinden grup üyelikleri
`POST v1.5/entitlements/groups` bir kullanıcıyı gruba ekler. v2026.10'dan itibaren aynı eklemenin tekrarı `409` ve `EntitlementAlreadyExists` koduyla yanıtlanır ve mevcut üyeliğin kimliğini taşır. Zaman aşımından sonra yeniden deneyen bir istemci için çağrıyı idempotent yapan yanıt budur: işlemi tamamlanmış sayın. Bu kimlikle yapılan `DELETE v1.5/entitlements/{objectAssignmentId}` üyeliği sona erdirir.
v2026.10 öncesinde aynı çağrı, grup deposunun hiç görmediği bir kayıt yazıyordu; bu yüzden kurallar ve tetikleyiciler üyeliği yok sayıyordu. Bu eski kayıtlar yükseltmeden sonra da yok sayılmaya devam eder. Çözüm, üyelikleri API üzerinden yeniden eklemektir.
::diagram api-entitlement-retry
### Denetim kayıtları bir liste API'si değildir
`v1.4/audit` yalnızca `GET {id}`, `POST` ve `POST bulk` sunar. Son ikisi dış sistemler için denetim satırı yazar. `System.API.Audits.List` adında bir izin bulunsa da liste yolu yoktur; Audit sayfasında dosya dışa aktarma da yoktur. Bir haftalık denetim satırlarını veri gölüne taşımak için `Audit Events` veri kaynağıyla bir Report Studio raporu oluşturun ve dosya olarak teslim edin.
Hedef üretici, hangi SCIM işlemlerini desteklemesi gerektiğini soracaktır. Yanıt kısadır ve bunu bilmek, ileride karşılaşacağınız belirtilerin çoğunu açıklar.
### Tek bir kullanıcı için yapılan çağrılar
Gönderim, atanmış her kullanıcı için önce kullanıcıyı arar, sonra karar verir:
```
GET /Users?filter=userName eq "jdoe"
```
| Arama sonucu | Atama | Sonraki çağrı |
| --- | --- | --- |
| Kullanıcı yok | Etkin | `POST /Users` |
| Bir kullanıcı | Etkin | `PUT /Users/{id}` |
| Bir kullanıcı | Etkin değil | `DELETE /Users/{id}` |
| Birden çok kullanıcı | Fark etmez | Hiçbiri, kullanıcı atlanır |
Kullanıcı belgesi `userName`, iş e-postası, ad ve soyad, `externalId` ve `active` alanlarını taşır. Kullanıcı gönderimi `PATCH` kullanmaz. Bu yüzden hedefin `/Users` üzerinde `eq` ile `filter` parametresini ve `POST`, `PUT`, `DELETE` işlemlerini desteklemesi gerekir.
::diagram api-scim-user-decision
### Arama özniteliğini seçmek
Gelişmiş ayarlardaki `User Identifier Property`, filtrenin hangi özniteliği kullanacağını belirler. Varsayılan `externalId` değeridir. İşe yarayan diğer değerler `userName` ve `email` olur. Servis günlüğündeki iki satır, seçimin hedefe uymadığını söyler:
| Servis günlüğü satırı | Anlamı | Çözüm |
| --- | --- | --- |
| Her çalıştırmada `SCIM API returned no result for user ... Will be created.` ve biriken yinelenen hesaplar | Hedef, filtrelediğiniz özniteliği saklamıyor; arama her seferinde boş dönüyor | Hedefin sakladığı bir öznitelik seçin; örneğin `userName` veya `email` |
| `SCIM API returned more than one user ...` ve kullanıcı hiç güncellenmiyor | Öznitelik hedefte benzersiz değil | Tam olarak tek bir hesabı gösteren bir öznitelik seçin |
### Force Sync ve zamanlama
`Force Sync`, `Features` ve `Enable Auto-sync` ayarlarına bakmadan kullanıcıları ve grupları hemen gönderir; bu yüzden test sırasında doğru düğmedir. Yanıtı şuna benzer: `120 users sync is completed. [112 success / 0 skipped / 8 error]`. Sayıları dikkatle okuyun: skipped sayacı hiç artırılmaz; bu yüzden örneğin adı eksik olduğu için atlanan kullanıcılar error altında görünür. Hedefi suçlamadan önce servis günlüğüne bakın.
**Zamanlanmış** gönderim yalnızca üç koşul sağlandığında başlar: uygulama etkindir, `Enable Auto-sync` açıktır ve bir `Timing` girdisinin sıradaki zamanı gelmiştir. `Timing`, her saat belirli bir dakikada veya her gün belirli bir saatte seçeneklerini sunar; ikisi de UTC'dir ve form yanında güncel UTC ile yerel saati gösterir. UTC+3'teki bir müşteri yerel 02:00 istiyorsa `Every Day at 23:00` girer.
### Gruplar
Gruplar `PUT` ile yazılır ve Monosign grup kimliğini taşıyan `externalId` ile eşleştirilir. Grup adımı, hedefteki her grubun `externalId` değerini böyle bir kimlik olarak okur. `externalId` alanında düz metin etiketi olan tek bir eski hedef grubu, tüm grup adımını durdurur ve eşlediğiniz grupların hiçbiri ulaşmaz. Önce o grubu hedefte temizleyin. `Group Identifier Property` saklanır ancak gönderim onu okumaz; değiştirmek işe yaramaz.
### Giden proxy
Gönderim, Settings altındaki `System` bölümünde bulunan genel `Proxy Host` ayarını okur. Açıklaması, proxy'nin SCIM, SMS, arama, push ve lisans servislerinde kullanıldığını söyler. Alan boşsa gönderim doğrudan bağlanır; internete yalnızca proxy'nin çıkabildiği ağlarda bu başarısız olur.
### Bunun yerine bir SaaS uygulamasının gruplarını okumak
`SCIM Entitlement Provider` kaynağı ters yönde çalışır: uygulamanın gruplarını yetki, üyelerini de atama olarak içe alır. `Test` düğmesi dört adım çalıştırır: `Connect to SCIM endpoint`, `Read users and groups`, `Provisioning capability` ve `User matching`. Üçüncü adım, sunucunun PATCH desteğini bildirmediği uyarısıyla biterse içe alma yine çalışır; ancak üyelik `PATCH /Groups/{id}` ile sağlandığı için Monosign'dan üye ekleme ve çıkarma büyük olasılıkla başarısız olur.
### Önce neye bakmalı
| Belirti | Bakılacak yer |
| --- | --- |
| Yinelenen kayıtlar ya da hiç güncellenmeyen kullanıcılar | `User Identifier Property` ve yukarıdaki iki servis günlüğü satırı |
| `Force Sync` hata bildiriyor | Servis günlüğü; atlanan kullanıcılar hata olarak sayılır |
| Zamanlanmış gönderim hiç başlamıyor | Uygulama etkin mi, `Enable Auto-sync` açık mı ve UTC olarak bir `Timing` girdisi var mı |
| Eşlenen gruplardan hiçbiri ulaşmıyor | Hedefte zaten var olan grupların `externalId` değeri |
| Gönderim bağlanamıyor | Settings, `System` altındaki `Proxy Host` |
Giden tek yol SCIM değildir. Bir **Provision Service**; bir provizyon sağlayıcısını başlık, `Url`, JSON ayarları ve kurallarla bir uygulamaya bağlar. Kullanıcı provizyon servisi her kullanıcıyı etkin her servise göre değerlendirir ve provizyon ya da deprovizyon işini müşterinin uç noktasına gönderir. O uç noktayı siz yazıyorsanız tasarımınızı tek bir iş satırının yaşamı belirler.
### Bir satırın yaşamı
| Adım | Ne olur |
| --- | --- |
| Kuyrukta | Satır `WaitingForProvision` (veya deprovizyon karşılığı) olarak bekler |
| Gönderildi | Servis `Url` adresine POST yapar; satır `Provisioning` olur |
| Uç noktanız 2xx döner | Başka hiçbir şey değişmez. Geri çağrı yoktur ve satırı tamamlandı yapan bir şey yoktur |
| Yaklaşık bir saat sonra | Bir tarama, hâlâ yolda olan satırları beklemeye geri alır ve satır yeniden POST edilir |
| Satırın oluşturulmasından 48 saat sonra | Yeniden deneme bütçesinin bittiği iletisiyle hata olarak işaretlenir ve `Dead Letters` altında görünür |
Sonuç, bu dersin en önemli cümlesidir: **2xx satırı sonlandırmaz; uç noktanız aynı kullanıcıyı yaklaşık her saat yeniden alır.** Tekrarın hiçbir şeyi değiştirmeyeceği biçimde tasarlayın: önce hesabı arayın, yalnızca yoksa oluşturun ve her iki durumda da 2xx dönün.
::diagram api-provision-row-life
### Yanıltan üç ayar
- **`Url` zorunlu değildir.** `Url` boşsa servisin satırları sonsuza dek `WaitingForProvision` kalır ve hiçbir hata günlüğe yazılmaz. Yeni bir servis hiçbir şey teslim etmiyorsa önce buna bakın.
- **`State` saklanan bir rozettir.** Hiçbir şeyi başlatmaz veya durdurmaz.
- **`Remove` silmez.** Yalnızca `Is Enabled` değerini false yapar ve rollerin çoğu denediğinde 403 alır. Bir servisi bir süreliğine kullanımdan çıkarmak için `Edit` ile açın, `Is Enabled` işaretini kaldırın ve kaydedin. Bu duraklatma geri alınabilir ve servisin daha önce oluşturduğu hesapları deprovizyon etmez.
### Kimler kapsam dışı sayılır
Etkin olmayan, `Enabled` olmayan veya **e-posta adresi bulunmayan** kullanıcı her kuralın dışında sayılır ve deprovizyon kuyruğuna alınır. Bu yüzden e-posta adreslerini boşaltan bir veri temizliği, müşteri tarafındaki gerçek hesapları kaldırabilir. Böyle bir temizlikten önce İK ekibiyle bunu konuşun.
`Start Full User Provision` her kullanıcıyı etkin her servise göre denetler. `Full User Provision is Started.` bildirimi hiçbir iş yapılmadan önce görünür ve ilerleme ekranı yoktur. Tıklamadan önce her servisteki kuralları ve `Is Enabled` değerini gözden geçirin, çünkü kural dışında kalan kullanıcılar kaldırılmak üzere kuyruğa alınır.
### Provizyon için dead letter kayıtları
Management, System, Services altındaki `Dead Letters`, bütçesi biten provizyon satırlarını listeler. Bunlar kendiliğinden yeniden denenmez.
| Düğme | Ne zaman kullanılır | Etkisi |
| --- | --- | --- |
| `Requeue` | Neden giderildi ve kullanıcının hesaba hâlâ ihtiyacı var | Satır bekleme durumuna döner ve servis onu yeniden alır. Yeniden başarısız olup listeye dönebilir |
| `Discard` | İş başka bir yolla zaten yapıldı; örneğin BT hesabı elle oluşturdu | Satır kalıcı bir discarded durumuna geçer, içeriğini ve son hatasını korur, hiçbir şey gönderilmez |
Discard geri alınamaz, ancak geleceği engellemez: kullanıcı yeniden uygun hâle geldiğinde yeni iş kuyruğa alınır.