13 Ekim 2025 Pazartesi

Docker Compose’tan Kubernetes’e Geçiş: Helm Chart ile Adım Adım Dağıtım Rehberi

Giriş

Docker Compose, tek makinede çok konteynerli uygulamaları hızla ayağa kaldırmak için harika. Ancak ölçek, güvenlik ve gözlemlenebilirlik ihtiyaçları arttığında, Kubernetes’e geçiş kaçınılmaz oluyor. Bu yazıda, mevcut Compose tanımınızı Helm Chart’a dönüştürerek Kubernetes üzerinde modern, sürdürülebilir ve otomasyona uygun bir dağıtım yapmayı adım adım ele alacağız. Rehber, pratik örnekler, en iyi uygulamalar ve sık yapılan hatalara karşı öneriler içerir.

Neden Helm?

Helm, Kubernetes manifestlerini paketleyip versiyonlayarak tekrar kullanılabilir hale getirir. values.yaml ile çevreye göre yapılandırma yönetimi kolaylaşır, helm upgrade --install ile idempotent dağıtımlar yapılır, rollback ile hızlı geri dönüş sağlanır. Çeviklik, izlenebilirlik ve CI/CD uyumluluğu açısından Compose’a kıyasla çok daha güçlü bir yönetim modeli sunar.

Ön Koşullar

- Kubernetes kümesi (minikube, kind, AKS, EKS veya GKE)
- kubectl ve helm kurulu (Helm v3 önerilir)
- Mevcut Docker Compose dosyası (docker-compose.yml)
- Bir container registry erişimi (Docker Hub, GHCR, ECR vs.)

Compose’tan Helm’e Modelleme

Compose servislerini tek tek Deployment ve Service kaynaklarına bölün. Her servis için bir Deployment (replica sayısı, image, env, volume mount) ve bir Service (ClusterIP veya LoadBalancer) oluşturun. Ağ politikaları, health check, kaynak limitleri gibi Kubernetes yerleşik yeteneklerle güvenilirlik ve ölçeklenebilirlik kazanın.

Helm Chart İskeleti Oluşturma

Proje dizininde helm create uyg-app komutunu çalıştırın. Oluşan yapı:
charts/
templates/
values.yaml
Chart.yaml
Yararlı şablonlar gelse de, gereksiz varsayılanları sadeleştirmek iyi bir başlangıçtır.

values.yaml Tasarımı

Uygulamanın farklı ortamları için değişecek alanları values.yaml içine alın. Örnek bir iskelet:
image.repository: ghcr.io/org/uyg-app
image.tag: 1.2.3
replicaCount: 3
resources.limits.cpu: "500m"
resources.limits.memory: "512Mi"
env: { APP_ENV: "prod", LOG_LEVEL: "info" }
service.type: ClusterIP
service.port: 8080
ingress.enabled: true
ingress.hosts: ["api.ornek.com"]

Deployment ve Service Şablonları

Deployment için şunları ihmal etmeyin:
- resources: request ve limit belirleyin (örn. cpu: 200m, memory: 256Mi).
- livenessProbe ve readinessProbe: HTTP endpoint veya TCP check ile hızlı hata tespiti.
- securityContext: root dışı kullanıcı, readOnlyRootFilesystem, capabilities kısıtlaması.
- envFrom: ConfigMap ve Secret’lardan çevresel değişken yönetimi.
Service için uygun type (ClusterIP, NodePort, LoadBalancer) ve port seçin. Dış dünyaya açılacaksanız Ingress tanımı ve TLS sertifikası (ör. cert-manager) planlayın.

İnşa, Push ve İlk Dağıtım

- Container imajınızı CI üzerinden versiyonlayın ve registry’ye push edin (örn. 1.2.3 tag’i).
- values.yaml içindeki image.tag değerini güncelleyin.
- İlk kurulum: helm upgrade --install uyg-app ./uyg-app -n prod
- Dağıtımı doğrulayın: kubectl get pods -n prod ve kubectl describe ile olayları inceleyin.

Yükseltme ve Geri Alma

- Versiyon güncellemesi: helm upgrade uyg-app ./uyg-app -n prod
- Farkları görmek için: helm diff upgrade (helm-diff eklentisi).
- Sorun varsa: helm rollback uyg-app <REVISION> -n prod. Helm, geçmiş sürümleri sakladığından geri dönüşler saniyeler içinde tamamlanır.

Gizli Bilgiler ve Config Yönetimi

Şifreler, token’lar ve API anahtarlarını Secret içinde tutun. Git’te açık tutmamak için Sealed Secrets veya External Secrets Operator kullanın. Konfigürasyonlarınızı ConfigMap olarak versiyonlayın; uygulama yeniden başlatması gerektiren değişikliklerde checksum/config anotasyonuyla otomatik rollout sağlayın.

Otomatik Ölçeklendirme ve Sağlık

HPA (Horizontal Pod Autoscaler) ile CPU/Memory metriklerine göre pod sayısını otomatik artırıp azaltın. readinessProbe doğru ayarlı değilse HPA ölçeklense bile trafiğin başarısız olacağını unutmayın. Ayrıca PodDisruptionBudget ile planlı bakım sırasında minimum sağlıklı pod sayısını garanti altına alın.

Güvenlik ve RBAC

Uygulamaya özel bir ServiceAccount tanımlayın, yalnızca gerekli izinleri veren bir Role/RoleBinding ekleyin. PodSecurityContext ile kullanıcı/GRUP ID belirleyin, root olarak çalışmayın. Ağ tarafında NetworkPolicy ile trafik kısıtlaması yaparak saldırı yüzeyini daraltın.

CI/CD ve GitOps

- CI adımları: test → build → scan → push → helm lint → helm template/diff → deploy.
- GitOps için Argo CD veya Flux kullanın. Helm chart’ınızı bir Git deposuna koyun, values dosyalarını ortam bazlı dallarda yönetin. Her commit, küme durumunu deklaratif olarak günceller; manuel hataları azaltır.

Gözlemlenebilirlik: Log, Metrik ve İz

Log’lar için stdout/stderr yazın; kümede Loki/ELK ile toplayın. Metrikler için Prometheus, dashboard için Grafana kurun. Uygulama düzeyinde OpenTelemetry ile dağıtık izlemeyi etkinleştirerek istek gecikmelerini uçtan uca görünür kılın.

Yaygın Hatalar ve İpuçları

- imagePullPolicy yanlış: Geliştirme dışında IfNotPresent genelde yeterlidir; prod’da immutable tag kullanın (örn. SHA digest).
- resource tanımsız: Limit/Request yoksa scheduler tutarsız davranır; önceliklendirme zorlaşır.
- probe endpoint’leri: Uygulama hazır olmadan trafiğe açmayın; readiness’i gerçek bağımlılıklar sağlandığında başarılı olacak şekilde ayarlayın.
- config değişikliği rollout: ConfigMap değişikliğini pod’lara yansıtmak için anotasyon checksum tekniğini kullanın.

Sonuç

Helm ile Kubernetes’e geçiş, yalnızca bir orkestrasyon değişimi değil; aynı zamanda daha iyi sürümleme, güvenlik, otomasyon ve gözlemlenebilirlik kültürüne geçiştir. Compose dünyasındaki sadeliği, şablonlanabilir manifestler, values tabanlı yapılandırma ve GitOps süreçleriyle kaybetmeden; aksine kurumsal ölçekte yönetilebilirlik kazanırsınız. Küçük başlayın, her sürümde bir iyileştirme ekleyin ve dağıtımlarınızı otomatikleştirerek güvenle ölçekleyin.

12 Ekim 2025 Pazar

OpenTelemetry ile Node.js Uygulamalarında Dağıtık İzleme: Jaeger ile 15 Dakikada Kurulum

OpenTelemetry nedir ve neden şimdi?

Modern uygulamalar mikroservisler, HTTP çağrıları, mesaj kuyrukları ve veritabanı etkileşimleriyle dolu. Bir isteğin nerede yavaşladığını veya neden hata verdiğini anlamak için klasik loglar tek başına yetmiyor. OpenTelemetry (OTel), dil bağımsız bir standart ve SDK seti olarak uygulama içinde otomatik enstrümantasyon sağlar; iz (trace), span, metrik ve log verilerini toplayıp OTLP gibi açık protokollerle istediğiniz araca yollar. Bu rehberde, Node.js bir servise OTel entegre ederek izleri Jaeger üzerinden görselleştireceğiz.

Hedef

Amaç: Node.js uygulamanızdaki HTTP isteklerinin uçtan uca izlenmesini 15 dakikada etkinleştirmek. İzleri toplamak için OpenTelemetry Node SDK’sını kullanacağız, çıktıyı OTLP üzerinden gönderecek ve Jaeger All-in-One ile arayüzde görüntüleyeceğiz.

Önkoşullar

- Node.js 16+ ve npm yüklü olmalı. - Docker çalışıyor olmalı. - Uygulama Express, Fastify veya yerleşik HTTP modülü kullanıyor olabilir; OTel, otomatik enstrümantasyonla bu kütüphaneleri tanır.

Adım 1: Paketleri yükleyin

Projeye OpenTelemetry bağımlılıklarını ekleyin: npm i @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/resources @opentelemetry/semantic-conventions @opentelemetry/exporter-trace-otlp-http

Bu paketler; API yüzeyi, Node SDK, otomatik enstrümantasyon, kaynak (resource) nitelikleri ve OTLP HTTP trace exporter içerir. İhtiyaca göre gRPC tabanlı exporter da tercih edebilirsiniz fakat yerelde HTTP pratik ve hızlıdır.

Adım 2: Tracing başlatıcısını oluşturun

Proje köküne tracing.js isminde bir dosya ekleyin ve SDK’yı minimum ayarlarla başlatın. Ana fikir: servis adını tanımlayın, OTLP exporter’ı 4318 portuna yönlendirin ve otomatik enstrümantasyon modüllerini etkinleştirin.

Örnek yapılandırma (özet): const { NodeSDK } = require('@opentelemetry/sdk-node'); const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node'); const { Resource } = require('@opentelemetry/resources'); const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); const sdk = new NodeSDK({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: 'orders-api', [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0' }), traceExporter: new OTLPTraceExporter({ url: 'http://localhost:4318/v1/traces' }), instrumentations: [getNodeAutoInstrumentations()] }); sdk.start(); process.on('SIGTERM', () => sdk.shutdown());

Burada service.name gelecekteki sorgular için kritik; Jaeger’de projeyi bu ad üzerinden bulacaksınız. Versiyon alanı, sürüm bazlı karşılaştırmalar için faydalıdır.

Adım 3: Uygulamayı OTel ile çalıştırın

Node sürecini tracing başlatıcısı ile preload ederek başlatın: node -r ./tracing.js app.js

Eğer bir test isteği göndermek isterseniz, uygulama ayağa kalktıktan sonra örneğin curl http://localhost:3000/health gibi basit bir çağrı yapın. OTel, HTTP istemci ve sunucu katmanlarını, Express route’larını ve veritabanı sürücülerini otomatik olarak span’lere dönüştürür.

Adım 4: Jaeger All-in-One’ı başlatın

Jaeger’i tek komutla çalıştırabilirsiniz. Bu imaj, OTLP HTTP alıcısı ve web arayüzünü içerir: docker run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one:1.56

- 16686: Jaeger UI portu. - 4318: OTLP HTTP endpoint’i. Uygulamanızdaki exporter URL’si ile eşleşir. Arayüze tarayıcıdan erişip (localhost:16686) “services” alanında orders-api servisini seçerek izleri görüntüleyebilirsiniz.

Adım 5: Manuel span eklemek (opsiyonel)

Otomatik enstrümantasyon çoğu senaryo için yeterli olsa da domain mantığınızı daha iyi anlamak için manuel span eklemek değerlidir. Örneğin kritik bir iş kuralını ölçmek için: const { context, trace } = require('@opentelemetry/api'); const tracer = trace.getTracer('orders-business'); await tracer.startActiveSpan('price-calculation', span => { // iş mantığı ... span.setAttribute('discount.applied', true); span.end(); });

Bu şekilde, Jaeger’de sadece altyapı çağrılarını değil, iş süreçlerinizi de okunaklı şekilde takip edebilirsiniz.

Üretim için en iyi uygulamalar

- Örnekleme (sampling): Trafiğiniz yüksekse, varsayılan oranı düşürün. Çevresel değişkenle kontrol etmek pratik: OTEL_TRACES_SAMPLER=traceidratio ve OTEL_TRACES_SAMPLER_ARG=0.1 (yüzde 10). - Kaynak nitelikleri: Ortam bilgilerini ekleyin: deployment.environment=prod, cloud.region=eu-central-1. - Veri güvenliği: Hassas verileri span attribute veya event’lerde taşımayın. Maskleme/sansürleme katmanı ekleyin. - Bağımlılık izleme: HTTP client timeouts, retry politikaları ve hataları span event’lerinde açıkça belirtin. - Başlatma düzeni: Tracing dosyanızı uygulama kodundan önce yüklediğinizden emin olun; aksi halde ilk istekler enstrümanlanmayabilir.

Sorun giderme

- İzler gelmiyor: Exporter URL’sini ve portu doğrulayın (http://localhost:4318/v1/traces). - CORS/agent hatası: Sunucu tarafında çalıştığınızdan emin olun; tarayıcı için farklı SDK gerekir. - Servis görünmüyor: service.name niteliği boşsa Jaeger listede göstermeyebilir. - Ağ çakışmaları: 4318 portu başka bir süreç tarafından kullanılıyorsa, Jaeger’i farklı portla çalıştırın ve exporter URL’sini eşitleyin.

Sonuç

OpenTelemetry ile Node.js uygulamanıza dakikalar içinde dağıtık izleme ekleyebilir, Jaeger üzerinden gecikmeleri, hata oranlarını ve bağımlılık zincirlerini şeffaf biçimde görebilirsiniz. Daha ileri kullanımda OpenTelemetry Collector ekleyip verileri birden fazla hedefe (ör. Tempo, Zipkin) yönlendirebilir; metrik ve log’ları aynı bağlamda zenginleştirerek tam kapsamlı gözlemlenebilirlik elde edebilirsiniz. Başlangıç için bu kurulum, üretimde dahi temel ihtiyaçları karşılayacak kadar hafif ve esnektir.

11 Ekim 2025 Cumartesi

GitHub Actions ile Monorepo’da Çoklu Platform Docker İmajı, Önbellekli Build ve SBOM/İmza (Buildx Rehberi)

Giriş

Monorepo yapısında birden fazla servis için Docker imajı üretmek, özellikle hem amd64 hem de arm64 mimarilerini hedeflemek istediğinizde çabucak karmaşıklaşır. GitHub Actions ve Docker Buildx, doğru yapılandırıldığında bu süreci hem hızlı hem de güvenli hale getiriyor. Bu yazıda, çoklu platform (multi-arch) imaj oluşturma, build önbelleği (cache) kullanma, SBOM üretme ve imaj imzalama adımlarını pratik bir akış üzerinden anlatacağım. Amacım, “tek seferde kurulup unutulan” bir CI/CD hattı kurmanıza yardımcı olmak.

Neden Çoklu Platform İmaj?

Apple Silicon (arm64) yaygınlaştıkça geliştiriciler ve üretim ortamları farklı mimarilerde çalışabiliyor. İmajlarınızı linux/amd64 ve linux/arm64 için aynı anda yayınlamak, hem geliştirici deneyimini iyileştirir hem de edge/IoT gibi arm tabanlı cihazlarda dağıtımı kolaylaştırır. Buildx, bu geçişi QEMU emülasyonu ile otomatikleştirebilir, böylece tek bir komutla iki mimariyi de üretebilirsiniz.

Gereksinimler ve Gizli Anahtarlar

Başlamadan önce bir container registry belirleyin (Docker Hub veya GHCR). GitHub deposunda Secrets bölümüne aşağıdaki bilgileri ekleyin: REGISTRY_USERNAME, REGISTRY_TOKEN (veya GHCR için GHCR_PAT). Eğer imaj imzalayacaksanız, Cosign anahtar çiftinizi ya da keyless (OIDC) yöntemi kullanacaksanız ilgili izinleri de ayarlayın. Monorepo kullanıyorsanız her servis için bir context yolu tanımlayın (ör. services/api, services/web).

Workflow’un İskele Yapısı

Tipik bir akışta, tetikleyiciler push (özellikle tag ile sürümleme), pull_request ve isteğe bağlı olarak workflow_dispatch olur. Adımlar sırasıyla şöyle ilerler: kodun çekilmesi (actions/checkout), QEMU kurulumu (çoklu platform için), Buildx kurulumu, registry’e giriş, build ve push. Performans için BuildKit önbelleğini GitHub Actions içi önbellek (type=gha) ile kullanmanızı öneririm. Bu sayede aynı katmanları tekrar tekrar derlemek zorunda kalmazsınız.

Örnek akış mantığı şu sırayı izler: “Checkout → QEMU kur → Buildx kur → Registry login → Çoklu platform build + push → SBOM üret → İmza → Artefact yükleme”. YAML dosyasında docker/build-push-action için platforms: linux/amd64,linux/arm64, cache-from: type=gha, cache-to: type=gha,mode=max gibi ayarları etkinleştirin. Etiketlemede semantik sürüm (örn. v1.4.2) ile latest tag’ini birlikte yayınlayın; branch tabanlı tag’ler (örn. edge) test ortamlarına akış sağlar.

SBOM ve Tedarik Zinciri Güvenliği

Güncel güvenlik süreçlerinde SBOM (Software Bill of Materials) zorunluluğa yakın bir standart haline geldi. Buildx/BuildKit ile attest=type=sbom kullanarak imajın içine SBOM gömebilir veya Syft gibi bir araçla ayrı bir dosya olarak üretip CI artefact’ı olarak saklayabilirsiniz. Ben genellikle her ikisini de yapıyorum: imaj attestation, dışa aktarılan bir SBOM ve basit bir HTML rapor; böylece hem makine hem de insan odaklı kontroller kapsanmış oluyor.

İmza tarafında, Cosign ile imajınızı imzalamak, üretim registry’nizde kimlik doğrulanmış ve değişmez bir iz bırakır. Keyless imza (OIDC) kullanıyorsanız GitHub Actions koşusunda sağlanan kimlik belirteçleriyle etkileşimsiz imza atabilirsiniz. Üretim tarafında ise; admission controller’lar veya politika motorları (örn. Kyverno, Connaisseur) ile “sadece imzalı imajlar” kuralını uygulamak, supply chain risklerini ciddi oranda azaltır.

Monorepo ve Build Matrisi

Monorepo’da birden çok dizini tek akışta derlemek için matris kullanın. Her matris girdisi bir servis yolunu ve hedef imaj adını taşısın. Değişiklik bazlı build için paths-filter ile dosya/dizin değişikliklerini algılayan bir ön adım ekleyip sadece etkilenen servisleri derlemek, gereksiz build’lerin önüne geçer. Bu, özellikle cache etkinleştirilmiş Buildx ile birleştiğinde, PR başına dakikalarca zaman tasarrufu sağlar.

Önbellek (Cache) İncelikleri

Build performansı, doğru katmanlaşmış bir Dockerfile ve doğru cache stratejisi ile dramatik biçimde iyileşir. Bağımlılık kurulumunu (örn. npm ci, pip install, go mod download) kaynak kodundan önceki katmanlarda tutun ve sadece lock dosyası değiştiğinde invalid olsun. GitHub Actions içinde type=gha cache’i kullanırken mode=max seçimi daha agresif bir yeniden kullanım sağlar. Pull request build’lerinde push: false ile imajı registry’ye itmeden cache’i yine de güncelleyebilirsiniz.

Sürümleme ve Etiket Stratejisi

Üretim tutarlılığı için semantik sürümleme öneririm. Tag’lerinizden dinamik olarak şu etiketleri çıkarın: vX.Y.Z, vX.Y, vX ve latest. Ana branş için edge veya canary etiketi de ekleyebilirsiniz. Bu yaklaşım tüketen taraflara esnek güncelleme kanalları sunar ve geri dönüş (rollback) senaryolarını netleştirir.

Sık Karşılaşılan Sorunlar

QEMU tabanlı derlemelerde nadiren de olsa bellek/süre limitine takılabilirsiniz; çözüm olarak job’a daha yüksek zaman limiti tanımlayın veya daha küçük base image’lar kullanın. “manifest list” hataları genellikle eksik push veya yanlış tag kombinasyonundan kaynaklanır; multi-arch push’un tek adımda yapılmasına dikkat edin. SBOM/attestation çıktılarının registry tarafından desteklenip desteklenmediğini kontrol edin; bazı özel registry’ler attestation’ı farklı isimlendirme ile saklayabiliyor.

Sonuç

GitHub Actions + Docker Buildx ikilisiyle monorepo’nuzda çoklu platform imaj üretmek, cache ile hızlandırmak, SBOM ve imza ile güvence altına almak zor değil; ancak birkaç temel ayrıntıyı doğru ayarlamak şart. Yukarıdaki iskelet yaklaşımı kendi proje yapınıza uyguladığınızda, hem geliştirici geri bildirim döngünüz hızlanacak hem de tedarik zinciri güvenliği gereksinimlerini karşıladığınızı bilerek daha rahat uyuyacaksınız. İleride bu akışı, imaj tarama, imza doğrulama ve politika kontrolü adımlarıyla genişleterek uçtan uca güvenli bir dağıtım hattına dönüştürmeniz mümkün.

10 Ekim 2025 Cuma

Passkeys ile Şifresiz Giriş: WebAuthn + FIDO2 ile Adım Adım Uygulama Rehberi

Passkey nedir ve neden şimdi?

Parola sızıntıları, oltalama (phishing) ve zayıf parola alışkanlıkları yıllardır güvenlik ekosisteminin en zayıf halkası. Passkey, FIDO2 standartları ve WebAuthn API’si üzerine inşa edilen, kullanıcıların yalnızca cihazlarındaki biyometrik doğrulama (parmak izi, Face ID, Windows Hello) veya PIN ile oturum açmasını sağlayan şifresiz bir yöntemdir. Parolalar yok, tek kullanımlık SMS kodları yok; kriptografik anahtar çifti ve tarayıcı desteği var. Apple, Google ve Microsoft’un ekosistemlerinde senkronize edilebilen passkey’ler hem güvenliği hem de dönüşüm oranlarını artırır.

Bu rehberde, modern bir web uygulamasına passkey tabanlı kayıt ve giriş akışını nasıl ekleyeceğinizi, hangi teknik ayrıntılara dikkat etmeniz gerektiğini ve yaygın hataları nasıl önleyeceğinizi anlatıyorum. Anlatım sade, adımlar somut; odak noktamız uygulanabilirlik.

Mimariye hızlı bakış

WebAuthn, üç aktörle çalışır: Relying Party (siteniz), istemci (tarayıcı) ve authenticator (platform veya harici anahtar). Kayıt sırasında site, tarayıcıya bir challenge ve ayarlar gönderir; cihazda bir anahtar çifti oluşturulur, siteniz genel anahtarı güvenli şekilde kaydeder. Girişte, site bir challenge ile imza ister; cihaz, kullanıcı doğrulaması sonrası imzayı üretir ve siteniz bunu doğrular. Parola asla yok; kimlik doğrulama domain’e (rpId) bağlı olduğu için oltalama büyük ölçüde engellenir.

Önkoşullar ve kurulum gereksinimleri

- HTTPS zorunlu: WebAuthn yalnızca güvenli origin’lerde çalışır. Geliştirme için localhost istisnadır.

- rpId ve origin: rpId genellikle alan adınızdır (ör. example.com). Alt alanlardan çağırıyorsanız bunu planlayın.

- Session ve CSRF: Challenge değerlerini oturumda tutun; her istek için taze ve tekil challenge üretin. SameSite=Lax/Strict çerezleri tercih edin.

- Tarayıcı desteği: Chrome, Edge, Safari ve Firefox güncel sürümlerde passkey destekliyor. iOS 16+, Android 9+ geniş kapsama sahip.

Kayıt akışı: Sunucu tarafı

1) Kullanıcı kayıt butonuna bastığında sunucu benzersiz bir challenge üretir ve oturumda saklar. Ardından istemciye PublicKeyCredentialCreationOptions döndürür: { rp: { name, id }, user: { id, name, displayName }, challenge, pubKeyCredParams, authenticatorSelection, attestation }.

2) user.id değeri kararlı ve benzersiz olmalı (ör. 16-32 baytlık bir UUID veya key). Kullanıcı adını değiştirse bile user.id sabit kalmalıdır.

3) Attestation’ı çoğu senaryoda "none" olarak ayarlayın; gizlilik ve uyumluluk açısından yeterlidir.

4) İstemciden dönen attestationObject ve clientDataJSON alanlarını doğrulayın: challenge eşleşmesi, origin kontrolü ve attestation formatı. Başarılıysa credentialId, publicKey ve signCount’ı veritabanında kullanıcıyla eşleştirerek saklayın.

Giriş akışı: Sunucu ve istemci

1) Sunucu, giriş başlatıldığında yine tekil bir challenge üretir ve PublicKeyCredentialRequestOptions döndürür: { challenge, rpId, allowCredentials?, userVerification }. Passkey-first deneyimi için discoverable credentials (resident key) kullanımını tercih edebilirsiniz; bu durumda allowCredentials boş bırakılabilir.

2) İstemci tarafında, kayıt için navigator.credentials.create({ publicKey }), giriş için ise navigator.credentials.get({ publicKey }) çağrıları yapılır. Mobilde ve masaüstünde tarayıcı, sistem düzeyi biyometri istemini kendisi yönetir.

3) Dönen authenticatorData, clientDataJSON ve signature sunucuya gönderilir. Sunucu, ilgili publicKey ile imzayı doğrular, signCount artışını kontrol eder ve oturumu başlatır.

Conditional UI ve kullanıcı adı olmadan giriş

Chrome ve Android’de Conditional UI ile otomatik doldurma benzeri bir passkey deneyimi sunabilirsiniz. navigator.credentials.get({ publicKey, mediation: "conditional" }) şeklinde çağrıldığında kullanıcı adı alanına odaklanıldığında tarayıcı passkey önerir. Bu, “username-less” akışlarla birleştiğinde form sürtünmesini ciddi şekilde azaltır.

En iyi uygulamalar

- Resident key desteğini açın: authenticatorSelection: { residentKey: "preferred", userVerification: "required" }. Böylece kullanıcı adı olmadan giriş mümkün olur.

- Base64url dönüşümlerine dikkat: Tarayıcı ArrayBuffer döndürür; sunucuya gönderirken ve doğrularken URL-safe kodlama kullanın.

- Çoklu cihaz stratejisi: Passkey’ler iCloud Anahtar Zinciri ve Google Password Manager ile eşzamanlanabilir. Kullanıcıların ikinci cihaz eklemesini ve donanımsal anahtarları (YubiKey) desteklemeyi düşünün.

- Geri kazanım planı: Cihaz kaybında kilitlenme yaşanmaması için e-posta bağlantısı veya destek kanıtı gibi güvenli kurtarma akışları tasarlayın. Parolaya dönmek yerine sınırlı ayrıcalıklı, denetimli akışlar tercih edin.

Test ve hata ayıklama

- Chrome DevTools’ta Virtual Authenticator ile farklı authenticator türlerini ve UV/UP kombinasyonlarını simüle edin. chrome://webauthn üzerinden test kolaydır.

- Origin ve rpId uyuşmazlıkları en yaygın sorundur. Üretimde www ve kök alan adı tutarsızlıklarını önleyin.

- Sunucu saat senkronizasyonu, proxy ve CDN başlıkları (X-Forwarded-Proto) için yapılandırmalarınızı kontrol edin; HTTPS algısı bozulursa WebAuthn başarısız olabilir.

Güvenlik ve uyumluluk notları

Passkey’ler kimlik bilgilerinin etki alanına bağlanması sayesinde oltalamaya dirençlidir. Ortadaki adam saldırıları, parolalara göre anlamlı ölçüde zorlaşır. Kurumsal ortamlarda cihaz yönetimi, anahtar yedekleme politikaları ve regülasyon (KVKK/GDPR) gerekliliklerini değerlendirin. Attestation’a yalnızca gerçekten cihaz tedarik zinciri doğrulaması gerekiyorsa başvurun; aksi halde gizlilik dostu none yeterlidir.

Sonuç: Şifresiz geleceğe bugünden geçin

Passkey, kullanıcılar için sürtünmeyi azaltırken güvenliği yükselten nadir teknoloji kırılımlarından biri. Kayıt ve giriş akışlarında WebAuthn’u doğru kurguladığınızda, dönüşüm oranlarınız artar ve destek yükünüz azalır. Adımları küçükten büyüğe taşıyın: önce HTTPS ve rpId düzeni, sonra resident key ve conditional UI, en sonunda çoklu cihaz ve kurtarma planları. Bir kez doğru kurguladığınızda, şifresiz girişin kullanıcı memnuniyetine ve güvenliğe etkisini doğrudan göreceksiniz.

9 Ekim 2025 Perşembe

Passkey (FIDO2/WebAuthn) ile Parolasız Giriş: Modern Web Uygulamalarına Adım Adım Entegrasyon

Passkey ve WebAuthn Nedir, Neden Önemli?

Parolasız kimlik doğrulama, güvenlik ve kullanıcı deneyimi açısından modern webin en kritik dönüşümlerinden biri. Passkey teknolojisi, FIDO2 ve WebAuthn standartlarına dayanarak şifreleri tamamen ortadan kaldırır ve herkese açık anahtar kriptografisiyle phishing saldırılarını kökten azaltır. Kullanıcılar, platformlarının (iOS, Android, Windows, macOS) yerleşik güvenlik donanımını veya güvenlik anahtarlarını (YubiKey gibi) kullanarak tek dokunuşla giriş yapar. Bu makalede, bir web uygulamasına passkey (WebAuthn) entegrasyonunu adım adım, pratik ipuçlarıyla anlatıyorum.

WebAuthn Nasıl Çalışır? (Kısa Teknik Özet)

WebAuthn, tarayıcı üzerinden navigator.credentials API’si ile çalışır. Kayıt (registration) aşamasında sunucu bir challenge üretir ve tarayıcıya gönderir. Kullanıcının cihazı benzersiz bir anahtar çifti (özel/public) oluşturur; public key sunucuya kaydedilir. Giriş (authentication) aşamasında sunucu yine bir challenge yollar; cihaz, özel anahtarla bu challenge’ı imzalar ve tarayıcı imzayı sunucuya iletir. Sunucu public key ile imzayı doğruladığında kullanıcı giriş yapar. Şifre yoktur; dolayısıyla credential stuffing ve klasik phishing riskleri dramatik biçimde azalır.

Ön Koşullar ve Mimarinin Temelleri

Entegrasyon için HTTPS zorunludur; rpId (Relying Party ID) genellikle alan adınızın eTLD+1 biçimidir (örneğin example.com). Backend tarafında kayıt ve giriş için iki uç nokta gerekir: /webauthn/register ve /webauthn/login (veya benzer adlar). Bu uç noktalar challenge üretir, tarayıcıdan dönen yanıtları doğrular ve kimlik bilgilerini (credentialId, publicKey, aaguid vb.) saklar. Sunucu tarafında dilinize göre bir WebAuthn/FIDO2 kütüphanesi kullanmanız önerilir; örneğin Node.js için SimpleWebAuthn, .NET için Fido2NetLib, Go için popüler WebAuthn paketleri mevcuttur.

Adım 1: Kayıt (Registration) Akışı

1) Sunucu, kullanıcı hesabı oluşturulurken bir kayıt challenge’ı üretir ve tarayıcıya dönüş yapar. Dönen JSON içinde publicKey alanı olmalıdır (rp, user, challenge, pubKeyCredParams gibi).

2) Tarayıcı tarafında kayıt isteği şu şekilde tetiklenir: const cred = await navigator.credentials.create({ publicKey: options });. Buradaki options, sunucunun verdiği PublicKeyCredentialCreationOptions içeriğidir.

3) Dönen credential, id, rawId, response.attestationObject ve response.clientDataJSON içerir. Bu verileri JSON’a uygun biçimde base64url kodlayıp sunucuya gönderin: POST /webauthn/register/verify.

4) Sunucu, attestation politikasına (genellikle attestation: "none") göre doğrulama yapar, public key ve credentialId’yi kullanıcıyla eşleştirip veritabanına kaydeder. COSE algoritması olarak ES256 varsayılan ve yaygın bir tercihtir.

Adım 2: Giriş (Authentication) ve Passkey Deneyimi

1) Giriş aşamasında sunucu bir doğrulama challenge’ı üretir ve tarayıcıya yollar. Eğer discoverable credentials (kullanıcı adı girmeden hesap seçimi yapılabilen passkey’ler) destekliyorsanız, allowCredentials alanını boş bırakabilirsiniz.

2) Tarayıcı, aşağıdaki çağrıyla kullanıcıdan biyometrik/doğrulama isteği alır: const assertion = await navigator.credentials.get({ publicKey: requestOptions });. Modern tarayıcı ve platformlarda, mediation: "conditional" ile otomatik doldurma benzeri akış sağlayabilirsiniz: navigator.credentials.get({ publicKey: requestOptions, mediation: "conditional" }).

3) Dönen yanıtta response.authenticatorData, response.clientDataJSON ve response.signature bulunur. Bu verileri sunucuya gönderin: POST /webauthn/login/verify. Sunucu, ilgili public key ile imzayı doğrular, signCount değerini günceller ve oturumu başlatır.

En İyi Uygulamalar ve UX İpuçları

Passkey deneyimi, kullanıcı adı ve şifre kutularını tamamen devre dışı bırakabilir. Özellikle Conditional UI desteği ile (Chrome, Android, iOS ve Safari’nin güncel sürümleri) sayfa yüklenir yüklenmez platform, uygun passkey’leri önerir. Kullanıcı tek dokunuşla giriş yapar. Formlarınızda “Passkey ile giriş yap” butonunu net biçimde gösterin; ilk kurulumda parolayı da kabul edip passkey oluşturma adımını teşvik ederek geçişi yumuşatın.

Hesap kurtarma için e-posta doğrulama, yedek güvenlik anahtarları veya müşteri destek süreçleri tasarlayın. Passkey’ler iCloud veya Google hesabı üzerinden cihazlar arasında senkronize olabilir; bu özellik, kullanıcı değişen cihazlarda bile sorunsuz giriş deneyimi sağlar.

Güvenlik ve Uyum Detayları

- HTTPS zorunludur; localhost geliştirme ortamında tarayıcılar özel izinler sunar. Üretimde mutlaka geçerli bir TLS sertifikası kullanın ve TLS 1.2+ desteğini aktif tutun.

- rpId, cookie SameSite ve Secure bayrakları, Origin eşleşmeleri gibi detaylar önemlidir. Ters proxy (Nginx/Caddy/Cloudflare) arkasında header’ların doğru yönlendirildiğinden emin olun.

- Attestation politikanızı iş gereksinimlerine göre belirleyin. Çoğu SaaS için none yeterlidir; regülasyonlu sektörlerde direct veya enterprise gerekebilir.

- Zaman senkronizasyonu (NTP) ve sunucu saat farkı doğrulamada rol oynar; bu nedenle saat kaymasını minimal tutun.

Test, Hata Ayıklama ve Yayına Alma

Geliştirme sırasında tarayıcı konsolunda Security ve Network sekmelerini izleyin; WebAuthn hataları genellikle açıklayıcıdır. localhost üzerinde test ederken rpId olarak “localhost” kullanın. İlk yayında, kademeli açılış (feature flag) ile kullanıcıların küçük bir yüzdesine passkey’i sunup metrikleri takip etmek iyi bir stratejidir: başarı oranı, iptal oranı, geri dönüşler ve destek talepleri ölçülmelidir.

Sonuç: Parolasız Geleceğe Bugünden Geçin

Passkey (FIDO2/WebAuthn) entegrasyonu; daha güvenli, daha hızlı ve daha kullanıcı dostu bir oturum açma deneyimi sağlar. Şifre sıfırlama maliyetlerini düşürür, hesap ele geçirme vakalarını azaltır ve mobil cihazlarda tek dokunuşla giriş imkânı sunar. Bu rehberdeki adımları izleyerek, önce hibrit (parola + passkey) modeliyle başlayabilir, ardından kullanıcılarınız hazır olduğunda tamamen parolasız bir geleceğe geçebilirsiniz.

8 Ekim 2025 Çarşamba

Next.js Projenize Passkey (WebAuthn) ile Parolasız Giriş Ekleme: SimpleWebAuthn ile Adım Adım

Parolasız kimlik doğrulama, hem güvenliği hem de kullanıcı deneyimini aynı anda iyileştiren güncel bir yaklaşım. Bu yazıda Next.js tabanlı bir web uygulamasına Passkey (FIDO2/WebAuthn) ile giriş özelliğini nasıl ekleyebileceğinizi, SimpleWebAuthn kütüphanesinden yararlanarak adım adım anlatıyorum. Amaç; phishing’e dayanıklı, cihazlar arası senkronize olabilen ve kullanıcıya tek dokunuşla giriş sağlayan bir çözüm kurmak.

Passkey nedir? Kısaca, kullanıcı adı-parola yerine cihazın güvenli donanımında (veya güvenli modülde) saklanan anahtar çifti ile giriş yapma yöntemidir. Tarayıcı ve cihaz (ör. iPhone, Android, Windows Hello, güvenlik anahtarı) iş birliğiyle çalışır ve WebAuthn standardını uygular.

Gereksinimler ve Kurulum

Başlamadan önce Node.js 18+, Next.js 13+ (App Router veya Pages), HTTPS (geliştirme için localhost’ta istisna), ve bir veritabanına (PostgreSQL, MongoDB, vb.) ihtiyacınız var. Sunucuda SimpleWebAuthn’in server paketi, istemcide ise browser paketi kullanılacak.

npm install @simplewebauthn/server @simplewebauthn/browser

Prod ortamında RP ID (Relying Party ID) alan adınız olmalı (ör. example.com). RP Origin ise protokol + alan adıdır (ör. https://example.com). Local geliştirmede rpID “localhost”, origin ise “http://localhost:3000” olabilir.

Kayıt (Registration) Akışı

Kullanıcı yeni bir passkey oluştururken, sunucu bir “challenge” üretir ve tarayıcıya kayıt seçeneklerini (PublicKeyCredentialCreationOptions) gönderir. Tarayıcı, cihazın güvenli modülünde anahtar çifti oluşturur ve sonucu sunucuya geri yollar. Sunucu, yanıtı doğrular ve kimlik bilgisini (credential) veritabanına kaydeder.

1) Sunucu: Kayıt seçeneklerini üret

generateRegistrationOptions({ rpName, rpID, userID, userName, attestationType: 'none', authenticatorSelection: { residentKey: 'preferred', userVerification: 'preferred' } })

Burada userID rastgele ve stabil bir kimlik olmalı (ör. UUID). Üretilen challenge değerini oturumda saklayın. rpID, alan adınızla birebir uyumlu olmalıdır; alt alan adı farkları doğrulamayı bozabilir.

2) İstemci: navigator.credentials.create()

const att = await startRegistration(options)

@simplewebauthn/browser içindeki startRegistration, tarayıcı API’sini sarmalar. Kullanıcı Touch ID/Face ID/Pin ile onay verir.

3) Sunucu: Kayıt doğrulama

verifyRegistrationResponse({ response, expectedChallenge, expectedOrigin, expectedRPID })

Doğrulama başarılıysa credentialId, publicKey, signCount gibi alanları kullanıcıya bağlı şekilde veritabanınıza kaydedin. Aynı kullanıcıya birden fazla credential tanımlanabilir; cihaz değiştirme senaryoları için faydalıdır.

Giriş (Authentication) Akışı

Giriş için süreç benzer: Sunucu challenge üretir, istemci bir imza üretir, sunucu imzayı doğrular. Burada kullanılacak seçenekler PublicKeyCredentialRequestOptions’tır.

1) Sunucu: Giriş seçenekleri

generateAuthenticationOptions({ rpID, userVerification: 'preferred', allowCredentials: [{ id: credentialId, type: 'public-key' }] })

allowCredentials ile ilgili kullanıcının credentialId’lerini gönderebilirsiniz. Challenge değeri yine oturumda tutulmalı.

2) İstemci: navigator.credentials.get()

const assertion = await startAuthentication(options)

Kullanıcı cihazında biyometrik/doğrulama adımı gerçekleşir ve tarayıcı imzalı yanıtı döner.

3) Sunucu: Giriş doğrulama

verifyAuthenticationResponse({ response, expectedChallenge, expectedOrigin, expectedRPID, authenticator: storedCredential })

Başarılı doğrulamada signCount artışı izlenmeli. Beklenmedik düşüş, olası klonlanmış bir anahtara işaret edebilir.

Next.js’te İstemci Tarafı ve Oturum

Next.js’te App Router kullanıyorsanız /app/api altında iki rota belirlemek (register ve login için “options” ve “verify”) işleri düzenli kılar. İstemci tarafında butona tıklanınca önce “options” endpoint’ine istek atın, ardından dönen opsiyonları startRegistration veya startAuthentication fonksiyonuna verin. Doğrulama başarılıysa sunucudan bir HttpOnly, Secure cookie (ör. JWT veya session id) ayarlayarak oturumu başlatın. Cookie için SameSite=Strict ve kısa ömür tercih edin.

Güvenlik ve Üretim İpuçları

- Origin ve rpID eşleşmesine çok dikkat edin. Port, protokol ve alt alan adı hataları en yaygın sorundur.
- Attestation genellikle “none” seçilir; cihaz tedarikçi doğrulaması gerektiren kurum uygulamalarında “direct” düşünülebilir.
- Kullanıcılara birden fazla passkey kaydetme imkânı verin. Telefon kaybında erişim kapanmasın.
- SSRF, CSRF ve rate limit gibi genel güvenlik önlemlerini ihmal etmeyin.
- Üretimde her zaman HTTPS kullanın; WebAuthn birçok tarayıcıda güvenli bağ zorunludur.

Hata Ayıklama ve Uyumluluk

Chrome, Safari ve Firefox’un güncel sürümlerinde passkey desteği olgunlaştı. Android 14 ve iOS 17 ile birlikte platform passkey’leri cihazlar arası senkronize edilebiliyor. Test sırasında about://webauthn (Chrome) üzerinden sanal güvenlik anahtarı oluşturabilir, geliştirici seçenekleriyle akışı simüle edebilirsiniz. Hata alırsanız tarayıcı konsolundaki NotAllowedError, SecurityError ve InvalidStateError mesajları size yön gösterecektir.

Sonuç

Passkey, modern web uygulamaları için güçlü ve kullanıcı dostu bir kimlik doğrulama yöntemi. Next.js ve SimpleWebAuthn ile birkaç endpoint yazarak hızlıca devreye alabilirsiniz. Doğru rpID/origin ayarı, güvenli cookie yönetimi ve çoklu credential desteği ile hem güvenlik ekibinizi hem kullanıcılarınızı mutlu edecek bir parolasız giriş deneyimi sunabilirsiniz.

7 Ekim 2025 Salı

WebGPU Destekli ONNX Runtime Web ile Tarayıcıda Yapay Zeka Çalıştırma: Adım Adım Rehber

Giriş

Tarayıcıda yapay zeka çalıştırmak, artık sadece demo projelerin konusu değil. WebAssembly (WASM) ve WebGPU sayesinde, masaüstü benzeri performansla gerçek zamanlı çıkarım almak mümkün. Bu rehberde, ONNX Runtime Web kullanarak bir modeli tarayıcıda çalıştırmayı, WebGPU ve WASM arasında nasıl seçim yapacağınızı ve performansla ilgili pratik ipuçlarını adım adım anlatıyorum.

Neden Tarayıcıda Yapay Zeka?

Tarayıcı üzerinde çıkarımın üç büyük avantajı var: gizlilik (veri cihazdan çıkmıyor), kurulum kolaylığı (ekstra bağımlılık yok) ve dağıtım hızı (sadece bir web sayfası). Örneğin bir görüntü sınıflandırma modeli, web uygulamanızda kullanıcı fotoğrafını anında analiz edebilir ve bu sırada veriyi sunucuya göndermenize gerek kalmaz. Üstelik WebGPU desteği olan tarayıcılarda GPU hızlandırma ile mobil cihazlarda bile akıcı performans elde edebilirsiniz.

Gereksinimler

- Güncel bir tarayıcı (Chrome 113+, Edge 113+, Safari 17+). WebGPU desteği yoksa WASM sağlayıcısı otomatik devreye girer.
- Basit bir HTTP sunucu (ör. npx serve veya python -m http.server). Güvenlik nedeniyle dosyaları doğrudan dosya sistemi üzerinden açmak yerine bir sunucu gerekli.
- Bir ONNX modeli (ör. MobilNet v2 sınıflandırma modeli). Dilerseniz kendi modelinizi torch.onnx.export ile dışa aktarabilirsiniz.

Proje Kurulumu

1) Klasör oluşturun: mkdir ort-web-demo && cd ort-web-demo
2) Model dosyasını model.onnx olarak kök dizine koyun.
3) Aşağıdaki basit HTML dosyasını index.html olarak kaydedin (CDN üzerinden ONNX Runtime Web yüklenecek):

<!doctype html>
<html lang="tr">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <title>ONNX Runtime Web Demo</title>
</head>
<body>
  <h3>Tarayıcıda Yapay Zeka (WebGPU / WASM)</h3>
  <input type="file" id="file" accept="image/*"/>
  <div id="log">Hazır...</div>
  <script src="https://cdn.jsdelivr.net/npm/onnxruntime-web/dist/ort.min.js"></script>
  <script>
  (async () => {
    // WebGPU uygunsa önce onu, değilse WASM'ı dene
    const providers = (navigator.gpu) ? ['webgpu', 'wasm'] : ['wasm'];
    ort.env.wasm.simd = true; // SIMD hızlandırma
    ort.env.wasm.numThreads = Math.min(4, navigator.hardwareConcurrency || 2);

    const session = await ort.InferenceSession.create('model.onnx', { executionProviders: providers });
    document.getElementById('log').innerText = 'Model yüklendi. Sağlayıcı: ' + session.executionProvider;

    const fileInput = document.getElementById('file');
    fileInput.onchange = async () => {
      const file = fileInput.files[0];
      if (!file) return;
      const img = new Image();
      img.src = URL.createObjectURL(file);
      await img.decode();

      // Basit ön işleme: 224x224'e ölçekle, [0,1] normalizasyonu
      const canvas = document.createElement('canvas');
      canvas.width = 224; canvas.height = 224;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, 224, 224);
      const { data } = ctx.getImageData(0, 0, 224, 224);
      const input = new Float32Array(1 * 3 * 224 * 224);
      for (let i = 0; i < 224 * 224; i++) {
        const r = data[i * 4] / 255;
        const g = data[i * 4 + 1] / 255;
        const b = data[i * 4 + 2] / 255;
        input[i] = r; input[i + 224 * 224] = g; input[i + 2 * 224 * 224] = b;
      }

      const tensor = new ort.Tensor('float32', input, [1, 3, 224, 224]);
      const feeds = {}; feeds[session.inputNames[0]] = tensor;
      const t0 = performance.now();
      const results = await session.run(feeds);
      const t1 = performance.now();
      const output = results[session.outputNames[0]].data;
      const maxIndex = output.indexOf(Math.max(...output));
      document.getElementById('log').innerText = `Sınıf: ${maxIndex}, Süre: ${(t1 - t0).toFixed(1)}ms`;
    };
  })();
  </script>
</body>
</html>

Uygulamayı Çalıştırma

Kök dizinde küçük bir sunucu başlatın. Node.js varsa: npx serve . veya Python ile: python -m http.server 8080. Ardından tarayıcıdan http://localhost:8080 adresine gidin. Bir görsel seçtiğinizde model çıkarımı yapacak ve süreyi ms cinsinden gösterecektir. WebGPU mevcutsa sağlayıcı olarak webgpu, değilse wasm kullanılır.

Performans İpuçları

- SIMD ve çok iş parçacığı: Kodda ort.env.wasm.simd = true ve numThreads ayarları etkin. Tarayıcı buna izin veriyorsa WASM performansı ciddi artar.
- WebGPU avantajı: Büyük modellerde GPU hızlandırma dramatik fark yaratır. Ancak WebGPU, HTTPS ve güvenli bağlam gerektirir. Üretimde daima HTTPS kullanın.
- Model optimizasyonu: ONNX modeli fuse ve constant folding ile optimize edin. INT8 quantization (ör. onnxruntime-tools veya optimum) tarayıcıda boyutu küçültür ve hız kazandırır.
- Lazy yükleme: Modeli sayfa yüklendiğinde değil, kullanıcı etkileşimi başladığında indirin. İlk TTI süresini iyileştirir.
- Önbellek: Model dosyasını IndexedDB veya Cache Storage ile saklayın. İlk açılıştan sonra bekleme neredeyse sıfırlanır.

Hata Ayıklama ve Uyumluluk

- Giriş/çıkış adları: Bazı modellerde giriş ismi input değil, farklı olabilir. session.inputNames ve session.outputNames ile dinamik alın.
- Bellek limitleri: Büyük modeller mobilde bellek sınırına takılabilir. Daha küçük veya quantized sürüme geçin.
- CORS: Modeli farklı bir domain’den çağırıyorsanız CORS başlıklarını doğru ayarlayın (Access-Control-Allow-Origin).
- Tarayıcı farkları: Safari’de GPU bellek kotaları daha katı olabilir; WASM yedek planınızın iyi çalıştığından emin olun.

Güvenlik ve Gizlilik

Tarayıcıda çıkarımın en güçlü yanı, verinin cihazda kalmasıdır. Yine de kullanıcı içeriğini asla arka plana otomatik yüklemeyin ve gerekli olmadıkça loglamayın. Model dosyalarınızı bütünlüğü doğrulanmış bir CDN’den servis edin ve içerik güvenlik politikanızda (Content-Security-Policy) sadece ihtiyaç duyulan kaynaklara izin verin.

Sonuç

ONNX Runtime Web ile WebGPU/WASM arasında otomatik geçiş yaparak, modern tarayıcılarda güçlü bir yapay zeka deneyimi sunmak mümkün. Yukarıdaki basit örnek; görüntü sınıflandırma, metin analizi veya poz tahmini gibi pek çok senaryonun temelini oluşturur. Üretime geçerken model optimizasyonu, önbellekleme ve güvenlik adımlarını uyguladığınızda, native’e yakın bir hız ve akıcılık elde edebilirsiniz.