Skip to content
ADR-0008Mimari karar kaydıKabul edildisürüm 1.0.02 Ekim 2026

ADR-0008 — İptal Listesinin Yeri ​

Durum: Accepted ✅ (2026-09-09)


Bağlam ​

Tespit edilen çelişki ​

2026-09-09 depo denetiminde, iptal (revocation)Bir belgenin süresi dolmadan geçersiz kılınması; belge veren bunu doğrulayıcıların denetlediği iptal listesinde işaretler. mekanizmasının iki farklı yerde iki farklı şekilde tanımlandığı bulundu:

SPEC-CRED-0001 §5 diyor ki:

Liste off-chain (belge veren (issuer)Belgeyi imzalayıp veren kurum: üniversite, meslek kuruluşu, kamu kurumu ya da şirket. host eder, imzalı/versiyonlu); zincirde yalnızca URI + hash + versiyon + bitmap.

(Cümlenin sonundaki "+ bitmap" ifadesi zaten kendi içinde tutarsızdır — liste off-chain ise bitmap zincirde ne arıyor?)

contracts/src/revocation/StatusListRegistry.sol ise şunu yapıyor:

solidity
function setRevoked(bytes32 issuerId, uint256 index) public onlyIssuer(issuerId)
function setRevokedBatch(bytes32 issuerId, uint256[] calldata indexes) external
function getChunk(bytes32 issuerId, uint256 chunkIndex) external view returns (uint256)
function _setBit(bytes32 issuerId, uint256 index, bool value) private

Yani bitmap zincirde, 256-bit chunk'lar hâlinde. Her iptal bir zincir işlemi.

İkisi aynı anda doğru olamaz. Bu ADR çelişkiyi kapatır.

Neden şimdi ​

Bu, kodun yazıldığı anda fark edilmeyen bir tasarım ayrımıdır ve SPEC-BC-0001'in "Yaklaşım B (bitstring)" kararının iki farklı okuması olmasından kaynaklanır. "Bitstring" veri yapısını tanımlar; nerede durduğunu tanımlamaz. Karar kütüğüne bitstring seçildi diye geçmiş, yerleşim sorusu hiç sorulmamış.


Karar ​

Karar 1 — Bitstring listesi off-chain durur ​

İptal listesi (status list)Her belgenin tek bir konumu olduğu sıkıştırılmış, imzalı liste; geçerli, askıda ya da iptal olduğunu söyler., IETF Token Status List (draft-ietf-oauth-status-list) uyarınca imzalı bir Status List Token olarak belge veren tarafından yayınlanır:

https://status.<issuer-domain>/v1/statuslist/<listId>

Token, belge verenin belge (credential)Belge verenin imzaladığı ve kişinin cüzdanında duran dijital belge; kişi yalnız istenen alanları gösterir. imzalama anahtarıyla aynı güven zincirine bağlı bir anahtarla imzalanır (SPEC-ID-0002 X.509). İçeriği sıkıştırılmış bitstring'dir.

Karar 2 — Zincir yalnızca çapa tutar ​

StatusListRegistry kontratı şunu tutar:

listId        = keccak256(issuerId, listURI)
issuerId      bytes32
listURI       string
contentHash   bytes32     // yayınlanan Status List Token'ın hash'i
listSize      uint256     // min 100.000 (mahremiyet tabanı korunur)
version       uint64      // her yayında artar
publishedAt   uint64
status        {ACTIVE, RETIRED}

Zincirde tek bir bit bile iptal verisi yoktur.

Karar 3 — Yayın döngüsü sabit ve gürültülüdür ​

Belge veren, listeyi sabit aralıklarla yeniden yayınlar (öneri: 1 saat) — o aralıkta iptal olsa da olmasa da. Her yayında contentHash ve version zincirde güncellenir.

Bu, Karar 1'in mahremiyet faydasını korumak için zorunludur. Yalnızca iptal olduğunda yayınlarsak, zincirdeki güncelleme işleminin kendisi "bu saatte bir iptal oldu" bilgisini sızdırır — yani kaçtığımız problemi geri getiririz.

Karar 4 — StatusListRegistry.sol yeniden yazılacaktır ​

_setBit, getChunk, setRevoked, setRevokedBatch, unsetRevoked fonksiyonları kaldırılır. Yerlerine publishList(...) ve getListAnchor(...) gelir.

ITrustQueries.sol içindeki IStatusList.isRevoked(issuerId, index) arayüzü de kaldırılır — zincir artık bu soruyu cevaplayamaz ve cevaplayacakmış gibi görünen bir arayüz bırakmak tehlikelidir.

Karar 5 — Doğrulama akışı ​

doğrulayıcı (verifier)Gösterilen belgeyi denetleyen taraf: imza, belge verenin güven listesindeki kaydı, durum ve politika. Relying party diye de anılır.:

  1. Belgenin status claim'inden listURI + index alınır.
  2. Status List Token indirilir (veya önbellekten alınır).
  3. Token'ın imzası doğrulanır.
  4. Token'ın hash'i, zincirdeki contentHash ile karşılaştırılır.
  5. version yeterince taze mi kontrol edilir (politika: örn. son 24 saat).
  6. Bitstring'de index okunur.

Adım 4 kritiktir: belge verenin kendi sunucusunda listeyi sessizce geri alması (iptal edilmiş bir belgeyi "geçerli" göstermesi) böyle engellenir.


Gerekçe ​

1. Mahremiyet — asıl gerekçe bu ​

On-chain bitmap'in en ciddi problemi gas değil, iptal anının sızmasıdır.

İzinli bir ağda her işlem her validator'a görünür ve blok zaman damgası taşır. setRevoked(issuerId, 4711) işlemi zincire yazıldığında şu bilgi ağdaki tüm devletlerin eline geçer:

"X Üniversitesi, 14 Mart 2027 saat 10:42'de, 4711 numaralı indeksteki belgeyi iptal etti."

Tek başına bu, index'in kime ait olduğunu söylemez. Ama korelasyonla daraltır:

  • Bir üniversite disiplin kararıyla diplomayı iptal ettiğinde, o kararın tarihi genelde bilinir veya kamuya açıktır.
  • Bir kurumdan ayrılan çalışanın belgesi ayrılış günü iptal edilir. İşten ayrılma tarihi ile zincirdeki damga eşleşir.
  • Toplu iptal (bir bölümün kapanması) zincirde belirgin bir küme olarak görünür.

Off-chain + sabit aralıklı yayın bunu kapatır: dışarıdan görünen tek şey "listenin yeni bir sürümü yayınlandı"dır. Hangi bit değişti, hatta bir bitin değişip değişmediği bile görünmez.

Bu, PM-TRUST-0001'in "ilişkilendirilebilir hash bile riskli" ilkesiyle aynı mantığın zaman boyutundaki uygulamasıdır.

2. Standart uyumu ​

ADR-0006 iptali Token Status List'e devretti. O standardın mimarisi zaten "belge veren bir token yayınlar, doğrulayıcı onu çeker" şeklindedir. Bitmap'i zincire koymak, standardın veri yapısını alıp taşıma modelini terk etmek olurdu — yani yarım uyum. Yarım uyum, dış cüzdanlarla ve dış doğrulayıcılarla çalışmayı bozar.

3. Maliyet ve ölçek ​

İzinli ağda gas ücretsiz olsa bile, zincir durumu (state) her validator'ın diskinde tutulur ve sonsuza kadar kalır.

Kaba büyüklük: tek bir üniversite için 100.000 indekslik liste = 12,5 KB bitmap. Türkiye'de ~200 yükseköğretim kurumu → 2,5 MB. Türk dünyası ölçeğinde binlerce belge veren × liste büyümesi → onlarca MB kalıcı durum, üstelik her iptalde bir işlem ve bir blok.

Off-chain'de aynı veri CDN'den servis edilir, sıfır zincir durumu tüketir.

4. Ölçeklenebilirlik ve tazelik dengesi ​

Off-chain liste, doğrulayıcı tarafında agresif önbelleklenebilir. On-chain okuma her seferinde RPC node'a gitmeyi gerektirir — ve doğrulama, ağın en sık yapılan işlemidir.

5. ADR-0007 ile aynı desen ​

Şema kaydı da aynı deseni kullanıyor: içerik off-chain, çapa on-chain. İki farklı desen kullanmak, hem kodu hem zihinsel modeli gereksiz yere ikiye böler. Tek desen: zincir, dış dünyadaki bir dokümanın hangi sürümünün geçerli olduğunu söyler.


Değerlendirilen Alternatifler ​

A — Bitmap tamamen zincirde (mevcut kod) — Reddedildi ​

  • Artı: Tek kaynak; doğrulayıcı ek HTTP çağrısı yapmaz; belge verenin sunucusu çökse de iptal bilgisi ayakta.
  • Eksi: İptal anı sızıntısı (§1), kalıcı durum maliyeti, standarttan sapma, RPC bağımlılığı.

Reddedildi. Tek gerçek avantajı olan "belge veren sunucusu çökerse" senaryosu, Karar 5 adım 4 + önbellekleme ile yeterince karşılanır.

B — Kriptografik akümülatör / ZK iptal — Ertelendi ​

Merkle/RSA akümülatörü veya ZK üyelik ispatı ile iptal, mahremiyet açısından en güçlü çözümdür (doğrulayıcı hangi index'i sorguladığını bile açığa vurmaz).

Reddedilmedi, ertelendi. Gerekçe: olgun kütüphane ve cüzdan desteği yok, ADR-0006'nın ES256 tabanı ile uyumu ek araştırma gerektirir, ve pilotu gereksiz yere karmaşıklaştırır. RS-REVOCATION-0001 bunu Faz 2 için değerlendirecektir.

C — Kısa ömürlü belge (iptal yok) — Kısmen benimsendi ​

İptali tamamen ortadan kaldırmanın yolu, belgeyi çok kısa ömürlü yapıp sürekli yenilemektir.

  • Öğrenci belgesi için doğru cevap budur: 30 gün TTL, iptal listesine hiç girmez.
  • Diploma için yanlıştır: diploma kalıcıdır, sürekli yenilenmesi hem belge verene yük hem de her yenilemede belge verene "bu kişi hâlâ aktif" sinyali verir (takip yüzeyi).

Benimsenen: Karma. Şema bazında TTL politikası SPEC-SCHEMA-0002'de tanımlanır; kısa ömürlü tipler iptal listesi kullanmaz.

D — Hibrit: acil iptal zincirde, normal iptal off-chain — Reddedildi ​

"Kritik iptaller anında zincire yazılsın" fikri cazip görünür ama en kötü mahremiyet sonucunu üretir: zincire yazılan iptal, tam da en hassas olan iptaldir. Sızıntıyı azaltmaz, yoğunlaştırır.


Sonuçlar ​

Bağlayıcı ​

  1. StatusListRegistry.sol yeniden yazılır (Karar 4). Mevcut bitmap mantığı kaldırılır.
  2. ITrustQueries.sol → IStatusList.isRevoked kaldırılır.
  3. CredentialGate.sol içindeki CredentialRevoked kontrolü, zincirden okuma yapamayacağı için yeniden düşünülmelidir. Zincir-üstü credential-gating (ADR-0003 Karar 4) artık iptal durumunu doğrudan göremez; iptal kontrolü çağıran tarafın sunduğu taze bir kanıta dayanmak zorundadır. Bu, ADR-0003'ün bir sonucunu daraltır ve SPEC-AGENT-0001'de ele alınacaktır.
  4. SPEC-CRED-0001 §5'teki "+ bitmap" ifadesi düzeltilir.
  5. SPEC-CRED-0003 bu kararı normatif olarak yazar: token formatı, yayın döngüsü, önbellek politikası, tazelik eşiği.
  6. status.<issuer-domain> her belge veren için işletilen bir bileşendir — ARCH-0004 envanterine ve belge veren onboarding kontrol listesine girer.

Kabul edilen ödünleşimler ​

  • Belge verene operasyon yükü. Her belge veren artık bir status sunucusu işletmek zorunda. Küçük kurumlar için Tamga barındırma hizmeti sunabilir — ama o zaman Tamga tüm iptalleri görür. Bu bir merkezîleşme noktasıdır ve PM-GOV-0001'de politika olarak ele alınmalıdır.
  • Tazelik penceresi. Sabit aralıklı yayın, en kötü durumda bir yayın aralığı kadar (1 saat) gecikme demektir. Anında iptal gerektiren senaryolar için Karar 3'ün aralığı şema bazında kısaltılabilir.
  • Ek ağ çağrısı. Doğrulayıcı doğrulamada bir HTTP isteği daha yapar. Önbellekleme ile pratikte ihmal edilebilir.

İlişkiler ​

Düzeltir: SPEC-CRED-0001 §5 (çelişki) · StatusListRegistry.solDayanır: ADR-0006 · PM-TRUST-0001Uygular: SPEC-CRED-0003 · SPEC-BC-0001 (yeniden yazım) Daraltır: ADR-0003 Karar 4 (credential-gating iptal görünürlüğü) Kardeş karar: ADR-0007 (aynı off-chain içerik + on-chain çapa deseni) Erteler: RS-REVOCATION-0001 (akümülatör/ZK, Faz 2)


Durum ​

Accepted ✅ — 2026-09-09. DECISIONS'a D-REV-1 olarak işlenecek ve D-NET/D-CRED bölümlerindeki ilgili satırlar güncellenecektir.