Işıklar Asistan
Desktop software that does a driving school's office work and shows the owner what is being missed. The data stays on the school's own computer. It runs today at Işıklar Sürücü Kursu in Biga. The goal is to make it installable at more schools by the end of November 2026.
Sürücü kursunun büro işini üstlenen, kurs sahibine gözden kaçanı gösteren masaüstü programı. Veri kursun kendi bilgisayarında durur. Bugün Biga'da Işıklar Sürücü Kursu'nda çalışıyor. Hedef, Kasım 2026 sonunda başka kurslara da kurulabilir olmak.
- Tauri 2 · React
- Rust API
- Python sidecar
- SQLite / SQLCipher
- Windows DPAPI
- Trainee records and document check. It reads uploaded documents and catches a document that belongs to someone else.
- MEBBİS centre. Integration with the Ministry of Education's portal. In production it handled 212 candidates with 0 errors.
- Lesson and exam planning: driving lists, ministry exam lists and Word documents.
- Approved e-invoices through Luca, invoice checks and tariffs. Vehicle tracking through Arvento.
- Owner dashboard, finance screen, daily backup and an installer.
- Kursiyerler ve Evrak Kontrol: belgeleri okur, başkasına ait belgeyi yakalar.
- MEBBİS Merkezi: gerçek MEBBİS'te 212 aday, 0 hata.
- Ders ve sınav planı: direksiyon listesi, MEB sınav listeleri, Word belgeleri.
- Luca'dan onaylı fatura, fatura kontrolü, tarife; Arvento ile araç takip.
- Panel, yönetici ve finans ekranı, günlük yedek, kurulum paketi.
A driving school holds the most sensitive data categories in Turkish law: health reports, criminal-record certificates, ID scans and biometric photos. It also holds the school's passwords for the government portal and the e-invoice system. The test plan is sized to real data: 12,600 trainees and 56,000 scanned documents.
Bir sürücü kursu, Türk hukukundaki en hassas veri türlerini tutar: sağlık raporu, adli sicil belgesi, kimlik taraması, biyometrik fotoğraf. Bunlara ek olarak MEBBİS ve e-Fatura şifrelerini de tutar. Test planı gerçek veri büyüklüğüne göre: 12.600 kursiyer, 56.000 tarama.
Threats we design against, in order: ransomware → theft of credentials (MEBBİS, Luca, e-Devlet) → personal data leak → insider misuse → targeted attack. Once the product runs at many schools, our server becomes a valuable target.
Gerçekçi tehdit sırası: fidye yazılımı → kimlik bilgisi hırsızlığı (MEBBİS, Luca, e-Devlet) → kişi verisi sızıntısı → içeriden kötüye kullanım → hedefli saldırı. Ürün çok kursa yayıldığında sunucumuz değerli bir hedef olur.
Ground rule: assume the client can be broken. So the client holds no secrets: no embedded keys, passwords or hidden endpoints. Anything valuable lives on the server or in the Windows vault. There is no obfuscation, on purpose, because it wouldn't stop a determined attacker.
Temel ilke: istemci kırılabilir kabul edilir. İstemcide sır yok: gömülü anahtar, şifre, gizli uç nokta yok. Değerli olan sunucuda ve Windows kasasında durur. Kod karartma bilinçli olarak yok; kararlı birini durdurmaz.
Statuses are reported honestly. "In place" means verified in code; everything else is on the roadmap. An internal register of open risks is tracked to closure. It is not published here because the software runs at a real school.
Durumlar dürüstçe yazılır: "Var" kodda doğrulanmıştır, gerisi yol haritasındadır. Açık riskler iç bir listede kapanana kadar izlenir; yazılım gerçek bir kursta çalıştığı için burada yayımlanmaz.
| AreaAlan | ControlKoruma | StatusDurum |
|---|---|---|
| IdentityKimlik | Passwords hashed with argon2id. The first owner account can be created only when no users exist, and only from that PC. Session token: 32 random bytes; only its SHA-256 hash is stored. Responses don't reveal whether a user exists.Şifre argon2id; ilk sahip hesabı yalnız hiç kullanıcı yokken ve yalnız o bilgisayardan; oturum anahtarı 32 bayt rastgele, veritabanında yalnız SHA-256 özeti; kullanıcı varlığı sızmaz. | in placevar |
| SecretsSırlar | Portal passwords in DPAPI; portal cookies encrypted; one-time codes never written to disk; keeper accepts only local, keyed commandsPortal şifreleri DPAPI'de; çerezler şifreli; tek kullanımlık kod yazılmaz; bekçi yalnız yerelden ve anahtarla | in placevar |
| RepositoryDepo | ID-number scan before every commit and on every push, history included. Unscannable files (photo, PDF, Excel, ZIP, HAR) need an allowlisted path. AI agents can't read env files. History cleaned and verified.Commit öncesi ve her push'ta, geçmiş dahil TC taraması; taranamayan dosya (fotoğraf, PDF, Excel, ZIP, HAR) yalnız izin listesiyle; ajanlar env dosyalarını okuyamaz; geçmiş temizlendi. | in placevar |
| External actionsDış işlemler | Show → confirm → send → read back. If the portal page is unexpected, the software stops and says manual action is needed.Göster → onaylat → gönder → geri oku; beklenmeyen ekranda dur, "manuel işlem gerekli" de. | e-invoiceLuca MEBBİS writeMEBBİS yazma |
| Data at restDuran veri | Database encrypted with SQLCipher, key in DPAPI with a paper recovery codeSQLCipher ile şifreli veritabanı, anahtar DPAPI'de, kurtarma kodu kâğıtta | in progressyolda |
| BackupsYedek | Daily backup encrypted with the school's own key: local + school's off-site copy + our server in Türkiye. We cannot open it.Kursun anahtarıyla şifreli günlük yedek: yerel + kursun dış kopyası + Türkiye'deki sunucumuz. Biz açamayız. | in progressyolda |
| UpdatesGüncelleme | Ed25519-signed packages, private key kept offline. Unsigned packages are rejected. A backup runs before every update. A separate low-privilege key can only "disable automation and show a message".Ed25519 imzalı paket, özel anahtar çevrimdışı; imzasız paket reddedilir; güncelleme öncesi yedek; ayrı, düşük yetkili anahtar yalnız "otomasyonu kapat + mesaj göster" diyebilir. | in progressyolda |
| AccountabilityHesap verebilirlik | Append-only access log of who opened which document and when; even the app can't edit or delete it. Brute-force lock after 5 failed logins.Kim, ne zaman, hangi belgeyi açtı: uygulamanın bile değiştiremediği erişim günlüğü. 5 yanlış denemede kilit. | in progressyolda |
| ServerSunucu | Hosted in Türkiye. TLS. Mandatory TOTP or passkey for staff. Tenant ID plus row-level security on every table. Remote support is outbound-only, uses fixed read-only commands, lasts 60 minutes and is logged on both sides.Türkiye'de, TLS, ekip hesaplarında zorunlu TOTP / passkey, her tabloda kurum kimliği + RLS; uzak destek kurstan dışarı, salt okunur sabit komutlar, 60 dk, iki taraflı günlük. | plannedplanda |
| PackagePaket | Code-signing certificate; signed integrity manifest for Python filesKod imzalama sertifikası; Python dosyaları için imzalı bütünlük listesi | plannedplanda |
20 reverse-engineering and stress tests
20 maddelik tersine mühendislik ve stres testi
- Reverse engineering (#1–2): inspect my own executables and installer with IDA, Ghidra and
strings; tamper with installed files and check that it's detected. - Attacking the local API (#3–8): requests without auth, forged Host/Origin, DNS rebinding, requests from another PC, CSRF from an open web page, keeper commands with no key or a wrong key, Tauri commands outside their permissions, HTML/JS payloads in trainee names across every screen and Word document, and path traversal.
- Forensics (#9–10): disk traces (permissions, backups, logs, OCR and print temp files, WebView2 storage) and process memory dumps, checked for passwords and one-time codes.
- Tersine mühendislik (#1–2): kendi exe ve kurulum paketim IDA / Ghidra /
stringsile; kurulu dosyayı değiştirip fark edildiğini görmek. - Yerel API'ye saldırı (#3–8): girişsiz istek, sahte Host/Origin, DNS rebinding, başka bilgisayardan istek, açık web sayfasından CSRF, bekçiye anahtarsız ya da yanlış anahtarla komut, yetki dışı Tauri komutları, her ekranda ve Word belgesinde kursiyer adına HTML/JS yükü, dizin aşma.
- Adli inceleme (#9–10): diskteki izler (izinler, yedek, günlük, OCR ve baskı geçicileri, WebView2 depolaması) ve süreç bellek dökümleri: şifre ve tek kullanımlık kod aranır.
- Update chain (#11–12): fake update manifest, unsigned package, downgrade, man-in-the-middle; replayed, expired or foreign password-reset tokens.
- Data hygiene (#13): personal data and secrets in git history.
- Resilience (#14–20): real-scale data, 8 hours of uptime, a power cut mid-write, a full disk, a clock change, non-Turkish Windows, an external system dropping mid-operation, a portal page that changes (tested on the simulator), and a ransomware drill where the PC is gone.
- Güncelleme zinciri (#11–12): sahte güncelleme bildirimi, imzasız paket, sürüm düşürme, araya girme; tekrar kullanılan, süresi geçmiş ya da başka cihazın sıfırlama belirteci.
- Veri temizliği (#13): git geçmişinde kişi verisi ve sır.
- Dayanıklılık (#14–20): gerçek büyüklük, 8 saat açık kalma, yazarken elektrik kesintisi, dolu disk, saat değişimi, Türkçe olmayan Windows, işlem ortasında kopan dış sistem, değişen portal sayfası (simülatörde), bilgisayarın gittiği fidye yazılımı tatbikatı.
Tests #1–12 and #20 are exactly the kind of work the Cyber Verification Program is for. I run them only on my own builds, on my own machine.
#1–12 ve #20, Cyber Verification Program'ın tam olarak kapsadığı türden işler. Bunları yalnız kendi sürümlerimde, kendi bilgisayarımda yapıyorum.
Personal data, by design
Tasarımdan kişisel veri koruması
Türkiye's Personal Data Protection Law treats health and criminal-record data, and biometric data, as special categories (Art. 6). A driving school processes all three. Each class of data has a fixed home and a list of places it must never reach:
KVKK, sağlık ve ceza mahkûmiyeti verisini ve biyometrik veriyi özel nitelikli sayar (md. 6). Bir sürücü kursu üçünü de işler. Her veri sınıfının sabit bir yeri ve asla gitmeyeceği yerlerin listesi var:
| ClassSınıf | ExamplesÖrnek | LivesNerede durur | Never goes toAsla gitmez |
|---|---|---|---|
| Special categoryÖzel nitelikli | health report, criminal record, ID scan, biometric photosağlık raporu, adli sicil, kimlik taraması, biyometrik fotoğraf | school's PC; on our server only inside a backup encrypted with the school's keykursun bilgisayarı; sunucuda yalnız kursun anahtarıyla şifreli yedek içinde | our server in plaintext, WhatsApp, logs, repositoriesaçık hâliyle sunucu, WhatsApp, günlük, depo |
| PersonalKişisel | name, T.C. ID number, phone, addressad, TC, telefon, adres | school's PC; the server gets only what a feature needs (name + status, phone for messages)kursun bilgisayarı; sunucuya yalnız gereken kadarı (ad + süreç, mesaj için telefon) | repositories, logs; ID numbers never in message templatesdepo, günlük; mesaj şablonunda TC |
| SecretSır | portal passwords, database keyportal şifreleri, veritabanı anahtarı | DPAPI (user scope) + paper recovery codeDPAPI (kullanıcı kapsamı) + kâğıtta kurtarma kodu | repositories, config files, serverdepo, ayar dosyası, sunucu |
| TransientGeçici | portal one-time codeMEBBİS doğrulama kodu | memory, for that moment onlyyalnız o an, bellekte | written nowherehiçbir yere yazılmaz |
| SessionOturum | owner / secretary sessionsahip / sekreter oturumu | only its SHA-256 hashyalnız SHA-256 özeti | — |
- Roles: the school is the data controller and we are the data processor. Before the first paying customer, a lawyer will help us prepare the data-processing agreement, the privacy notice (aydınlatma metni) and the WhatsApp consent line.
- Breach notification: the KVK Board must be notified within 72 hours of learning of a breach. The access log exists partly for this.
- Residency: our server will be in Türkiye, so there is no cross-border transfer. WhatsApp Cloud API messages are opened at Meta, which is a transfer, so it is flagged for legal review before use.
- Minimisation and masking: logs contain no personal data. ID numbers are masked or left out of lists, and shown in full only where staff need them.
- Retention: records are kept for 2 years after they close, or for the ministry's period if that is longer (to be confirmed against the legislation). The destruction path is designed together with the append-only tables.
- Local processing: document reading (OCR) and biometric photo preparation run on the school's PC. Nothing goes to a cloud OCR service.
- Roller: kurs veri sorumlusu, biz veri işleyeniz. İlk ücretli müşteriden önce hukukçuyla veri işleyen sözleşmesi, aydınlatma metni ve WhatsApp onay satırı hazırlanır.
- İhlal bildirimi: ihlal öğrenildikten sonra en geç 72 saat içinde Kurul'a; erişim günlüğü bunun için de gerekli.
- Yurt dışı aktarım: sunucu Türkiye'de, aktarım doğmaz. WhatsApp Cloud API mesajları Meta'da açılır, bu bir aktarımdır; kullanmadan önce hukukçuya sorulacak.
- En aza indirme ve maskeleme: günlüklerde kişi verisi yok; TC listelerde maskeli ya da yok, tam hâli yalnız işi gereken personele.
- Saklama ve imha: kaydın kapanışından 2 yıl, MEB'in süresi uzunsa o (mevzuattan doğrulanacak); imha yolu silinmez tablolarla birlikte tasarlanır.
- Yerel işleme: belge okuma (OCR) ve biyometrik fotoğraf hazırlama kursun bilgisayarında yapılır; bulut OCR'a gönderilmez.
MEBBİS Foto publicaçık
Local biometric photo preparation with MediaPipe: face and eye landmarks, alignment, background removal, 394×512 output. Photos never leave the PC. It contains no automation that submits to the portal.
MediaPipe ile yerel biyometrik fotoğraf: yüz ve göz noktaları, hizalama, arka plan ayırma, 394×512 çıktı. Fotoğraf bilgisayardan çıkmaz; portala kayıt gönderen otomasyon içermez.
github.com/z3rocold/mebbis-foto →Document watcher
Evrak izleyici
Detects new criminal-record, health-report and education PDFs, parses them locally, and writes to the school database only after a person confirms. Real documents and samples stay out of git.
Yeni adli sicil, sağlık raporu ve öğrenim belgesi PDF'lerini algılar, yerelde ayrıştırır, okul veritabanına yalnız onaydan sonra yazar. Gerçek belgeler ve örnekler git dışında.
MEBBİS lab
MEBBİS laboratuvarı
Maps of 25 screens and 42 states, taken from the school's own recorded sessions. The goal is a local, resettable simulator with synthetic records, so development never sends test traffic to the real government system. Raw recordings are private and hash-verified, and they are never replayed.
Kursun kendi oturum kayıtlarından 25 ekran / 42 durum haritası. Hedef: sentetik kayıtlarla çalışan, sıfırlanabilen yerel simülatör; geliştirme gerçek devlet sistemine test trafiği göndermez. Ham kayıtlar özel, SHA-256 doğrulamalı, asla tekrar gönderilmez.
surucukursum.net
The product website. Every claim on it has a written source. The same pre-commit personal-data scan runs there.
Ürünün tanıtım sitesi. Sitedeki her iddianın yazılı dayanağı var; aynı commit öncesi kişi verisi taraması orada da çalışır.