Requirements

Passkeys are supported only on iOS 15 and above. Passkey autofill requires iOS 16 and above.

Installation

Cocoapods

Add Authsignal to your Podfile.

pod 'Authsignal', '~> 1.0.10'

Swift Package Manager

Add the following to the dependencies value of your Package.swift file.

dependencies: [
    .package(
        url: "https://github.com/authsignal/authsignal-ios.git",
        from: "1.0.10"
    )
]

Initialization

Initialize the client with your tenant ID and the base URL for your region.

RegionBase URL
US (Oregon)https://api.authsignal.com/v1
AU (Sydney)https://au.api.authsignal.com/v1
EU (Dublin)https://eu.api.authsignal.com/v1

You can find your tenant ID in the Authsignal Portal.

import Authsignal

let authsignal = Authsignal(
    tenantID: "YOUR_TENANT_ID",
    baseURL: "YOUR_REGION_BASE_URL"
)

Passkeys

Prerequisites

After you have configured your Relying Party you should follow the steps below.

To use passkeys you must first setup an associated domain with the webcredentials service type.

1

Host an apple-app-site-association file on the domain that matches your relying party:

GET https://<yourrelyingparty>/.well-known/apple-app-site-association
2

The response JSON should look something like this:

{
   "applinks": {},
   "webcredentials": {
      "apps": ["ABCDE12345.com.example.app"]
   },
   "appclips": {}
}

where ABCDE12345 is your team id and com.example.app is your bundle identifier.

3

In XCode under “Signing & Capabilities” add a webcredentials entry for your domain / relying party e.g. example.com:

Creating a passkey

Creating a passkey must be authorized with a short-lived token. You can obtain a token by tracking an action from your backend.

Using a passkey

Passkey autofill (iOS)

This feature requires rendering a text field with the textContentType property.

Then when the screen loads, you should initialize the text field for passkey autofill by running the following code.

Cancelling an autofill request (iOS)

Push

Adding a credential

Adding a new credential must be authorized with a short-lived token. You can obtain a token by tracking an action from your backend in an authenticated context.

Removing a credential

Getting a challenge

Updating a challenge

After presenting the user with a prompt to approve or reject the request, you should update the challenge with their response.

Requiring user authentication (Android)

When adding a credential, it is possible to require that the user authenticate whenever they subsequently access the credential (i.e. when approving or rejecting a push challenge).

authsignalPush.addCredential(
    token = token,
    userAuthenticationRequired = true
)

It’s also possible to specify additional user authentication parameters.

authsignalPush.addCredential(
    token = token,
    userAuthenticationRequired = true,
    timeout = 60,
    authorizationType = 0
)

The timeout param determines the time (in seconds) that the credential can be accessed after authenticating - or 0 if authentication must occur for every credential use. The authorizationType param determines if authentication is required via biometrics and/or device credential (e.g. pin).

If user authentication is required for a credential, you must call updateChallenge in a biometric prompt authentication callback.

  1. Initialize a signature before displaying the biometric prompt
val signature = authsignalPush.startSigning()

val cryptoObject = CryptoObject(signature)

// Initialize biometric prompt and prompt info
val biometricPrompt = ...
val promptInfo = ...

biometricPrompt.authenticate(promptInfo, cryptoObject);
  1. Retrieve the signature from the crypto object in your prompt’s authentication callback
override fun onAuthenticationSucceeded(result: AuthenticationResult) {
    super.onAuthenticationSucceeded(result)

    val cryptoObject = result.cryptoObject
    val signer = cryptoObject.signature

    authsignalPush.updateChallenge(
        challengeId = challengeId,
        approved = true,
        signer = signer
    )
}

Email OTP

Enroll email

Start enrollment for a new email OTP authenticator by sending the user an email containing an OTP code.

This method is typically used when you’ve not yet verified the user’s email address.

Challenge email

Start re-authentication for an existing email OTP authenticator by sending the user an email containing an OTP code.

This method is typically used when you’ve already verified the user’s email address.

Verify email

Finish enrolling or re-authenticating a new or existing email OTP authenticator by verifying the code submitted by the user.

SMS OTP

Enroll SMS

Start enrollment for a new SMS OTP authenticator by sending the user an SMS containing an OTP code.

This method is typically used when you’ve not yet verified the user’s phone number.

Challenge SMS

Start re-authentication for an existing SMS OTP authenticator by sending the user an SMS containing an OTP code.

This method is typically used when you’ve already verified the user’s phone number.

Verify SMS

Finish enrolling or re-authenticating a new or existing SMS OTP authenticator by verifying the code submitted by the user.

Authenticator app (TOTP)

Enroll TOTP

Start enrollment for a new TOTP authenticator by generating a QR code to display to the user.

Verify TOTP

Finish enrolling or re-authenticating an TOTP authenticator by verifying the code submitted by the user.

Authenticator binding

To ensure a strong binding between authenticators, the mobile SDK supports two different ways of adding new authentication methods.

Presenting a challenge with an existing method

With this option, you can present a challenge with an existing method (e.g. passkey) in order to enroll a user in a new method (e.g. authenticator app) within a limited time window (10 minutes by default).

Tracking an action to generate a token

Alternatively, you can track an action on your backend to generate a time-limited token (valid for 10 minutes by default) and use this token to authorize adding the new authenticator.

If this is not the user’s first authenticator, you must specify the scope add:authenticators when generating the token.

In your backend, generate a token using a Server SDK or the Server API.

You should only generate a token with the add:authenticators scope from a context where the user is strongly authenticated. This will ensure a strong binding between different authentication methods.

Then pass the token from your backend to the mobile SDK. You can pass the token directly to the relevant method when creating a passkey or adding a push credential or else you can use the setToken method.