Risk Assessment (SDK Layer)#
Risk-assessment integrations (BankID and similar) need device-context fields the framework attaches to outgoing HAAPI requests. the Curity Identity Server forwards those fields to the assessment service during flow steps that need them, so the service can require step-up authentication or deny the request based on the device context.
For the concept and security trade-offs, see Risk Assessment .
When to Use Risk Assessment#
Configure risk-assessment integration only when your deployment integrates with a risk-scoring authentication service — BankID is the most common case; the same mechanism applies to other vendors that consume device context.
Most apps do not need this configuration. The field collection adds device-context lookups at startup and per-request payload overhead. Skip it unless your authentication flow runs through an assessment service.
What Gets Collected#
The framework collects four fields once at startup and attaches them to every HAAPI request:
| Field | iOS source | Android source |
|---|---|---|
| Operating system name | UIDevice.current.systemName (returns "iOS" on iPhone and iPad) | always "Android" |
| Operating system version | UIDevice.current.systemVersion (for example, "17.4.1") | Build.VERSION.RELEASE |
| Device model name | UIDevice.current.deviceModelName (see notes below) | Build.MODEL |
| Application identifier | Bundle.main.bundleIdentifier! | applicationContext.packageName |
The Curity SDK forwards these to the Curity Identity Server on every flow request; the server proxies the relevant fields to the configured risk-assessment provider.
Configuration#
Build RiskAssessmentConfiguration on the main thread — typically in AppDelegate.application(_:didFinishLaunchingWithOptions:) — because UIDevice is main-actor-isolated:
let riskAssessmentConfiguration = RiskAssessmentConfiguration(
operatingSystemName: UIDevice.current.systemName,
operatingSystemVersion: UIDevice.current.systemVersion,
deviceModelName: UIDevice.current.deviceModelName,
applicatonIdentifier: Bundle.main.bundleIdentifier!
)
let haapiConfiguration = HaapiConfiguration(
// ...other configuration
riskAssessmentConfiguration: riskAssessmentConfiguration
)operatingSystemName — UIDevice.current.systemName returns the system name string (typically "iOS").
operatingSystemVersion — UIDevice.current.systemVersion returns the major.minor.patch string (for example, "17.4.1").
deviceModelName — UIDevice.current.deviceModelName is not a standard UIDevice property; it is a Curity-recommended extension that resolves the machine identifier (for example, "iPhone15,3") to a human-readable model name (for example, "iPhone 14 Pro Max"). If you don’t have that extension, fall back to UIDevice.current.model, which returns the device class ("iPhone", "iPad") — coarser, but informative for the risk-assessment service.
applicatonIdentifier — the app’s bundle identifier (Bundle.main.bundleIdentifier!). The parameter name is misspelled in the SDK (missing the second i in “application”); type it verbatim to compile. The misspelling is preserved for binary compatibility and may be corrected in a future major release.
Pass the Android applicationContext into the configuration from Application.onCreate. The framework reads the context-derived fields internally:
class ClientApplication : Application() {
lateinit var haapiConfiguration: HaapiConfiguration
override fun onCreate() {
super.onCreate()
haapiConfiguration = HaapiConfiguration(
// ...other configuration
applicationContext = applicationContext
)
}
}Internally, the framework reads:
- OS name — always
"Android". - OS version —
Build.VERSION.RELEASE(for example,"14"). - Device model —
Build.MODEL(for example,"Pixel 7"). - Application identifier —
applicationContext.packageName(for example,"com.example.client.app").
The Android API is intentionally narrower than the iOS surface because all four fields are obtainable from the standard Android Context without main-thread restrictions; explicitly passing each one would add no information.
Toggle risk assessment via a single boolean per platform — useRiskAssessmentConfiguration: true — on createIOSConfiguration / createAndroidConfiguration. The native bridge handles the field collection internally using the same UIDevice / Build lookups documented above.
import {
createIOSConfiguration,
createAndroidConfiguration,
noAuthentication,
} from 'identityserver.haapi.reactnative.sdk'
const iosConfig = createIOSConfiguration({
clientId: 'haapi-ios-client',
appRedirect: 'app://haapi',
clientAuthenticationMethodConfiguration: noAuthentication(),
useRiskAssessmentConfiguration: true,
})
const androidConfig = createAndroidConfiguration({
clientId: 'haapi-android-client',
appRedirect: 'app://haapi',
clientAuthenticationMethodConfig: noAuthentication(),
useRiskAssessmentConfiguration: true,
})When the flag is true, the native side constructs a RiskAssessmentConfiguration (iOS) or wires applicationContext into the Android configuration. The host JS side has nothing else to configure — there is no JS-facing field selection.
Server-Side Prerequisites#
For the SDK’s device-context fields to reach a risk-assessment service, the server must be set up:
- the Curity Identity Server version 9.7.0 or later — earlier versions do not support the risk-assessment forwarding protocol.
- A configured risk-assessment integration at the Curity profile level — BankID’s risk-assessment functionality, or another vendor’s equivalent. The integration carries the upstream risk-service URL, threshold settings, and auth-step bindings.
- An authentication flow that includes a risk-assessment step. Risk assessment fires only at specific points in the flow (typically before high-value steps); flows without those steps do not invoke it even when the client-side fields are configured.
Refer to the official BankID Relying Party Guidelines for version 6 for the upstream service requirements and acceptance criteria.
On Android, set android:allowBackup="true" (the default) in AndroidManifest.xml so the persisted device context survives backup-and-restore. Without it, fresh installs after factory reset or device migration lose context history that some risk-assessment integrations rely on for continuity.
How to implement this: Risk Assessment (concept) · How to Integrate Risk Assessment · Risk Assessment (Driver Layer)