This page describes security considerations for integrating the Incode iOS SDK.
End-to-End Encryption (E2EE)
End-to-end encryption (E2EE) adds an extra layer of security by encrypting the data transmitted between the server and the client. The process begins with a key exchange: the client and server share keys for encrypting and decrypting messages. This exchange ensures all later communications are encrypted, so only the intended server and client can decrypt the messages.
For E2EE, the SDK uses Apple's native cryptography (CryptoKit) instead of OpenSSL:
- RSA-OAEP with SHA-256 asymmetric encryption for the secure key exchange.
- AES-GCM symmetric encryption (CryptoKit) for securing server requests and responses. AES stands for Advanced Encryption Standard.
Enable End-to-End Encryption
Complete the following steps in order.
Initialize the SDK with a Custom E2EE Server
Provide your dedicated E2EE endpoint through the e2eeURL parameter when you initialize the SDK:
IncdOnboardingManager.shared.initIncdOnboarding(
url: "<YOUR_API_URL>",
e2eeURL: "<YOUR_E2EE_URL>",
apiKey: "<YOUR_API_KEY>"
) { success, error in
if let error = error {
print("Incode init failed: \(error.description)")
return
}
// SDK is ready.
}
Enable E2EE on the Session Configuration
Turn on E2EE when building your IncdOnboardingSessionConfiguration:
let session = IncdOnboardingSessionConfiguration(
token: "<SESSION_TOKEN>",
e2eEncryptionEnabled: true
)
Start the Flow
Pass the session configuration to your chosen start method, depending on your integration approach:
startFlow(sessionConfig:delegate:moduleId:)runs the server-defined Dashboard flow directly from the session configuration.setupOnboardingSession(sessionConfig:completion:)creates the session without starting modules. This is useful when running SDK-defined sections.startOnboardingis a separate method for defining a flow in code rather than using a server-defined Dashboard flow. It requires anIncdOnboardingFlowConfigurationdescribing the steps to run. It is not interchangeable withstartFlow.
IncdOnboardingManager.shared.startFlow(sessionConfig: session, delegate: self)
See Configure Flows Locally and Run End to End for running a flow end to end and Integration Approaches for building a flow in code.
Electronic Signatures: AES and QES
The iOS SDK supports the Advanced Electronic Signature (AES) and Qualified Electronic Signature (QES) modules.
NFC
The NFC document reader uses AES/3DES (DESede) secure messaging to read passport and other electronic ID chips, matching standard BAC/PACE/Chip Authentication per ICAO 9303. Single DES is used only as an internal component of the ISO/IEC 9797-1 Retail MAC used by the 3DES suite, not as a standalone cipher.
Jailbreak Detection
The SDK performs device-integrity checks to detect jailbroken or otherwise tampered devices. These checks feed into isSDKEntierlyInitialized (the "Entierly" spelling is the real, shipping property name). That property returns a tuple (flag: Bool, error: IncdError?). When integrity is compromised, it returns flag == false with error set to the IncdError.integrityCompromised case.
As of iOS SDK 5.45.0, the public disableJailbreakDetection flag is removed and the check cannot be disabled.
Screen and Session Recording
When a flow is configured to record the session, such as for audit or regulatory purposes, the SDK manages screen recording internally and gates it on permission. Control session recording through the flow and session configuration (recordSession, mergeSessionRecordings).
SSL Pinning
IncdOnboardingManager.shared.configureSSLPinning(enabled: true, forced: true)
Both parameters are optional (Bool?); pass nil for either to leave its current value unchanged. A pinning failure surfaces as an IncdError.sslPinningFailed error and triggers an onSSLPinningFailed() delegate callback.
Diagnostics
sendDiagnosticsData controls whether the SDK reports diagnostics. It defaults to true. When it is false, no diagnostics are collected or delivered. When it is enabled, running in Capture-Only mode delivers the diagnostics data to your app via onDiagnosticsDataReceived(_:).