Advanced Topics

Device Recovery

On occasion your end-user's may be in situation where they need to re-enroll a new device. Consider the following scenarios:

  • The user lost their mobile phone and had to replace it
  • The user has deleted your mobile application and later decided to reinstall it
  • The user still has access to their old mobile phone but would like to use your app on a new device

In all of the above scenarios the end-user has lost critical security factors that are not recoverable because they reside on the device itself. These factors include local authentication factors (like TouchID and FaceID) as well as special Pinn key-pairs that prove to your system the user is on an authentic device.

To address this problem Pinn allows for you to create a custom device recovery workflow that leverages Pinn's palm authentication to allow users to perform device recovery in a self-service fashion.

!

Note

We specifically call this "Device Recovery" because your users will still have their left_palm and right_palm data enrolled, even after their device is lost.

User Identification

In order for Pinn to help you securely recovery the users phone as a secure device attached to that user, you must first identify the user that is trying recovery their account. This can be done in many different ways and you should carefully consider this step based on your app's design.

Email Identification

The user may enter their own email address, at which point the user is making a claim that they are a given user in your system. For increased security you may at this time want to send a "Verification Email" to your user so they can prove ownership of the address prior to Pinn device recovery (this is optional).

Username Identification

Another common identifier you may have for a user is a unique username. Your user can supply this as a way to identify their account to your backend. If your user has a password in your system you can also enforce that this is provided to add additional security to your recovery process.

Phone Number Identification

Many mobile applications now rely heavily on mobile numbers as a unique identifier for the user. The user can supply this to identify themselves to your backend. Optionally for additional security here you may want to consider SMS/Call 2FA as a means for your backend to prove the user owns that number prior to Pinn device recovery.

Basic Example Workflow

  1. User loses their device and purchases a new one
  2. User downloads your mobile application from the App Store or Play Store
  3. User attempts to "Sign in" on the new device
  4. User enters their email address to identify the account they would like to recover for your system
  5. You app backend looks up the user and creates a Pinn Recovery Key for the user, this will enforce that they must perform palm authentication prior to enrolling a new device.
  6. The user performs palm authentication successfully
  7. Users new device is automatically enrolled, and the user now has full access again

Advanced Example Workflow

  1. User loses their device and purchases a new one
  2. User downloads your mobile application from the App Store or Play Store
  3. User attempts to "Sign in" on the new device
  4. User enters their mobile number
  5. Your app backend sends them an SMS verification code text
  6. User enters the verification code in your app
  7. You app then creates a Recovery Key for the user
  8. User performs palm authentication successfully
  9. Users new device is automatically enrolled, and the user now has full access again

!

Important

Your application can require and enforce any number of steps as additional security prior to Pinn palm authentication. It is critical that you perform these steps prior to creating a Recovery Key for the user. The recovery key should only be created by your backend once the user has performed the required steps by your system.

Special Considerations

Pinn palm authentication cannot be leveraged in cases where your end user never enrolled their palms before. There are two common solutions to this scenario.

A. Enforce users to enroll their palm at registration time If your application ensures all users have their palm enrolled before using your services, your system will have a guarantee that all users trying to recovery will be able to do so with their palm.

B. Provide a fallback for users that opted out of or never enrolled their palm data When a user comes back to your app on a new device and their palm was not enrolled, they will need a workaround in order to re-register the new device. You may consider doing a combination of techniques in this scenario, for example both email and SMS based verification, this implementation is up to you and depends primarily on your security needs.

Recovery Key Basics

The concept of recovery keys is highly related to enrollment keys. As a review, enrollment keys are returned to your iOS or Android app as a way for you backend to bridge trust, which then in turn allows your user to enroll their device. Recovery keys can be thought of as a "promise" for your users device to receive an enrollment key after they have verified their palm biometrics with Pinn. Under the hood these steps can be boiled down like this:

  1. Your backend returns a Recovery Key instead of an Enrollment Key for an existing user that wants to recover a new device
  2. Your app, via the iOS/Android SDK will receive this recovery key and perform the necessary Pinn recovery steps (e.g. user verifies their left and right palm)
  3. Once the biometrics are verified, your app will automatically receive an enrollment key afterwards and use it to enroll the new device
  4. User has gained access on the new device

Most of this complexity is abstracted by our SDKs and REST API, however your backend is responsible for producing a Recovery Key when it is required.

Recovery Key Integration

Before attempting the following you should already have device and palm enrollment completely functional, after that you can make some minor changes to your backend to allow for device recovery.

As of right now your /enrollment_keys endpoint should look something like this (in your chosen backend language).

import requests

@app.route('/enrollment_keys', methods=['POST'])
@login_required
def enrollment_keys():
	r = requests.post('https://pinnapis.com/v1/enrollment_keys',
			  json={'user_id': current_user.pinn_user_id},
			  headers={'Authorization': 'Bearer <your_secret_key>'})
	if r.ok:
            return jsonify(r.json())
	else:
	    # Handle error
        

In this context, an enrollment key is given to any user that has registered an account, thus allowing them to enroll their device right after account registration. Note that in the context of this application login_required is a function that ensures the user has been identified (and partially authenticated) to the system. This could be done via username/password, SMS verification, email verification or just the user simply providing a unique identifier. We are going to modify this example to return a Recovery Key if we detect that the user is trying to gain access on a new device.

import requests

@app.route('/enrollment_keys', methods=['POST'])
@login_required
def enrollment_keys():
    if current_user.pinn_user.left_palm_enrolled and current_user.pinn_user.right_palm_enrolled:
        r = requests.post('https://pinnapis.com/v1/recovery_keys',
		          json={'user_id': current_user.pinn_user_id, 'flow': ['left_palm', 'right_palm']},
		          headers={'Authorization': 'Bearer <your_secret_key>'})
    else:
        r = requests.post('https://pinnapis.com/v1/enrollment_keys',
		          json={'user_id': current_user.pinn_user_id},
		          headers={'Authorization': 'Bearer <your_secret_key>'})
    return jsonify(r.json())
        

We have now changed the logic, if we detect that the user has their palm data enrolled we will instead provide a recovery flow to the user before they can enroll their new device. This logic is just an example, but your app can provide any number of security checks prior to the Pinn recovery flow.

Let's take a look at one more example, in this scenario the app is checking to make sure the user verified their email prior to recovery or enrollment being possible. We have omitted the details for email verification and are assuming the backend in here saved the state in a user session.

import requests
from flask import session

@app.route('/enrollment_keys', methods=['POST'])
def enrollment_keys():
    if 'email_verified' in session:
        if current_user.pinn_user.left_palm_enrolled and current_user.pinn_user.right_palm_enrolled:
            r = requests.post('https://pinnapis.com/v1/recovery_keys',
	   	              json={'user_id': current_user.pinn_user_id, 'flow': ['left_palm', 'right_palm']},
		              headers={'Authorization': 'Bearer <your_secret_key>'})
        else:
            r = requests.post('https://pinnapis.com/v1/enrollment_keys',
		              json={'user_id': current_user.pinn_user_id},
		              headers={'Authorization': 'Bearer <your_secret_key>'})
    if r.ok:
        return jsonify(r.json())
    else:
	# Handle error
        

In this example we removed the login_required method, and instead added a check to see if the user verified their email address in the context of the current session between your app and backend. This would be a step prior to enrollment that your app and backend would implement.

?

Questions?

We are here to help! Contact us with any development related questions at dev@pinn.ai and we'll reach back in a timely manner.