Login with PIN

PIN authentication lets users authenticate using a PIN code defined on their device. This PIN unlocks a locally stored encrypted seed, from which a secure key pair is derived on demand. The private key is used to sign authentication challenges, while the PIN and private key never leave the device. This ensures a user-friendly yet secure experience based on strong cryptography. For more about the PIN authenticator's settings for behavior and lockout policies, see our Manage authenticators page.

Note

This guide explains how to implement authentication with PIN codes using Journeys and mobile Orchestration SDKs. To learn more about SDKs integration, see Orchestration quickstart (Android) and Orchestration quickstart (iOS).

How it works

Mobile PIN authentication is based on asymmetric cryptography. When the user registers a PIN, the Authentication SDK generates a random secret seed, which is encrypted using the PIN and securely stored on the device. The PIN itself is never stored, and the private key is never persisted — it only exists in memory when needed.

PIN registration

During registration, the Orchestration SDK receives a registerPinCode step from Mosaic and exposes it to the app. The app prompts the user to enter a PIN and then calls the Authentication SDK, which encrypts the seed and derives a public/private key pair. The public key and its identifier are returned to the app, which submits them to Mosaic via the Orchestration SDK.

Mosaic then returns a PinCodeRegistrationCommit instruction to finalize the process. The Orchestration SDK exposes this instruction to the app, which must call commitPinCodeRegistration() using the Authentication SDK. This marks the key as ready for use in authentication.

UserClient AppOrchestration SDKMosaic ServerAuthentication SDKLaunch appStart registration journeyRequest journeyReturn registerPinCode stepExpose registerPinCode stepPrompt for PINEnter PINCall registerPinCode(PIN)Return public key, key IDSubmit public key, key IDSubmit resultReturn PinCodeRegistrationCommit instructionExpose commit instructionCall commitPinCodeRegistration()Return successConfirm registrationUserClient AppOrchestration SDKMosaic ServerAuthentication SDK

PIN authentication

During authentication, the Orchestration SDK receives a authenticatePinCode step from Mosaic and exposes it to the app. The app collects the user's PIN and invokes the Authentication SDK, which decrypts the seed, derives the key pair on demand, and signs a challenge received from Mosaic. The signed result is sent back through the Orchestration SDK to Mosaic, where it is verified using the public key.

UserClient AppAuthentication SDKOrchestration SDKMosaic ServerLaunch appStart authentication journeyRequest journeyReturn authenticatePinCode stepExpose authenticatePinCode stepPrompt for PINEnter PINCall authenticatePinCode(PIN)Return signed challengeSubmit signed challengeSubmit resultAuthentication successfulNotify successLogged inUserClient AppAuthentication SDKOrchestration SDKMosaic Server

Requirements

iOS

iOS

  • iOS 13+
  • Xcode 11+
Android

Android

  • Android 5+ (API level 21+)

Before you start

Before you start, make sure you have a Mosaic application with an OIDC client. See create an application.

For a user to register a PIN, they must already exist in your app and verify their identity before registration. This authentication can be performed using any supported method (e.g., password, OTP, document verification), either within the same journey or in a prior one.

Step 1: Configure PIN authenticator

Admin Portal

Mobile PIN authentication lets users log in to their app using a PIN code that they choose specifically for the app. The PIN format and complexity (e.g., 4 or 6 digits) are defined by your application and must be enforced in the frontend.

The PIN authentication settings (Admin Portal > B2C Identity or B2B Identity > Authentication methods ) allow you to configure the lockout policy in case of repeated failed attempts:

  • Failed attempts : set the number of incorrect PIN entries allowed before triggering a lockout.
  • Lockout duration : define how long the user must wait before they can try again.
Tip

Once you've configured the lockout policy, you may also implement logic to unlock the PIN authenticator in case it locks. Use the Unlock authenticators API to reset a locked PIN code.

For more about the PIN authenticator, see Customize login methods.

Step 2: Create journeys

Admin Portal

In the Admin Portal, go to B2C Identity or B2B Identity based on your setup, and open the Journeys section. Create two separate journeys—one for PIN registration and one for PIN authentication. You can name them as you like, for example register-pin-journey, login-with-pin-journey.

PIN registration journey

After adding the following steps to your journey:

  1. Login form
  2. Authenticate with password
  3. Register Mobile PIN

Configure them as follows:

Login form

Configure this step to display a form that collects a password. Basic configuration for our example includes:

  • Authentication methods : Enable only Password .
  • Step ID : Provide a unique identifier, e.g., loginForm . This is used by the client to recognize the step.
  • Branch output variable : Set to loginData . This is the variable that stores the user input and passes it to the next step.

Authenticate with password

Configure this step to validate the user credentials collected in the previous step. Basic configuration for our example includes:

  • External user ID : Set to loginData.username . This maps the value submitted via the login form.
  • Password : Set to loginData.password . This retrieves the password submitted by the user.

Register Mobile PIN

This step binds the PIN credential to the device. Basic configuration for our example includes:

  • User Auth State : Leave set to The user is authenticated .
  • Branch Output Variable : Set to pinRegistrationData or similar. This stores the result returned by the client (e.g., public key info).

PIN authentication journey

After adding the following steps:

  1. Login form
  2. Authenticate with Mobile PIN

Configure them as follows:

Login form

Configure this step to display a form that collects a PIN code. Basic configuration for our example includes:

  • Authentication methods : Enable only Mobile PIN .
  • Step ID : Provide a unique identifier, e.g., loginForm .
  • Branch output variable : Set to loginData . This variable will hold the PIN input sent by the client.
Note

You can extend this journey later by enabling additional authentication methods (e.g., password or OTP) to support fallback scenarios.

Authenticate with Mobile PIN

This step verifies the user using the registered PIN. Basic configuration for our example includes:

  • User identifier source : Set to Provided by the client .
  • Branch output variable : Set to pinAuthData or similar. This variable will contain the signed result submitted by the client.

Step 3: Add mobile SDKs

mobile client

To run this flow, your integration needs the Orchestration SDK (for iOS and Android) and Authentication SDK (for iOS and Android) to enable your application to use mobile biometrics and invoke journeys.

Important

Make sure to initialize mobile SDKs within the context of the same client ID.

For Android, see instructions here:

For iOS, see instructions here:

Step 4: Start the journey

mobile client

You must start the appropriate journey from your mobile app depending on the context, using the journey IDs you defined earlier step 2.

Launch PIN registration journey

To let a user set up their PIN for the first time, launch the registration journey you created (e.g., after successful authentication):

SwiftKotlin
Copy
Copied
// Start the journey to register a PIN
TSIdo.startJourney(journeyId: "register-pin-journey")
Copy
Copied
// Start the journey to register a PIN
TSIdo.startJourney(
    "register-pin-journey", // Replace with your journey ID
    TSIdoStartJourneyOptions(additionalParams, flowId),
    idoCallback
)

Once the journey starts, the client receives a TSIdoServiceResponse containing the input required for the step—such as the PIN challenge and user identifier. After submitting the result using submitClientResponse, the journey may return a backend instruction (e.g., PinCodeRegistrationCommit) that must be handled to complete the operation. Make sure your implementation is prepared to handle this instruction by committing the registration result using the SDK.

Launch PIN authentication journey

To authenticate the user using their PIN, launch the authentication journey:

SwiftKotlin
Copy
Copied
// Start the journey to authenticate with PIN
TSIdo.startJourney(journeyId: "login-with-pin-journey")
Copy
Copied
// Start the journey to authenticate with PIN
TSIdo.startJourney(
    "login-with-pin-journey", // Replace with your journey ID
    TSIdoStartJourneyOptions(additionalParams, flowId),
    idoCallback
)

Once the journey starts, the client receives a TSIdoServiceResponse containing the input required for the step—such as the PIN challenge and user identifier. After generating the signed result using the Authentication SDK, submit it back using submitClientResponse. No additional backend instruction is expected in this case.

Note

In Android, the idoCallback object must implement the TSIdoCallback interface to receive the journey result.