00 · AUTH — Açılış Sözleşmesi
Görev: Uygulama açıldığında kimliği doğrular, güncel config versiyonlarını ve bir token döndürür; açılışta ne yapılacağına dair karar (decision) verir.
Ne zaman çalışır: Her uygulama açılışında — ilk çalıştırmada ve sonrasında her seferinde.
Bu dosyayı örnek istek/yanıtlarla birlikte okuyun: JSON'lar doldurulmuş örnektir; bölümdeki tablolar alanların anlamını anlatır.
1. Genel Bakış
AUTH, döngünün ilk ve her seferinde çalışan adımıdır. SDK sunucuya iki şey gönderir:
- Kimlik →
apiKey+packageName+platform+consentId - Cihazda önbelleklediği mevcut durumu →
localState(kurulu versiyonlar + önceki onay haritası)
Sunucu karşılığında üç şey döndürür:
- Versiyonlar →
schemaVersion/uiVersion/legalVersion/contentVersion - Token → oturum bazlı config token'ı (
tokenExpiresInsaniye ile geçerlilik) - Karar →
decision: config yenileme mi, tekrar sor (reprompt) mu, yoksa sessizce devam mı?
Tasarım felsefesi: AUTH hafif ve hızlı tutulur. Güncel config (tema, ekranlar, gruplar, metinler — büyük gövde) yalnızca değiştiğinde, decision.updateRequired === true olduğunda, bir sonraki adım olan 01 · GET /config ile çekilir. İçerik değişmiyorsa config hiç transfer edilmez → açılış hızlı, veri tasarruflu, gecikme düşük.
2. İki Aşamalı Açılış Akışı
┌──────────────┐ kimlik + localState ┌──────────────┐
│ SDK (App) │ ─────────────────────▶ │ SUNUCU │
│ │ ◀───────────────────── │ │
└──────────────┘ versiyon + token + decision └──────────────┘
│
decision.updateRequired ?
┌───────────────┴───────────────┐
│ TRUE │ FALSE
▼ ▼
GET /config (01) Mevcut config'i
token ile tam config indir, cihazdaki önbellekten
parse et, önbelleğe yaz, kullan; sürüye devam et
UI'ı yeniden kur
│
▼
decision.retriggerRequired /
showConsentOnLaunch → onay ekranını göster mi?
| Adım | Koşul | SDK davranışı |
|---|---|---|
| 1 — AUTH (bu sözleşme) | Her açılışta | Kimlik + localState gönder; versiyon + token + decision al |
| 2 — GET /config | decision.updateRequired === true ise | Token ile tam config indir, parsel et, önbelleğe yaz, UI'ı yeniden kur |
| 3 — Onay kararı | showConsentOnLaunch veya retriggerRequired true ise | Onay ekranını (banner/manager) göster; aksi halde sessiz devam |
3. Endpoint & Güvenlik
3.1 Endpoint
| Özellik | Değer |
|---|---|
| Method | POST |
| Path | /v2/consent/{consentId}/auth |
| Base URL | {{SDK_BASE_URL}} |
| Gövde formatı | application/json (UTF-8) |
| Timeout | 15 sn |
| Idempotent | Evet — aynı istek tekrarlandığında aynı sonucu verir |
3.2 Güvenlik (imza ile sahte/replay istek koruması)
Kimlik doğrulaması yalnız apiKey ile değil, HMAC imza + nonce + zaman damgası üçlüsüyle yapılır. İstek şunları taşır:
| Header | Değer / Formül |
|---|---|
Content-Type | application/json |
X-Consent-SDK-Key | apiKey (body'deki apiKey'ye alternatif; üretimde header tercih edilir) |
X-Consent-Signature | HMAC-SHA256(apiKey, packageName + platform + requestTimestamp + nonce) — hex kodlanmış |
X-Request-Timestamp | epoch milliseconds |
X-Nonce | Tek kullanımlık rastgele string |
- Algoritma:
HMAC-SHA256 - İmza girdisi (canonical):
packageName + platform + requestTimestamp + nonce - Replay penceresi:
±300 sn. Penceresi dışındaki timestamp veya tekrar eden nonce →401 REPLAY_DETECTED.
AUTH ve POST_CONSENT yazma/durum değiştirici sözleşmeler olduğu için imza/nonce/timestamp zorunludur. (GET /config bir okuma işlemidir; orada imza yerine yalnız token kullanılır —
01 · GET /config§3.)
4. İstek (request)
Uygulamanın gönderdiği gövde. Kimlik alanları zorunludur; geriye kalanlar isteğe bağlıdır ama kararın doğruluğunu artırır. camelCase zorunludur.
| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
apiKey | string | Evet | Uygulamanın gizli API anahtarı (kendi Apps Console'undan). Yanlış/çözülmüş anahtar → 401 INVALID_API_KEY. |
consentId | string | Evet | Onay kaydının benzersiz kimliği (ör. ck_mobildev_0001). Hangi consent setinin çözüleceğini belirler. Path'teki {consentId}'yle birebir aynı olmalıdır. |
packageName | string | Evet | Paket/identifier. Android: reverse-domain (com.mobildev.app); iOS: bundle id (com.mobildev.ios). apiKey'nin bu package'a tanımlı olup olmadığı doğrulanır; uyuşmazlık → 403 PACKAGE_MISMATCH. |
platform | enum iOS | Android | Evet | Hedef platform. Paket formatı, platform bazlı davranış (örn. iOS ATT) ve şema feature-gate kararı buna göre çözülür. |
sdkVersion | string (semver) | Evet | SDK paketinin sürümü. schemaVersion ile birlikte feature-gate kararında kullanılır; eski SDK yeni şemayı çözemiyorsa uyumlu config setine yönlendirilir. |
appVersion | string (semver) | Hayır | Müşteri uygulamanın sürümü. Telemetri/korelasyon için; auth kararını doğrudan etkilemez. |
buildNumber | integer | Hayır | iOS CFBundleVersion / Android versionCode. Aynı appVersion içinde farklı build'leri ayırt eder. |
locale | string (BCP-47) | Hayır | Kullanıcı dili (ör. tr-TR). Config'in availableLanguages'inde varsa o dil, yoksa defaultLanguage çözülür. |
deviceTime | string (ISO 8601 UTC) | Hayır | Cihaz saati. Sunucu saatiyle drift/manipülasyon kontrolü; aşırı drift → 400 CLOCK_DRIFT. |
device | object | Hayır | model, osVersion. Hata teşhis ve uyumluluk raporlama içindir; auth kararında doğrudan kullanılmaz. |
localState | object | Hayır | Cihazda önbelleklenen mevcut durum. Sunucunun karar üretmesinin geri beslemesidir (aşağıda detay). İlk çalıştırmada null/boş bırakılır. |
4.1 localState Alt Alanları
| Alan | Tip | Açıklama |
|---|---|---|
hasConsent | boolean | Bu cihazda daha önce onay var mı? false = ilk açılış → ilk onay ekranı gösterilir. |
installedUiVersion | string | null | Önbellekteki UI/theme/layout versiyonu. Remote uiVersion'dan düşükse görünüm yenilenir (reprompt yok). |
installedLegalVersion | string | null | Önbellekteki legal/metin versiyonu. Remote'dan yüksekse metin yenilenir ve onay varsa reprompt. |
installedContentVersion | string | null | Önbellekteki içerik versiyonu. Remote'dan yüksekse retriggerRequired = true (içerik değişti → tekrar sor). |
lastShownAt | string | null (ISO 8601) | Onay ekranının son gösterildiği an. Config'de retrigger.interval tanımlıysa bu değer interval'ı aşarsa zaman bazlı reprompt devreye girer. |
consent | object | null | Önceki onay haritası. Anahtarlar groupId'lerdir (essential/functionality/targeting/tracking); değerler yalnız granted / denied. Bir sonraki adım (02 · POST_CONSENT'in localState) ile birebir aynı yapıdır — burada geri beslemesi için gönderilir. |
4.2 Örnek İstek (ilki açılış — localState boş)
{
"apiKey": "sk_live_9f2ac41ab88e3d5c7e9f",
"consentId": "ck_mobildev_0001",
"packageName": "com.mobildev.app",
"platform": "Android",
"sdkVersion": "1.4.0",
"appVersion": "2.8.0",
"buildNumber": 280,
"locale": "tr-TR",
"deviceTime": "2026-09-20T11:33:29Z",
"device": { "model": "Pixel 9", "osVersion": "Android 15" },
"localState": {
"hasConsent": false,
"installedUiVersion": null,
"installedLegalVersion": null,
"installedContentVersion": null,
"lastShownAt": null,
"consent": null
}
}
Daha sonraki açılışlarda
localStatedolu gelir (02 adımında sunucunun döndürdüğülocalState, buraya aynen kopyalanır). Doğru retrigger kararı bu bloğun doluluğuna bağlıdır. Bu örneğin aynısı ayrıca[00-auth.request.json](./00-auth.request.json)dosyasında yer alır.
5. Yanıt (response)
5.1 Gövde Alanları (200)
| Alan | Tip | Açıklama |
|---|---|---|
success | boolean | İsteğin başarıyla tamamlandığı. |
code | string | Durum kodu (başarıda OK). |
consentId | string | Çözülen consentId (eko; log/teşhis). |
schemaVersion | string | SDK feature-gate versiyonu (örn. 2.0). Eski SDK uyumlu set kullanır. |
uiVersion | string | Mevcut UI/theme/layout versiyonu. Cihazdaki installedUiVersion'dan yüksekse görünüm yenilenir (reprompt değil, yalnız görsel). |
legalVersion | string | Mevcut legal/metin versiyonu. Cihazdaki installedLegalVersion'dan yüksekse metin yenilenir ve onay varsa reprompt. |
contentVersion | string | Mevcut içerik versiyonu. Cihazdaki installedContentVersion'dan yüksekse retriggerRequired = true. |
contentMode | enum sample | production | İçerik modu. sample → geliştirme/test verisi. |
generatedAt | string (ISO 8601) | Config'in sunucuda yayınlanma/üretim zamanı. |
token | string | GET /config ve POST_CONSENT'te kullanılacak imzalı, oturum bazlı token (örn. cfg_t_8a3f5c2d1e0b). |
tokenExpiresIn | integer | Token geçerlilik süresi (saniye). Dolunca yeniden AUTH yapılır. |
decision | object | SDK'nın açılışta ne yapacağını belirten karar bloğu (aşağıda). |
Versiyon modeli — üç bağımsız katman: schemaVersion (şema/SDK feature-gate) · uiVersion (görünüm) · legalVersion + contentVersion (içerik). Bu ayrım, "yalnız görsel değişti" ile "içerik/majör şema değişti" arasındaki reprompt farkını üretir: içerik veya majör şema değişimi reprompt üretir; yalnız görsel değişimi reprompt üretmez (görsel yenilenir).
5.2 decision Alt Alanları
| Alan | Tip | Açıklama |
|---|---|---|
updateRequired | boolean | true → config yenileme gerekli; token ile GET /config yapılır. |
retriggerRequired | boolean | true → onay mevcut ama içerik/majör değişiklik var; onay ekranı yeniden gösterilir. |
showConsentOnLaunch | boolean | Bu açılışta onay ekranının gösterilip gösterilmeyeceği. İlk çalıştırmada veya retrigger gerekliyse true; config değişimi yoksa false. |
reasons | array<enum> | Kararı üreten nedenler (çeşitli olabilir). Loglama/teşhis. |
reasons değerleri: FIRST_RUN, NO_CACHED_CONFIG, CONTENT_UPDATED, LEGAL_UPDATED, UI_UPDATED, INTERVAL_RETRIGGER, MAJOR_SCHEMA_CHANGE, TOKEN_EXPIRED, NO_CHANGE.
5.3 Örnek Yanıt (ilk açılış — config + onay ekranı gerekli)
{
"success": true,
"code": "OK",
"consentId": "ck_mobildev_0001",
"schemaVersion": "2.0",
"uiVersion": "2.4",
"legalVersion": "1.0",
"contentVersion": "2",
"contentMode": "sample",
"generatedAt": "2026-09-18T10:20:00Z",
"token": "cfg_t_8a3f5c2d1e0b",
"tokenExpiresIn": 300,
"decision": {
"updateRequired": true,
"retriggerRequired": false,
"showConsentOnLaunch": true,
"reasons": ["FIRST_RUN", "NO_CACHED_CONFIG"]
}
}
Bu örneğin aynısı ayrıca
[00-auth.response.json](./00-auth.response.json)dosyasında yer alır.
6. Retrigger / Karar Matrisi
Sunucu, cihazdaki localState versiyonlarını remote versiyonlarla karşılaştırarak karar üretir. Retrigger, yalnızca onay zaten varken içerik/majör şema değişirse veya zaman interval'ı aşılır tetiklenir; uiVersion yalnız değişimi reprompt üretmez.
| Cihaz durumu | Remote durumu | updateRequired | retriggerRequired | showConsentOnLaunch | reasons |
|---|---|---|---|---|---|
| Hiç onay yok, cache boş | herhangi | true | false | true | FIRST_RUN, NO_CACHED_CONFIG |
| İlk açılış, cache var ama versiyonlar eski | remote yenisi | true | false | true | FIRST_RUN, UI_UPDATED / CONTENT_UPDATED |
| Onay var, cihaz == remote | eşit | false | false | false | NO_CHANGE |
Onay var, contentVersion/legalVersion arttı | remote yenisi | true | true | true | CONTENT_UPDATED / LEGAL_UPDATED |
Onay var, schemaVersion major arttı | major bump | true | true | true | MAJOR_SCHEMA_CHANGE |
Onay var, yalnız uiVersion arttı | remote yenisi | true | false | false | UI_UPDATED |
interval tanımlı ve lastShownAt aşıyor | — | false | true | true | INTERVAL_RETRIGGER |
| Token süresi dolmuş, yeni AUTH | — | true | false | — | TOKEN_EXPIRED |
Retrigger tetikleyicileri (config behavior.retrigger üzerinden ayarlanır):
| Tetikleyici | Config alanı | Etki | Reprompt üretir mi? |
|---|---|---|---|
| İçerik değişikliği | onConfigChange + contentVersion/legalVersion bump | Onay ekranı yeniden sorulur | Evet |
| Majör şema değişikliği | onMajorChange + schemaVersion major | Onay ekranı yeniden sorulur | Evet |
| Zaman aralığı | interval + lastShownAt | Interval aşıldıysa periyodik reprompt | Evet |
| Görsel değişiklik | uiVersion bump | Yalnız tema/banner yenilenir | Hayır |
Detayda bu tetikleyiciler config'in
behavior.retriggerbloğunda tanımlanır (onConfigChange/onMajorChange/interval). Müşteri, reprompt davranışını bu flag'lerle ayarlar (örn.interval: "180d"→ 180 günde bir tekrar sor).
7. Hata Kodları
Hatalarda ortak gövde döner: { success:false, code, message, retryable, requestId }. message insan-okunur teşhis metnidir; UI'da gösterilmez (kullanıcıya gösterilecek metin config'in localization bloğundan gelir, ör. error_state).
code | HTTP | retryable | Açıklama / SDK müdahalesi |
|---|---|---|---|
OK | 200 | — | Başarılı. |
INVALID_API_KEY | 401 | Hayır | apiKey geçersiz/bilinmiyor → kendi Console'unda anahtarı kontrol et. |
SIGNATURE_MISMATCH | 401 | Hayır | HMAC imza doğrulanamadı (secret/anahtar tutarsızlık) → imza girdisi + secret kontrolü. |
REPLAY_DETECTED | 401 | Hayır | Nonce tekrar kullanıldı veya timestamp replay penceresi dışı → cihaz saati + nonce üretimi. |
PACKAGE_MISMATCH | 403 | Hayır | apiKey bu packageName'e tanımlı değil → Console'da uygulama/anahtar eşleşmesi. |
CONSENT_NOT_FOUND | 404 | Hayır | consentId kaydı yok → consentId değeri doğrulanmalı. |
VALIDATION_ERROR | 400 | Hayır | Gövde şemayı karşılamıyor (zorunlu eksik/tip/enum hatası) → detail[] alan hatalarını düzelt. |
CLOCK_DRIFT | 400 | Evet | Cihaz saati sunucudan kabul edilemez ölçüde sapmış → NTP ile ayarla. |
RATE_LIMITED | 429 | Evet | Hız sınırı aşıldı → Retry-After (sn) kadar bekle, yeniden dene. |
SERVER_ERROR | 500 | Evet | Sunucu iç hata → önbellek config kullanılır, arka planda yeniden denenebilir. |
retryablesemantiği:false→ aynı istekle tekrar denemek işe yaramaz; farklı müdahale gerekir.true→ daha sonra yeniden denenebilir.
8. Offline Davranışı (KRİTİK)
Onay deneyimi sessizce bozulmamalı. Bağlantı yoksa bile kullanıcı onay akışını yaşar.
- AUTH, timeout (15 sn) veya hata ile başarısız olursa → SDK, son bilinen önbellek config'i + onay durumunu kullanmaya devam eder.
- Bağlantı gelince arka planda AUTH yeniden denenebilir;
decision.updateRequired === trueise config yenileme tetiklenir. - Hiç önbellek yoksa (ilk kurulum + çevrimdışı) → SDK'ya dahil edilen (bundled) varsayılan config ile onay akışı çalışır; kullanıcı boş ekranda bırakılmaz.
- Tüm çevrimdışı denemeler exponential backoff ile sınırlıdır; sonsuz döngü üretilmez.
9. Developer Notları
- AUTH hafif kalmalıdır. Her açılışta yalnız versiyon + token + decision döner. Tam config,
decision.updateRequired === trueolduğunda01 · GET /configile çekilir — asla AUTH yanıtının içine gömülmez. - Token = oturum kimliği.
tokenExpiresInpenceresi boyunca hem config okuması (tüketmez) hem onay kaydı (tüketir) için geçerlidir. Pencere dolunca veya oturum kapanınca yeniden AUTH yapılır. Token, bağlı olduğuconsentId'e bağlıdır; başka consentId ile kullanılamaz. - Versiyon modeli üç seviyeli ve bağımsızdır. İçerik veya majör şema değişimi → reprompt; yalnız görsel değişimi → reprompt yok, sadece görsel yenileme.
localStategeri beslemedir. SDK bunu cihazda önbelleğe alır ve her AUTH'ında gönderir; ilk çalıştırmada null/boş bırakılır. Doğru retrigger kararı bu bloğun doluluğuna bağlıdır.consentharitasının anahtarlarıgroupId'lerdir. Değerler yalnızgranted/denied.essentialgrubu her zamangranted'tir (kilitli) →security_storageasladeniedyapılmaz. GTM/etiketlere dağıtım (groupId → consentKeys) SDK tarafında yapılır (02 adımında).