Sunucuda belge doğrulama
Bu rehber, Tamga belgelerini (credential)Belge verenin imzaladığı ve kişinin cüzdanında duran dijital belge; kişi yalnız istenen alanları gösterir. barındırılan doğrulayıcıya (verifier)Gösterilen belgeyi denetleyen taraf: imza, belge verenin güven listesindeki kaydı, durum ve politika. Relying party diye de anılır. gitmeden kendi sunucunuzda doğrulamak isteyen geliştiriciler içindir: işe alım, kampüs girişi, yaş kontrolü, bilet kapısı.
Ne zaman okunur: belge değerlerinin hiçbir aracıya uğramamasını istediğinizde ya da doğrulamayı kendi altyapınızda yönetmek istediğinizde. Daha hızlı bir başlangıç için barındırılan doğrulayıcı: GUIDE-0001. Çalışan kod: GUIDE-0004 §2.
Nasıl çalışır?
- Sunucunuz ne istediğini bir politika ile tanımlar (ör. "diploma: ad, bölüm, mezuniyet yılı") ve imzalı bir istek üretir. İstek QR ya da bağlantı olarak gösterilir; içinde kişisel veri yoktur.
- Kişi cüzdanında isteği görür, onaylar; cüzdan cevabı şifreli olarak sunucunuza gönderir.
- Sunucunuz cevabı çözer ve doğrulama hattını çalıştırır: imza, güven listesi (trust list)Bir ülkenin kök sertifikalarını, belge verenlerini ve kayıtlı relying party'lerini taşıyan imzalı liste. Bugün Tamga'da güven bu listelere dayanır; ortak defter sonra gelir., 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. durumu, süre, holder bindingBelgeyi yalnız belge sahibinin cihazındaki bir anahtara bağlamak; kopyalanan belge gösterilemez. ve politika.
- Sonuç üç değerden biridir: kabul, ret ya da "şu an doğrulanamadı".
@tamga-network/verifier bu hattın tamamını uygular (SPEC-API-0001, adımlar T0 + A–E). Referans doğrulayıcı apps/verify (verify.tamga.network) aynı kütüphaneyi kullanır; aşağıdaki adımların tamamı orada çalışır hâlde.
Hazırlık
- Doğrulayıcı kaydı. Tamga güven listesinde bir doğrulayıcı kaydınız olur: kalıcı kimliğiniz alan adınızdır (
dns_name), istemci kimliğiniz x509_hash:…HAIP'teki client kimliği biçimi: kimlik, relying party'nin erişim sertifikasının base64url SHA-256 özetidir. biçimindedir (liste yayıncısı bunu erişim sertifikanızdan (access certificate)Relying party'nin isteklerini imzaladığı X.509 sertifikası; client kimliği bu sertifikanın özetinden türetilir. hesaplar), ayrıca X.509 sertifikanız ve isteyebileceğiniz alanların kapsamı kayıtlıdır. İsteğiniz bu kapsamı aşarsa cüzdan reddeder. - Güven kaynağı.
@tamga-network/trustile güven listelerini yükleyin:loadTrustSourceFromDir(dist)ya da düzenli indirme + yeniden yükleme (guardedReload). Güvenle ilgili her soruyu yalnızcaTrustSource'a sorun. - İptal listelerini önceden çekin.
new PrefetchStatusCache()+ düzenlirefresh(uriler). Doğrulama anında ağa çıkılmaz.
Akış
import { dcqlFromPolicy, createPresentationRequest, decryptResponse, verifyPresentation, pemRpSigner,
PrefetchStatusCache, type Policy } from "@tamga-network/verifier";
const policy: Policy = { policy_id: "ise-alim", /* credentials, trust, freshness */ } as Policy;
const signer = await pemRpSigner(RP_KEY_PEM, RP_CERT_PEM); // client_id = x509_hash (sertifikadan)
// 1) istek: QR / derin bağlantı olarak gösterilir (kişisel veri yok; yalnızca request_uri)
const req = await createPresentationRequest({ signer, dcql: dcqlFromPolicy(policy),
responseUri: "https://ornek.com.tr/vp/response", requestUriBase: "https://ornek.com.tr/vp/req" });
// 2) cüzdan şifreli yanıtı response_uri'ye POST eder → çöz
const resp = await decryptResponse(jweBody, req.encPrivateKey); // istekle üretilen anahtar; req.state ile eşleştirin
// 3) doğrula (SD-JWT; mdoc için format: "mso_mdoc" + responseUri)
const { result, claims } = await verifyPresentation({ presentation: resp.vp_token["diploma"][0], aud: signer.clientId, nonce: req.nonce,
policy, policyCredentialId: "diploma", trust, statusCache, rootCertsDer, rp: trust.relyingParty(signer.clientId) });Alan adları ve imzalar paket tiplerinde tanımlıdır; tam çalışan örnek apps/verify/src/routes/presentations.ts.
İstemci kimliği x509_hash biçimindedir (HAIP 1.0 §5); pemRpSigner(anahtar, sertifika) onu sertifikadan hesaplar (ADR-0034). Sertifikayı yenilerken önce yeni sertifika güven listesine girer, sonra sunucunuz yenisine geçer.
Sonucu yorumlama
outcome | Anlamı | Kullanıcıya |
|---|---|---|
ACCEPTED | tüm adımlar geçti | yalnızca claims içindeki onaylanan alanları kullanın |
REJECTED | belge geçersiz (imza, iptal, süre, bağ, politika) — failed_step hangi adımda takıldığını söyler | "Belge kabul edilmedi" |
INDETERMINATE | altyapı ya da tazelik sorunu (ör. D2/D4/D5 adımlarında STATUS_STALE) — belge kötü değil | "Şu an doğrulanamadı, tekrar deneyin" |
checks_performed / checks_skipped denetim için saklanabilir; kişisel veri saklamayın. Saat kayması toleransı policy.freshness.max_clock_skew_sec ile ayarlanır (varsayılan 120 sn).
Kontrol listesi
- NonceBir kez kullanılan rastgele değer; doğrulayıcı gönderir, cüzdan imzalar, böylece eski bir gösterme yeniden kullanılamaz. tek kullanımlıktır; aynı yanıt ikinci kez işlenmez.
- Politika yalnızca gereken alanı ister; yaş için mdocISO/IEC 18013-5 mobil belge biçimi, CBOR ile kodlanır; yüz yüze gösterme ve mobil ehliyet için kullanılır.
age_over_18gibi tek bir alan yeterlidir. - İ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. ön çekimi ve güven listesi yenilemesi çalışıyor olmalı. Çalışmıyorsa sonuçlar
INDETERMINATEolur — bu doğru davranıştır.
Derinlik: sıfır bilgi ispatıyla yaş doğrulama (mso_mdoc_zk)
"18 yaşından büyük mü?" sorusunu belgeyi, doğum tarihini, kurum imzasını ve cihaz anahtarını görmeden sorabilirsiniz (ADR-0032). Cüzdan Longfellow ZKmdoc belgeleri için açık bir sıfır bilgi ispatı sistemi; Tamga doğum tarihini göstermeden "18 yaşından büyük" gibi bilgileri kanıtlamak için kullanır. ile bir ispat üretir; siz yalnızca "kayıtlı bir kurumun kimlik belgesinde age_over_18 = true" bilgisini öğrenirsiniz. Aynı kişinin iki gösterimi birbirine bağlanamaz.
const policy: Policy = {
policy_id: "age-over-18-zk",
purpose: { "en-US": "Over-18 check — yes/no only" },
credentials: [{
id: "identity", vct_values: ["urn:tamga:id:IdentityAttestation:1"],
format: "mso_mdoc_zk", namespace: "tamga.id.1",
required_claims: ["age_over_18"], constraints: { age_over_18: true }, // yalnız eşitlik
}],
trust: { ... }, freshness: { ... },
};
// İstek: kabul edilen devreler imzalı listeden (ZK2)
const dcql = dcqlFromPolicy(policy, { zkCircuits: trust.zkCircuits?.() ?? [] });
// Yanıt: vp_token.identity[0] = base64url(DeviceResponse{ zkDocuments })
const { result } = await verifyPresentation({ presentation, format: "mso_mdoc_zk", responseUri, aud, nonce,
policy, policyCredentialId: "identity", trust, statusCache, rootCertsDer });- Doğrulama paketle gelen WebAssembly ile çalışır; Rust ya da yerel derleme gerekmez. Bir doğrulama masaüstünde ~3 sn sürer.
- Çok yüksek hacim için yerel arka uç:
packages/verifier/zkkaynağındancargo build --release --locked --features native --bin tamga-zk-verify(Rust 1.98.1, Linux/macOS), sonranew NativeZkBackend({ binPath })ya da ortamdanzkBackendFromEnv()(TAMGA_ZK_NATIVE_BIN) →VerifyInput.zk. Doğrulama ~0,2–0,3 sn sürer; ikili yanıt vermezse WASM'a düşer. - Yeni adım
Z1: devre imzalı listede mi, yalnızca istenen öğe mi açıklandı, zaman damgası taze mi, ispat geçerli mi? Kurum imzası, cihaz imzası ve geçerlilik ispatın içinde denetlenir (checks_skipped: A4–A7). İptal durumu gelmez (status: NOT_APPLICABLE); ZK ile sunulan belgeler kısa ömürlüdür. - Yedek yol: cüzdan ZK desteklemiyorsa sorgunuz eşleşmez; aynı soruyu klasik
mso_mdocpolitikasıyla (age-over-18-mdoc) sorun. Tamga Wallet'ta ZK üretimi telefon sürümüyle gelir (Aşama 2).
Kurallar
| Kod | Ne der |
|---|---|
| SPEC-API-0001 AP2 | INDETERMINATE, REJECTED ile aynı kovaya konmaz |
| SPEC-API-0001 AP3–AP4 | sonuç ve kayıtlar alan değerlerini ve iptal indeksini taşımaz |
| SPEC-API-0001 AP6 | istek, doğrulayıcı kaydının kapsamını aşamaz |
| Tek güven arayüzü | güven verisi yalnızca TrustSource üzerinden okunur |
| SPEC-CRED-0003 S12 | doğrulama başına iptal listesi çekilmez; toplu ön çekim kullanılır |
| SPEC-PROTO-0002 PV10 | nonce tek kullanımlıktır |
| ADR-0032 ZK2, ZK5 | yalnızca imzalı listedeki devreler kabul edilir; ZK yoksa klasik yol |