Skip to content
Last updated

Device binding

This guide explains the device binding feature, including the key concepts and endpoints required to implement it. Device binding is mandatory for all secure flows, such as those requiring a Qualified Electronic Signature (QES) or two-factor authentication (e.g., BankIdentPlus).

Overview

The device binding API allows customers to register their devices and create public/private key pairs for authenticating Multi-Factor Authentication (MFA) challenges.

Device binding is a prerequisite for Strong Customer Authentication (SCA). It ensures that a request originates from a trusted, registered device.

Once a customer binds their device, they receive authentication challenges that they must confirm using that device (e.g., logging in, changing data, authorizing transactions).

Restricted vs. Unrestricted keys

Customers authorize actions using one of two key types:

  • Unrestricted keys: Do not require specific user authentication to sign a request. These are typically used for background processes or low-risk actions.
  • Restricted keys: Require user authentication via biometrics (e.g., Touch ID, Face ID) to access the private key.
    • iOS: Combine privateKeyUsageflag with userPresence or touchIDAny.
    • Android: Use setUserAuthenticationParameters().

See the Strong customer authentication guide for the full list of use cases requiring restricted vs. unrestricted keys.

Security requirements

Your implementation must meet the following security standards:

  • Limit: Maximum of five registered devices per customer.
  • OS: Android 8.0+ or iOS 12+.
  • Hardware: Must support hardware-backed security via separate execution environments (e.g., Secure Enclave in iOS, TEE in Android).
  • Access Control: Your app must enforce a device passcode or biometric lock.
  • Storage: You must store personalized security credentials and cryptographic keys in the secure environment.

Integration flow

The following diagram illustrates the device binding process.

CustomerYour FrontendSolaris APIPhase 1: Initial Device Bindingalt[Signature Valid][Signature Invalid]Phase 2: Add New Keys (Optional)Use existing bound devicealt[Signature Valid][Signature Invalid]Enter device details1Generate Unrestricted Key Pair (ECDSA-P256)2POST /mfa/devices (Public Key & Device Info)3Create Unverified Device ID4Send SMS OTP5Return Challenge ID6Enter OTP7Sign OTP with Private Key8PUT /mfa/challenges/signatures (Signature)9204 Success (Device Registered)10400 Error (Binding Failed)11Generate new Restricted/Unrestricted Key Pair12Sign new Public Key with EXISTING Private Key13POST /mfa/devices/{id}/keys (New Key + Signature)14Verify Signature with stored Public Key15201 Created (New Key Registered)16400 Error (Process Failed)17CustomerYour FrontendSolaris API

Integration steps

  1. Initiation: The customer enters device information in your app.
  2. Key Generation: Your app generates a private/public key pair in ecdsa-p256 format.
  3. Submission: Send the public key (hex-encoded) and device info to Solaris via POST Create device.
  4. Challenge: Solaris temporarily stores the key and triggers a verification flow:
    • Solaris sends a 6-digit OTP via SMS to the customer.
    • Solaris returns a signature challenge object to your app.
  5. Input: The customer enters the SMS OTP in your app.
  6. Signing: Your app creates a signature using the OTP and the Private Key.
  7. Verification: Send the signature to Solaris via PUT Verify the signature.
  8. Completion: If valid, Solaris registers the device.

Step 1: Create a device

Collect the device information and generate a private/public key pair (ecdsa-p256) on the device.

POST Create device

This endpoint creates a device attachment request.

Required attributes:

  • person_id: The customer's unique ID.
  • key_type: Must be ecdsa-p256.
  • key: The Hex-encoded public key.
  • key_purpose: restricted or unrestricted.
  • name: The device model name (e.g., "Samsung Galaxy S10").
  • challenge_type: Verification method (default: sms).

Request URL

POST /v1/mfa/devices

Response example

Solaris creates a temporary, unverified device and returns a challenge object. The challenge expires in 5 minutes.

{
    "id": "device_id_123",
    "key_id": "key_id_456",
    "challenge":
    {
        "id": "challenge_id_789",
        "type": "signature",
        "created_at": "2019-08-21T12:16:17Z",
        "expires_at": "2019-08-21T12:21:17Z"
    }
}

GET Retrieve signature challenge

If you need to retrieve the challenge details again (e.g., if the app crashed):

GET /v1/mfa/challenges/signatures/{signature_id}

Manage devices


Step 2: Verify the signature

The customer enters the 6-digit SMS OTP into your app. You must use this OTP and the stored Private Key to create a cryptographic signature.

How to create the signature

Perform these cryptographic operations in your app:

  1. Hash: Create a SHA256 hash of the OTP.
  2. Sign: Sign the hash using the Private Key.
  3. Encode (ASN.1): Encode the signature in ASN.1 format.
  4. Encode (Hex): Convert the ASN.1 signature to a Hex string.
  5. Send: Submit the hex string in the API request.

PUT Verify the signature

Submit the calculated signature to finalize the binding.

Request URL

PUT /v1/mfa/challenges/signatures/{id}

Response example

Returns 204 No Content on success.

HTTP/1.1 204 Challenge successful

Step 3: Create additional keys (Optional)

After successful binding, you can add more keys (restricted or unrestricted) to the same device. This is useful if you want to separate keys for different permission levels.

POST Add new key to device

To add a new key, you must sign the request using the existing verified private key.

How to sign the request:

Calculated as: signature = registered_private_key.sign(hashSHA256(new_public_key))

  1. Generate the new key pair.
  2. Hash the new public key (SHA256).
  3. Sign that hash using the previously registered private key.

Request attributes:

AttributeTypeDescription
keystringThe new hex-encoded public key.
key_typestringecdsa-p256
key_purposestringrestricted or unrestricted
device_signatureobjectContainer for the signature data.
signature_key_purposestringPurpose of the existing key used for signing (restricted or unrestricted).
signaturestringThe calculated signature (see formula above).

Request URL

POST /mfa/devices/{id}/keys

Example response

HTTP/1.1 201 Created
{
  "id": "20f892fdc6414320b5b1df612f833edb"
}

Manage device keys