VerifyBlind iOS SDK'sını (sdk-ios) tüketen örnek uygulama — example-mobile-android'in iOS
karşılığı. SwiftUI, iOS 16+. Cihaz attestation'ı (App Attest) YOKTUR (bilinçli: VerifyBlind'in
zero-knowledge güvenliğinin parçası değil).
- Bundle ID:
com.verifyblind.example(Android örnekle aynı) - Mağaza/görünen ad: VerifyBlind Demo
- SDK:
https://github.com/VerifyBlind/verifyblind-sdk-ios(SwiftPM,from: 2.3.1) - Proje XcodeGen ile üretilir (
project.yml); imzasız derleme + TestFlight CI'da yapılır.
- "VerifyBlind ile Doğrula" → SDK ephemeral RSA keypair üretir, partner backend'den
noncealır. - SDK VerifyBlind uygulamasını Universal Link ile açar (
app.verifyblind.com/request?...). - Kullanıcı doğrulamayı VerifyBlind'de tamamlar; bu demo'ya geri dönünce sonuç poll edilir
(
scenePhase .active), şifreli yanıt lokalde çözülür. - Sonuçtaki
token(enclave'in imzaladığı ham yanıt) partner backend'in doğrulama ucuna (.../api/verify) gönderilir. Sunucu imzayı enclave public key'iyle doğrular, nonce'u bir kez tüketir ve sonucu kendi sorduğu koşula göre okur; ekranda "Sunucu doğruladı" ya da "Sunucu reddetti" görünür. Karar telefonda verilmez.
VerifyBlind, doğrulama bitince (başarı veya iptal) kullanıcıyı bu demo'ya geri getirir:
- SDK'ya geri-dönüş URL'i geçilir:
startAuthentication(..., returnUrl: "verifyblinddemo://callback")(DemoConfig.returnUrl). verifyblinddemoşemasıConfig/Info.plist→CFBundleURLTypesaltında kayıtlıdır.- Aynı şema Partner Portal → Ayarlar → Uygulama Geri-Dönüş Şeması'na (
verifyblinddemo) yazılmalıdır — VerifyBlind yalnızca şeması kayıtlıyla eşleşen return URL'i açar (fail-closed, açık-yönlendirme önlemi).
Bitince VerifyBlind verifyblinddemo://callback?nonce=..&status=success (ya da status=cancelled) açar →
demo öne gelir (onOpenURL / scenePhase .active) ve sonucu poll eder. example-mobile-android ile
aynı şema (tek partner-portal kaydı ikisini de doğrular).
- Her push'ta
buildjob'u (secret'sız) uygulamanın derlendiğini iOS Simulator'da doğrular. testflightjob'u secret'lar eklenince TestFlight'a yükler; eklenmeden önce sessizce atlanır.
Aşağıdakiler olmadan da build job'u çalışır (derleme doğrulanır). TestFlight'a build atmak ve
iPhone'unda denemek için gerekenler:
- https://developer.apple.com/account → Certificates, Identifiers & Profiles → Identifiers → +
- App IDs → App → Continue
- Description:
VerifyBlind Demo, Bundle ID: Explicit →com.verifyblind.example - Capabilities: hiçbirini işaretleme (push/App Attest/associated domains GEREKMEZ)
- Continue → Register
- https://appstoreconnect.apple.com → Apps → + → New App
- Platform: iOS · Name:
VerifyBlind Demo(mağaza adı global benzersiz olmalı; doluysa örn.VerifyBlind Demo TR) · Primary Language: Turkish · Bundle ID:com.verifyblind.example· SKU:verifyblind-demo - Oluştur. App'in "Apple ID" numarasını not al (App Information sayfasında, ~10 haneli) → bu
APP_STORE_APP_ID.
https://github.com/VerifyBlind/example-mobile-ios → Settings → Secrets and variables → Actions → New repository secret.
Aşağıdakilerden yalnızca APP_STORE_APP_ID yeni; gerisi ana iOS uygulamasının (VerifyBlind-iOS)
secret'larıyla birebir aynı değerlerdir (aynı App Store Connect API anahtarı + dağıtım sertifikası):
| Secret | Değer |
|---|---|
APP_STORE_APP_ID |
(2. adımdaki YENİ app'in Apple ID'si) |
APP_STORE_CONNECT_ISSUER_ID |
ana app ile aynı |
APP_STORE_CONNECT_KEY_IDENTIFIER |
ana app ile aynı |
APP_STORE_CONNECT_PRIVATE_KEY |
ana app ile aynı (.p8 içeriği) |
CERTIFICATE_PRIVATE_KEY |
ana app ile aynı |
APPLE_TEAM_ID |
ana app ile aynı (7DYSGPXTNK) |
Sertifika/profil otomatik: CI
app-store-connect fetch-signing-files --createile App ID'yi (yoksa) ve provisioning profile'ı kendisi oluşturur. 1. adımı atlasan bile--createdeneyebilir, ama App Store Connect app kaydı (2. adım) veAPP_STORE_APP_IDzorunludur.
App Store Connect → uygulaman → TestFlight → Internal Testing → kendi Apple ID'ni ekle. Upload sonrası iPhone'da TestFlight uygulamasından build gelir.
SDK, VerifyBlind uygulamasını Universal Link ile açar. Bunun cihazda VerifyBlind app'ini açabilmesi için:
app.verifyblind.com/.well-known/apple-app-site-associationyayında olmalı (<TeamID>.app.verifyblind.ios+/requestpath),- VerifyBlind iOS app'i
applinks:app.verifyblind.comAssociated Domains ile bu linki karşılamalı.
Bunlar yoksa startAuthentication Safari'ye düşer ve akış cihazda tamamlanamaz.
Test ortamı URL'leri Sources/DemoConfig.swift içinde (gizli değil). Kendi partner backend'inle
denemek için partnerBackendURL'i değiştir.
An example app that consumes the VerifyBlind iOS SDK (sdk-ios) — the iOS counterpart of
example-mobile-android. SwiftUI, iOS 16+. No device attestation (App Attest) (intentional: it is
not part of VerifyBlind's zero-knowledge security).
- Bundle ID:
com.verifyblind.example(same as the Android example) - Store / display name: VerifyBlind Demo
- SDK:
https://github.com/VerifyBlind/verifyblind-sdk-ios(SwiftPM,from: 2.3.1) - The project is generated with XcodeGen (
project.yml); an unsigned build + TestFlight happen in CI.
- "Verify with VerifyBlind" → the SDK generates an ephemeral RSA keypair and gets a
noncefrom the partner backend. - The SDK opens the VerifyBlind app via a Universal Link (
app.verifyblind.com/request?...). - The user completes verification in VerifyBlind; back in this demo the result is polled
(
scenePhase .active) and the encrypted response is decrypted locally. - The
tokenin the result (the raw response signed by the enclave) is sent to the partner backend's verify endpoint (.../api/verify). The server checks the signature with the enclave public key, consumes the nonce once and reads the result against the condition it asked; the screen shows "Verified by server" or "Rejected by server". The decision is not made on the phone.
VerifyBlind brings the user back to this demo when the flow ends (success or cancel):
- Pass a return URL to the SDK:
startAuthentication(..., returnUrl: "verifyblinddemo://callback")(DemoConfig.returnUrl). - The
verifyblinddemoscheme is registered underCFBundleURLTypesinConfig/Info.plist. - The same scheme must be set in Partner Portal → Settings → App Return Scheme (
verifyblinddemo) — VerifyBlind only opens a return URL whose scheme matches the registered one (fail-closed, prevents open-redirect).
When done, VerifyBlind opens verifyblinddemo://callback?nonce=..&status=success (or status=cancelled),
foregrounding the demo (onOpenURL / scenePhase .active), which then polls for the result. Uses the
same scheme as example-mobile-android (one partner-portal registration validates both).
- On every push the
buildjob (no secrets) verifies the app compiles on the iOS Simulator. - The
testflightjob uploads to TestFlight once secrets are added; before that it's silently skipped.
The build job runs without the following (compilation is verified). To push a build to TestFlight and
try it on your iPhone you need:
- https://developer.apple.com/account → Certificates, Identifiers & Profiles → Identifiers → +
- App IDs → App → Continue
- Description:
VerifyBlind Demo, Bundle ID: Explicit →com.verifyblind.example - Capabilities: check none (push/App Attest/associated domains NOT required)
- Continue → Register
- https://appstoreconnect.apple.com → Apps → + → New App
- Platform: iOS · Name:
VerifyBlind Demo(the store name must be globally unique; if taken, e.g.VerifyBlind Demo TR) · Primary Language: Turkish · Bundle ID:com.verifyblind.example· SKU:verifyblind-demo - Create it. Note the app's "Apple ID" number (on the App Information page, ~10 digits) → this is
APP_STORE_APP_ID.
https://github.com/VerifyBlind/example-mobile-ios → Settings → Secrets and variables → Actions → New repository secret.
Of the following only APP_STORE_APP_ID is new; the rest are exactly the same values as the main
iOS app's (VerifyBlind-iOS) secrets (same App Store Connect API key + distribution certificate):
| Secret | Value |
|---|---|
APP_STORE_APP_ID |
(the Apple ID of the NEW app from step 2) |
APP_STORE_CONNECT_ISSUER_ID |
same as the main app |
APP_STORE_CONNECT_KEY_IDENTIFIER |
same as the main app |
APP_STORE_CONNECT_PRIVATE_KEY |
same as the main app (.p8 contents) |
CERTIFICATE_PRIVATE_KEY |
same as the main app |
APPLE_TEAM_ID |
same as the main app |
Certificate/profile are automatic: CI creates the App ID (if missing) and the provisioning profile itself via
app-store-connect fetch-signing-files --create. Even if you skip step 1 it may try--create, but the App Store Connect app record (step 2) andAPP_STORE_APP_IDare mandatory.
App Store Connect → your app → TestFlight → Internal Testing → add your own Apple ID. After upload the build arrives in the TestFlight app on your iPhone.
The SDK opens the VerifyBlind app via a Universal Link. For that to open VerifyBlind on the device:
app.verifyblind.com/.well-known/apple-app-site-associationmust be live (<TeamID>.app.verifyblind.ios+ the/requestpath),- the VerifyBlind iOS app must claim this link via the
applinks:app.verifyblind.comAssociated Domains.
Without these, startAuthentication falls back to Safari and the flow cannot complete on the device.
Test environment URLs live in Sources/DemoConfig.swift (not secret). Change partnerBackendURL to try
it with your own partner backend.
Apache License 2.0 — bkz. / see LICENSE.