Skip to main content

iOS

Prerequisites

Passkeys

Passkeys are supported only on iOS 15 and above and synced via iCloud Keychain. Autofill requires iOS 16 and above.

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:

Installation

Cocoapods

Add Authsignal to your Podfile:

pod 'Authsignal', '~> 0.2.0'

Swift Package Manager

Add authsignal-ios to the dependencies value of your Package.swift.

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

Initialization

import Authsignal
...

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

You can find your client or tenant ID in the Authsignal Portal.

You must specify the correct base URL for your tenant's 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

Passkeys

Registering a new passkey

To register a new passkey, you first need to request a token via track. If the user is new, create a record for them in your own DB and pass their ID to Authsignal server-side to get a token, which can then be passed to the iOS SDK along with their username.

let result = await authsignal.passkey.signUp(token: initialToken, userName: userName)

if let error = result.error {
print(error)
} else if let resultToken = result.data {
// Pass this short-lived result token to your backend to validate that passkey registration succeeded
}

Authenticating with an existing passkey

To handle re-authenticating when the username is captured, lookup the user by their username in your backend and then pass their ID to track to get a token, which can then be passed to the iOS SDK.

let result = await authsignal.passkey.signIn(token: initialToken)

if let error = result.error {
print(error)
} else if let resultToken = result.data {
// Pass this short-lived result token to your backend to validate that passkey authentication succeeded
}

After the user authenticates with their passkey, the SDK will return a short-lived token which should be passed to your backend to validate the result of the challenge server-side.

Using passkey autofill

You can also initiate a passkey challenge in cases where the username isn't known yet - for example when using passkey autofill.

let result = await authsignal.passkey.signIn(autofill: true)

The result token will resolve once the user focuses the autofill text input, selects their passkey and completes the challenge.

For more detail on passkey autofill see Apple's documentation.

Cancelling a passkey challenge

If a passkey challenge has been initiated and is in a pending state, for example to support autofill, it can be cancelled at any time. This should be done before navigating away from the screen containing the autofill textfield or before performing a new passkey challenge.

authsignal.passkey.cancel()

Push

Adding a device credential

Adding a new credential must be authorized with a short-lived token. You can obtain this by calling the track endpoint on the Server API which will return a token in the response. This should be done at a point in your application when the user is strongly authenticated.

await authsignal.push.addCredential(token: token)

Removing a device credential

await authsignal.push.removeCredential()

Getting a challenge

let challengeId = await authsignal.push.getChallenge()

Updating a challenge

let approved: Bool = true // true if the user has approved the challenge

await authsignal.push.updateChallenge(challengeID: challengeId, approved: approved)