Dijital Kimlik Cüzdanı Prototipi: Issuer–Wallet–Verifier Mimarisi Nasıl Kuruldu?
HTTPS portalı, native iPhone cüzdanı, izole SoftHSM/ES256 servisi, kurum oturumları ve SQLite tabanlı sürümlü talep şablonlarıyla güncel prototip mimarisi.

Dijital kimlik cüzdanı fikrini anlatmanın en iyi yollarından biri, onu küçük ama uçtan uca çalışan bir sistem hâline getirmektir. Bu nedenle yalnızca bir mobil arayüz değil; belge yayıncısı, vatandaş cüzdanı ve doğrulayıcı kurum rollerini birlikte simüle eden yerel bir laboratuvar geliştirdim.
Bu üç yazılık serinin ilk bölümünde prototipin hangi problemden yola çıktığını, mimari rollerin neden ayrıldığını ve “kimliği paylaşmak” yerine “gereken özelliği kanıtlamak” yaklaşımının koda nasıl dönüştürüldüğünü anlatıyorum.

Yerel laboratuvarın genel bakış ekranı: talep et, onayla ve doğrula. İlk sürüm ekranı.
Başlangıç sorusu: Kurum gerçekten hangi bilgiye ihtiyaç duyuyor?
Yaş kontrolü yapan bir kurumun çoğu zaman adımıza, doğum tarihimize ve kimlik numaramıza ihtiyacı yoktur. Kurumun karar verebilmesi için “18 yaşından büyük” sonucunun güvenilir bir kaynak tarafından doğrulanması yeterlidir.
Benzer biçimde bir belediye yalnızca ikamet edilen il ve ilçeyi, teslimat şirketi yalnızca o işlem için adresi, sosyal destek birimi ise yetkisi varsa belirli hane bilgilerini isteyebilir. Bu yaklaşımın temel ilkesi şudur:
Kimlik kartının dijital kopyasını göndermek yerine, işlem için gereken en küçük doğrulanabilir veri kümesini sun.
Avrupa Komisyonu da seçici açıklamayı, cüzdan kullanıcısının ek bilgi açığa çıkarmadan yalnızca istenen özellikleri paylaşmasını sağlayan bir veri minimizasyonu özelliği olarak tanımlıyor. Bu nedenle prototipin veri modeli “tam kimlik kaydı” etrafında değil, senaryoya göre yetkilendirilmiş alanlar etrafında kuruldu.
Üç rol, üç ayrı sorumluluk
1. Issuer — belge yayıncısı
Issuer, sentetik kaynağın alanlarını imzalı belgeye dönüştürür. Canlı dağıtımda belge imzası SoftHSM içindeki P-256 anahtarıyla ES256 olarak üretilir; belgeyi ve paylaşım sonucunu API açık anahtarla doğrular. Cihazın onay imzası bu ihraççı imzasından ayrıdır.

Belge yayıncısı ekranı. Kayıtlar sentetiktir; açık anahtar doğrulayıcılar tarafından kullanılabilir. İlk sürüm ekranı.
İlk sürümün yerel Ed25519 imzalama örneği aşağıdadır. Canlı sürümde son satır yerine izole SoftHSM servisine giden await issuer.sign(data, "credential") çağrısı kullanılır:
const payload = {
issuer: "Yerel Demo Nüfus Kurumu",
subject: person,
age_over_18: age >= 18,
issued_at: Date.now(),
expires_at: Date.now() + 3600000,
id: randomUUID()
};
const data = base64url(JSON.stringify(payload));
const signature = Ed25519.sign(data, issuerPrivateKey);
Belgenin iptal edilmesi, yeniden yayınlanması ve süresinin dolması da akışın parçasıdır. Böylece sadece “imza doğru mu?” değil, “belge hâlâ kullanılabilir mi?” sorusu da ele alınır.
2. Holder ve wallet — vatandaşın cüzdanı
Wallet, imzalı belgenin vatandaşa ait kullanım yüzüdür. Talep eden kurumu, işlem amacını ve istenen alanları gösterir; kullanıcı alanları tek tek seçebilir, paylaşımı reddedebilir ve daha sonra işlem makbuzunu görebilir.

SwiftUI cüzdanın ana ekranı. Belge, eşleştirme, gelen talepler ve hareketler aynı kullanıcı deneyiminde birleştirildi. İlk sürüm ekranı.
Native iOS uygulaması SwiftUI ile geliştirildi. QR okuma için VisionKit, paylaşım öncesi cihaz sahibi doğrulaması için LocalAuthentication, yerel görüntüleme önbelleği için Keychain ve cihaz anahtarı için Security framework kullanılıyor.
Cüzdanın görevi yalnızca veri göstermek değildir. Kullanıcıya şu soruların anlaşılır cevabını vermelidir:
- Talebi hangi kurum gönderdi?
- İşlemin amacı nedir?
- Hangi alanlar isteniyor?
- Hangi alanlar gerçekten paylaşılacak?
- Talep ne zaman sona erecek?
- Paylaşımı reddedersem ne olacak?
3. Verifier — doğrulayıcı kurum
Verifier, belirli bir işlem için kanıt isteyen taraftır. Hazır demo kurumlarının yanında uygulamadan oluşturulan kurumlar da vardır. Kurumun hesabı, alan yetkileri ve onaylı şablonu API’de kontrol edilir; teslimat kurumu aile üyelerini, market açık adresi kendi kararıyla isteyemez.
const scenarios = {
age: {
claims: ["age_over_18"],
merchants: ["shop", "library"]
},
residence: {
claims: ["city", "district"],
merchants: ["municipality"]
},
address: {
claims: ["city", "district", "street_address", "postal_code"],
merchants: ["delivery"]
}
};
Bu kontrolün yalnızca arayüzde yapılması yeterli değildir. Sunucu da kurum-senaryo eşleşmesini ve kullanıcının seçtiği alanların talep kapsamı içinde kalıp kalmadığını doğrular. Böylece değiştirilmiş bir istemcinin izin verilmeyen alan eklemesi kabul edilmez.
Neden tek bir “kimlik sunucusu” yerine üç rol?
Rolleri ayırmak güven sınırlarını görünür kılar. Issuer doğru veriyi yayınlamaktan, wallet kullanıcının kararını ve anahtarını korumaktan, verifier ise ihtiyacını sınırlı ve anlaşılır biçimde ifade etmekten sorumludur.
W3C Verifiable Credentials Data Model 2.0 da ekosistemi issuer, holder ve verifier rollerinden oluşan üç taraflı yapı üzerinden tarif eder. Prototip bu standardın tam uygulaması değildir; ancak rol ayrımı ve imzalı claim yaklaşımı standarda geçiş için doğru zihinsel modeli sağlar.
Veri modeli: Belge ile sunum aynı şey değildir
Issuer’ın cüzdana verdiği belge daha geniş bir veri kümesine sahip olabilir. Fakat verifier’a gönderilen sunum yalnızca seçilmiş alanları içermelidir. Demoda sunum üretimi sırasında önce belgenin imzası ve süresi kontrol ediliyor, ardından yalnızca izinli ve seçilmiş alanlar yeni bir kanıta ekleniyor:
const selected = requestedClaims.filter(isSelectedByUser);
const disclosed = Object.fromEntries(
selected.map(key => [key, credential[key]])
);
const proof = {
issuer: credential.issuer,
audience: verifierId,
nonce: request.nonce,
request_id: request.id,
...disclosed,
expires_at: request.expiresAt,
pairwise_id: pairwiseIdentifier(person, verifierId)
};
Buradaki önemli ayrım şudur: Demo, teknik olarak SD-JWT veya sıfır bilgi ispatı üretmiyor. Yayıncı servis belgeyi doğrulayıp seçilmiş alanlardan yeni ve kısa ömürlü bir sunum imzalıyor. Bu, veri minimizasyonu fikrini gösteren anlaşılır bir prototip; yayıncının her sunumu gördüğü çevrimiçi bir modeldir.
Kuruma özel tanımlayıcı neden kullanıldı?
Kurumların aynı kişiyi sonraki işlemlerde tanıması gerekebilir. Fakat her kuruma aynı sabit kimlik numarasını vermek, kurumlar arası profil birleştirmeyi kolaylaştırır. Bu nedenle prototip her kişi-kurum çifti için farklı bir pairwise_id üretir:
pairwise_id = HMAC(
walletSecret,
personId + ":" + verifierId
).slice(0, 24)
Aynı kişi markette ve kütüphanede farklı tanımlayıcılarla görünür. Bu mekanizma tek başına tam anonimlik sağlamaz; ancak ortak ve değişmez bir vatandaş numarasının her işlemde dolaşmasını önleyen önemli bir tasarım aracıdır.
İlk geliştirme aşamasından çıkan sonuç
Prototipin ilk aşaması gösterdi ki dijital cüzdan tasarımı, mobil ekrana kart koymaktan çok daha fazlasıdır. Asıl çalışma; rol sınırlarını, talep politikalarını, alan seviyesinde yetkiyi, belge yaşam döngüsünü ve kullanıcıya gösterilecek karar bağlamını tanımlamaktır.
Serinin ikinci bölümünde iki ayrı QR’ın neden kullanıldığını, tek kullanımlık cüzdan eşleştirmesini, talebe bağlı nonce değerini, Secure Enclave cihaz imzasını ve paylaşım sonucunun kuruma nasıl ulaştığını adım adım inceleyeceğiz.
Güncel mimari: API’den ayrılan SoftHSM imzalama alanı
Canlı demo HTTPS portalı ve native iPhone cüzdanıyla çalışıyor. Belge ve paylaşım sonucu imzaları artık ana API sürecinde oluşturulan Ed25519 anahtarıyla değil, ayrı servisteki SoftHSM P-256 anahtarıyla ES256 olarak üretiliyor. Ed25519 yalnızca yerel geliştirme seçeneği olarak korunuyor; canlı signer kesilirse bu seçeneğe otomatik dönüş yok.

Güvenlik akışı: kurum oturumu, cihaz imzası, izole SoftHSM ve merkezi API doğrulaması.
- Kullanıcı onayını talebe bağlama — Nerede?: Gerçek iPhone / Secure Enclave; Hangi anahtarla?: Cihazın özel P-256 anahtarı
- Cihaz imzasını doğrulama — Nerede?: Merkezi API; Hangi anahtarla?: Kayıtlı cihazın açık anahtarı
- Belge ve sonuç imzalama — Nerede?: İzole servis / SoftHSM; Hangi anahtarla?: İhraççının P-256 özel anahtarı
- İhraççı imzasını doğrulama — Nerede?: Merkezi API; Hangi anahtarla?: İhraççının açık anahtarı
İmzalama servisi internete port açmıyor; yalnızca özel Docker ağından kimliği doğrulanmış çağrı kabul ediyor. SoftHSM anahtarı CKA_SENSITIVE=true ve CKA_EXTRACTABLE=false özellikleriyle oluşturuluyor. Token seçimi kalıcı seri numarasına bağlı; yeniden başlatmada aynı anahtar korunuyor. PIN ve SO PIN ana API’ye verilmez; API yalnızca imzalama çağrısı için ayrı servis sırrını kullanır.
Bu ayrım donanımsal HSM veya bağımsız kurum doğrulayıcısı kurulduğu anlamına gelmez. SoftHSM yazılımdır ve host yöneticisine karşı fiziksel anahtar koruması sunmaz. İmza doğrulama ve issuer/verifier iş mantığı hâlâ merkezi API’dedir. Ayrıca kullanılan JSON sözleşmesi, ES256 imzası taşısa da kendiliğinden standart bir JWS veya VC formatına dönüşmez.
Sabit senaryolardan kurum ve şablon yönetimine
“Kurum ve şablonlar” menüsüyle yeni kurum ve ayrı hesabı oluşturulabiliyor. Kurum türüne göre alan yetkileri yönetici tarafından onaylanıyor. İşlem adı, amaç, seçili alanlar, alan gerekçeleri ve zorunluluklar içeren her şablon sürümü ayrıca inceleniyor. En son onaylı sürüm senaryo kataloğuna ekleniyor.
Kurumlar, hesapların scrypt parola özetleri, alan yetkileri ve şablon sürümleri SQLite’ta kalıcıdır. Talepler, cihaz kayıtları, oturumlar ve paylaşım makbuzları ise bu sürümde bellektedir. İhraççı token dosyaları ayrı kalıcı volume’de tutulur. Kuruma özel tanımlayıcı üreten HMAC sırrı da kalıcıdır; bu sır SoftHSM’ye taşınmış değildir.
Belge süresi ve demo yenilemesi
Sentetik belgeler bir saat geçerlidir. Süresi dolmuş fakat imzası geçerli ve iptal edilmemiş bir demo belgesi, durum okuma veya paylaşım sırasında yeniden yayınlanıp imzalanır; süresi geçmiş belge olduğu gibi kabul edilmez. Bu, gerçek vatandaş kaydı için otomatik yenileme yetkisi veren bir politika değildir.
Erişim yetkisi olan kullanıcılar Mimari menüsünde numaralı kullanım akışını ve renkli güvenlik şemasını inceleyebilir.
Kaynaklar
Standartlar ve birincil kaynaklar
Üretim sistemlerinde güncel sürümleri ve kurumunuzun onaylı politikalarını esas alın.
Bu makaleyi nasıl değerlendirirsin?
Geri bildirimin sonraki içerikleri geliştirmeme yardımcı olur.