Bir pasaport fotoğrafı, çoğu uygulamanın alacağı en hassas dosyadır. Üzerinde bir yüz, tam ad, doğum tarihi ve belge numarası bulunur ve başka bir yerde hesap açmaya yeter. Yine de birçok yükleme akışında bu görüntü, biri onun var olması gerekip gerekmediğini sormadan önce beş altı kez kopyalanır.

Bu yazı konuya mühendislik tarafından bakıyor. GDPR'ın veri saklama hakkında söylediklerini aktarıyor, bir pasaport görüntüsünün sessizce biriktiği yerleri tek tek geziyor ve oku, döndür, unut adını verdiğimiz bir kalıbı anlatıyor: görüntü okunur, sonuç döndürülür ve resimden hiçbir şey saklanmaz. Son bölüm sizin işiniz olarak kalan kısma ayrılmış, çünkü bazı işletmelerin bir kopya saklaması zorunludur ve AB bunu Temmuz 2027'den itibaren yeni bir yasayla açıkça yazıyor.

Bu, kimlik belgelerini okuyup sonucu JSON olarak döndüren bir pasaport ve kimlik OCR API'si olan doc.cheap'in blogudur. Ürünle ilgili kısımları bunu göz önünde tutarak okuyun.

GDPR gerçekte ne istiyor

GDPR "bir pasaport görüntüsünü asla saklamayın" demez. Daha işe yarar bir şey söyler: ihtiyacınız olanı, ihtiyacınız olduğu süre boyunca tutun, daha uzun değil. Reg. (EU) 2016/679 Art. 5(1) ilkeleri belirler. Bunlardan ikisi tasarımın büyük kısmını belirler.

İlke Art. 5(1) metni (İngilizce sürüm) Bir görüntü için anlamı
Veri minimizasyonu, bent (c) "adequate, relevant and limited to what is necessary in relation to the purposes for which they are processed" Süreciniz ad, doğum tarihi ve belge numarasına ihtiyaç duyuyorsa, bunlar okunduktan sonra resmin kendisi gerekli olmayabilir.
Saklama sınırlaması, bent (e) "kept in a form which permits identification of data subjects for no longer than is necessary for the purposes for which the personal data are processed" Her kopyanın bir bitiş tarihi olmalı ve "silmeye bir türlü fırsat bulamadık" bir bitiş tarihi değildir.

Art. 5(2) hesap verebilirliği ekler: bu ilkelere uyduğunuzu gösterebilmeniz gerekir. Art. 25(1), yani tasarımda veri koruma, "appropriate technical and organisational measures, such as pseudonymisation, which are designed to implement data-protection principles, such as data minimisation, in an effective manner" ister; başka bir deyişle, veri minimizasyonu gibi ilkeleri etkili biçimde uygulamak için tasarlanmış, takma adlandırma gibi uygun teknik ve organizasyonel önlemler.

Birlikte okunduklarında hukuki bir soruyu mühendislik sorusuna çevirirler. Bir görüntünün ne kadar az kopyası varsa, tanımlamanız, korumanız, yedeklemeniz ve sonunda boşaltmanız gereken o kadar az yer olur. Hiç yazılmamış bir kopya, bu işlerin hiçbirini gerektirmeyen tek kopyadır.

Pasaport görüntüleri nereye gider

Çoğu ekip görüntüyü bilerek tek bir yerde saklar. Sorun, kimsenin seçmediği yerlerdir. İşte kendi akışınızla karşılaştırmanız için bir liste.

Yer Görüntü oraya nasıl ulaşır
Yükleme bucket'ı İstemci önce nesne depolamaya yükler, backend dosyayı oradan okur. Nesne, istekten daha uzun yaşar.
İstek logları Bir loglama middleware'i istek gövdelerini yazar ve base64 bir görüntü de bir istek gövdesidir.
Hata raporları Bir istisna izleyicisi, başarısız olan isteğin payload'ını rapora ekler.
Kuyruklar ve yeniden denemeler Bir iş mesajı görüntüyü taşır ve bir dead-letter kuyruğu başarısız olanları haftalarca tutar.
Yedekler ve anlık görüntüler O gün alınan bir veritabanı ya da disk anlık görüntüsü, satır silindikten çok sonra bile kendisinden önce yazılmış her görüntüyü içerir.
Destek talepleri Bir kullanıcı fotoğrafı "yükleme çalışmadığı için" e-postayla yeniden gönderir.
Analitik ve oturum kaydı Bir araç sayfayı, seçilen dosyanın önizlemesiyle birlikte kaydeder.
OCR sağlayıcısı Belgeyi okuyan servis, kendi saklama kurallarına göre kendi kopyasını tutar.

Son satır, en az kontrol ettiğiniz satırdır. Kendi loglarınızı düzeltebilirsiniz. Bir tedarikçinin tuttuğu kopya ise o tedarikçinin ayarlarına bağlıdır ve bu ayarların ne olduğunu sormanız gerekir.

Kalıp: oku, döndür, unut

Kalıbı ifade etmek basittir. Görüntü yalnızca bellekte, tek bir istek süresince var olur. İstekten çıkan şey okumanın kendisidir: çıkarılan değerler. Resim hiç dışarı çıkmaz.

  1. Görüntüyü doğrudan tanımaya gönderin. Arada yükleme bucket'ı olmasın. Büyük dosyalar için bir bucket kaçınılmazsa nesneye birkaç dakikalık bir ömür verin ve çağrı döndüğünde silin.
  2. Yanıttan ihtiyacınız olanı hemen kullanın. Belge sahibinin fotoğrafı gibi kırpmalar yalnızca o yanıtta bulunur. Akışınız bir selfie'yi portreyle karşılaştırıyorsa bunu şimdi yapın.
  3. Resmi değil, okumayı saklayın. Sürecinizin ihtiyaç duyduğu alanları kendi saklama kuralınıza göre kaydedin. Doğum tarihi ve belge numarası yine de kişisel veridir, bu yüzden onların da bir bitiş tarihi olur.
  4. Görüntüyü loglardan ve hata raporlarından uzak tutun. Gövdeleri sınırda, tek bir yerde temizleyin; her çağıranın bunu hatırlayacağına güvenmeyin.
  5. Sonucu yazıya geçirin. Yukarıdaki tablodaki her yer için görüntünün oraya ulaşıp ulaşamayacağını ve neden ulaşamadığını not edin. Bu not, Art. 5(2)'nin istediği hesap verebilirliktir.

API'miz görüntüyle ne yapıyor

doc.cheap'in aynı soruyu nasıl ele aldığı, veri saklama ve gizlilik sayfasında anlatıldığı şekliyle şöyle.

  • Görüntü asla saklanmaz. İstek süresince bellekte yaşar, tanıma motoruna verilir ve yanıt yazıldığında yok olur. Hiçbir disk, nesne deposu ya da log onu almaz.
  • Kırpmalar da saklanmaz. Belge kırpması, belge sahibinin fotoğrafı ve imza, onları üreten çağrının yanıtında döner. Daha sonra GET /v1/scans/{id} ile geri okunan bir taramada her görüntü alanı null olur.
  • Saklanabilen şey okumadır, ve yalnızca istediğiniz süre boyunca. retain_hours seçeneği bunu her istek için 0'dan 8760 saate (bir yıl) kadar belirler. Açıkça verilen bir değer her zaman hesap ayarının önüne geçer.
  • retain_hours: 0 hiçbir şey yazmaz. Hemen süresi dolan bir satır değil: hiç satır yok. Temizlenecek bir şey, yedekte bir şey ve dışa aktarılacak bir şey yoktur. Tarama yine de bir tarama olarak sayılır.
  • Gerisini hesabın varsayılan ayarı kapsar. Bir istek süre belirtmediğinde hesabın kendi geçmiş ayarı geçerlidir: 24 saat, 7 gün, 1 ay ya da 1 yıl. Yeni hesaplar 1 yılla başlar, böylece panel bir geçmiş gösterir. Ayarı kısaltmak zaten kayıtlı satırlara da uygulanır; her biri kendi oluşturulma zamanından itibaren ölçülür.
  • Saklanan bir satır tek bir küçük resim tutar: en uzun kenarı en fazla 96 px ve boyutu en fazla 16 KiB olan bir küçük resim; satır tanınabilsin diye panelin işlem kaydında gösterilir. API üzerinden okunamaz. Küçük resim, satırla birlikte gider.
  • Tek bir tarama erken silinebilir. Bir live anahtar DELETE /v1/scans/{id} gönderir; bu, sonucu, geçmiş satırını ve küçük resmi kaldırır. Bu işlem kesindir.

Geçmiş saklamayı kontrol etme kılavuzu ayarları adım adım anlatır, verileri nasıl işlediğimiz sayfamız da özetini verir.

İşte Python'da requests ile sıfır saklamalı bir çağrı. Herkese açık sandbox anahtarı sk_sandbox_public dokümantasyonda yazılıdır ve kayıt gerektirmez: adres başına toplam 10 ücretsiz tanınmış belge ve saatte en fazla 10 istek sağlar. Sıfır saklama kendi hesabınızın bir ayarıdır, bu yüzden canlı (live) anahtarınızı gerektirir. Herkese açık sandbox bir hesap değildir: her taramanın kaydını küçük resmiyle birlikte hizmetin kendi günlüğünde tutar, bu yüzden ona gerçek bir belge değil, yalnızca bir test görüntüsü gönderin.

import base64
import uuid

import requests

API = "https://api.doc.cheap/v1/scans"
KEY = "sk_sandbox_public"  # üretimde kendi live anahtarınız


def read_and_forget(path):
    with open(path, "rb") as f:
        image = base64.b64encode(f.read()).decode("ascii")
    response = requests.post(
        API,
        headers={
            "Authorization": f"Bearer {KEY}",
            "Idempotency-Key": str(uuid.uuid4()),
        },
        json={
            "image": image,
            # 0: canlı anahtarla, API tarafında bu taramayla ilgili hiçbir şey yazılmaz.
            # False: portre kırpması yok, çünkü bu akış onu kullanmıyor.
            "options": {"retain_hours": 0, "return_portrait": False},
        },
        timeout=30,
    )
    response.raise_for_status()
    scan = response.json()
    del image  # yerel kopya, çağrı döner dönmez gider
    if scan["meta"]["status"] != "recognized":
        return None
    # Sürecinizin ihtiyaç duyduğu okumayı kendi saklama kuralınıza göre tutun.
    return {
        "scan_id": scan["meta"]["id"],
        "document_number": scan["document"]["number"],
        "expiry_date": scan["document"]["expiry_date"],
        "birth_date": scan["holder"]["birth_date"],
        "mrz_status": scan["mrz"]["status"],
    }

Sıfır saklamanın, sizi şaşırtmadan önce bilmeye değer bir bedeli var. Bir Idempotency-Key normalde bir yeniden denemenin ilk sonucu döndürmesini sağlar. retain_hours: 0 ile döndürülecek kayıtlı bir sonuç yoktur; bu yüzden 24 saat boyunca aynı anahtarla yapılan bir yeniden deneme, ikinci kez yanıtlanmak yerine HTTP 409 ve idempotency_replay_unavailable koduyla reddedilir. Bu yanıtı "ilk çağrı başarılı oldu" olarak değerlendirin ve elinizdeki sonucu kullanın.

Taramayı geri okumak tasarımın öbür yüzünü gösterir. Bir sandbox anahtarı, id ne olursa olsun hiçbir şeyi geri okumaz. Bu isteği 5 Ekim 2026'da sk_sandbox_public ile gönderdik:

curl https://api.doc.cheap/v1/scans/<SCAN_ID> \
  -H "Authorization: Bearer sk_sandbox_public"

HTTP 404 ile döndü (mesaj kısaltıldı):

{
  "error": {
    "code": "not_found",
    "message": "No scan with id …",
    "docs_url": "https://doc.cheap/docs/errors/not_found"
  }
}

Bir live anahtar da retain_hours: 0 ile yapılan bir tarama için ve süresi geçmiş her tarama için aynı 404'ü alır. Servisleri bu açıdan karşılaştırıyorsanız pasaport OCR API karşılaştırması başlamak için iyi bir yer; her birine yalnızca ne döndürdüğünü değil, görüntünün nereye gittiğini de sorun.

Sizin işiniz olarak kalan

Oku, döndür, unut API tarafındaki kopyaları ortadan kaldırır. İşletmenizin neyi saklaması gerektiğine ise karar vermez. Bazı işletmeler için cevap "bir kopya"dır ve bunu yasa söyler.

AB'nin yeni kara para aklamayla mücadele yasası Reg. (EU) 2024/1624, 10 Temmuz 2027'den itibaren uygulanır. Art. 90 şöyle der: "It shall apply from 10 July 2027, except in relation to obliged entities referred to in Article 3, points (3)(n) and (o), to which it shall apply from 10 July 2029." Yani 10 Temmuz 2027'den itibaren uygulanır; Art. 3'ün (3)(n) ve (o) bentlerinde sayılan yükümlü kuruluşlar için ise 10 Temmuz 2029'dan itibaren. Kayıt saklamaya ilişkin Art. 77, bankalar ve diğer finans şirketleri gibi yükümlü kuruluşların şunu saklamasını zorunlu kılar:

"a copy of the documents and information obtained in the performance of customer due diligence pursuant to Chapter III, including information obtained through electronic identification means;"

Başka bir deyişle, müşteri durum tespiti sırasında elde edilen belgelerin ve bilgilerin, elektronik kimlik tanımlama araçlarıyla elde edilenler dahil, bir kopyası.

Art. 77(3) süreyi belirler: kayıtlar "retained for a period of 5 years commencing on the date of the termination of the business relationship", yani iş ilişkisinin sona erdiği tarihten itibaren 5 yıl saklanır, ardından "obliged entities shall delete personal data upon expiry of the five-year period", yani beş yıllık süre dolunca kişisel veriler silinir. Art. 77(2), belirli koşullar altında kopyalar yerine "a retention of the references to such information", yani bu bilgilere yapılan atıfların saklanmasına izin verir.

Dolayısıyla yükümlü bir kuruluşsanız, API'deki sıfır saklama kayıt tutma yükümlülüğünüzü ortadan kaldırmaz. Kaydın nerede durduğunu değiştirir. Kendi deponuz tek kopya olur ve yukarıdaki saklama sınırlaması ilkesi ona da uygulanır: ilişki bittikten beş yıl sonra gider. Tasarım işi, o depoyu bilinçli bir seçim hâline getirmektir: tek bir yer, tek bir sorumlu, şifreleme, erişim kontrolü ve bir silme işi; yukarıdaki tablodaki tesadüfi yığın değil.

Yükümlü bir kuruluş değilseniz önce basit soruyu sorun: alanlar okunduktan sonra sürecinizdeki herhangi bir şeyin resme ihtiyacı var mı? Dürüst cevap çoğu zaman hayırdır.

Kontrol listesi

  • "Görüntüler nereye gider" tablosundaki her yer kendi akışınızla karşılaştırıldı.
  • Görüntü doğrudan tanımaya gider ya da birkaç dakikalık ömrü olan bir bucket'tan geçer.
  • Kırpmalar yanıt işleyicisinin içinde kullanılır ve hiçbir yere yazılmaz.
  • OCR çağrısı saklama süresini bilerek belirler; geri okunacak bir şey yoksa retain_hours: 0.
  • Yeniden denemeler 409 idempotency_replay_unavailable yanıtını ele alır.
  • Loglar ve hata raporları istek gövdelerini tek bir sınırda temizler.
  • Sakladığınız alanların bir bitiş tarihi var ve onları silen bir şey var.
  • Bir yasa kopya gerektiriyorsa, bu kopya kendi silme tarihi olan tek ve bilinçli bir depoda durur.

Bu bir mühendislik özetidir, hukuki tavsiye değildir. Bu yazının atladığı, bir görüntünün sızabileceği bir yer bulursanız admin@doc.cheap adresine yazın.

Size bir soru: kimsenin saklamak istemediği bir kimlik belgesi kopyasını en son nerede buldunuz? Aşağıdaki yorumlarda anlatın.