Guardian.swift iOS SDK

Guardian.swift allows you to integrate Auth0's Guardian multi-factor service in your own iOS app, transforming it into the second factor itself. Your users will get all the benefits of our frictionless multi-factor authentication from your app. To learn more, read Getting Started with Apple Push Notification Service.

Requirements

  • iOS 10+ and Swift 4.1 is required in order to use Guardian.

  • To use this SDK you have to configure your tenant's Guardian service with your own push notification credentials, otherwise, you would not receive any push notifications. To learn more, read Configure Push Notifications for MFA.

Install Guardian iOS SDK

CocoaPods

Guardian.swift is available through CocoaPods. To install it, add the following line to your Podfile:

pod 'Guardian', '~> 1.1.0'

Was this helpful?

/

Carthage

Add this line to your Cartfile:

github "auth0/Guardian.swift" ~> 1.1.0

Was this helpful?

/

Enable Guardian push notifications

  1. Go to Dashboard > Security > Multi-factor Auth.

    Auth0 Dashboard Security Multi-Factor Authentication
  2. Toggle Push Notification on to enable it.

  3. Configure push notifications.

Usage

Guardian is the core of the SDK. To use the SDK, import the library:

import Guardian

Was this helpful?

/

Set the domain for your tenant. Or, use the custom domain if you configured one for your tenant:

let domain = "{yourDomain}/appliance-mfa"

Was this helpful?

/

Enroll

An enrollment is a link between the second factor and an Auth0 account. When an account is enrolled you'll need it to provide the second factor required to verify the identity. If your app is not yet using push notifications or you're not familiar with it, see Apple Push Notification Service Overview for details.

For an enrollment you need the following information, besides your Guardian domain:

Variable Description
Enrollment URI Value encoded in the QR code scanned from Guardian Web Widget or your enrollment ticket sent to you in email or SMS.
APNS Token Apple APNS token for the device. It must be a string containing the 64 bytes (in hexidecimal format).
Key Pair An RSA (private/public) key pair used to assert your identity with Auth0 Guardian.

After you have the information, you can enroll your device:

Guardian
        .enroll(forDomain: "{yourGuardianDomain}",
                usingUri: "{enrollmentUri}",
                notificationToken: "{apnsToken}",
                signingKey: signingKey,
                verificationKey: verificationKey
                )
        .start { result in
            switch result {
            case .success(let enrolledDevice):
                // success, we have the enrollment device data available
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

Was this helpful?

/

On success you'll obtain the enrollment information, that should be secured stored in your application. This information includes the enrollment identifier, and the token for Guardian API associated to your device for updating or deleting your enrollment.

Signing and verification keys

Guardian.swift provides a convenience class to generate a signing key:

let signingKey = try DataRSAPrivateKey.new()

Was this helpful?

/

This key only exists in memory but you can obtain its Data representation and store securely in, for example, an encrypted SQLiteDB:

// Store data
let data = signingKey.data
// perform the storage

// Load from Storage
let loadedKey = try DataRSAPrivateKey(data: data)

Was this helpful?

/

But if you just want to store inside iOS Keychain:

let signingKey = try KeychainRSAPrivateKey.new(with: "com.myapp.mytag")

Was this helpful?

/

The above example creates a key and stores it automatically under the supplied tag. If you want to retrieve it, you can use the tag:

let signingKey = try KeychainRSAPrivateKey(tag: "com.myapp.mytag")

Was this helpful?

/

For the verification key, we can just obtain it from any SigningKey, for example:

let verificationKey = try signingKey.verificationKey()

Was this helpful?

/

Allow login requests

Once you have the enrollment in place, you will receive a push notification every time the user has to validate their identity with MFA. Guardian provides a method to parse the data received from APNs and return a Notification instance ready to be used.

if let notification = Guardian.notification(from: notificationPayload) {
    // we have received a Guardian push notification
}

Was this helpful?

/

Once you have the notification instance, you can easily allow the authentication request by using the allow method. You'll also need some information from the enrolled device that you obtained previously. In case you have more than one enrollment, you'll have to find the one that has the same id as the notification (the enrollmentId property).

When you have the information, device parameter is anything that implements the protocol AuthenticatedDevice:

struct Authenticator: Guardian.AuthenticationDevice {
    let signingKey: SigningKey
    let localIdentifier: String
}

Was this helpful?

/

Local identifier is the local id of the device, by default on enroll UIDevice.current.identifierForVendor. Then just call:

Guardian
        .authentication(forDomain: "{yourGuardianDomain}", device: device)
        .allow(notification: notification)
        .start { result in
            switch result {
            case .success:
                // the auth request was successfuly allowed
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

Was this helpful?

/

Reject login requests

To deny an authentication request call reject instead. You can also send an optional reject reason. The reject reason will appear in the Guardian logs.

Guardian
        .authentication(forDomain: "{yourGuardianDomain}", device: device)
        .reject(notification: notification)
        // or reject(notification: notification, withReason: "hacked")
        .start { result in
            switch result {
            case .success:
                // the auth request was successfuly rejected
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

Was this helpful?

/

Unenroll

If you want to delete an enrollment, for example, if you want to disable MFA, you can make the following request:

Guardian
        .api(forDomain: "{yourGuardianDomain}")
        .device(forEnrollmentId: "{userEnrollmentId}", token: "{enrollmentDeviceToken}")
        .delete()
        .start { result in
            switch result {
            case .success:
                // success, the enrollment was deleted
            case .failure(let cause):
                // something failed, check cause to see what went wrong
            }
        }

Was this helpful?

/