Server and Web Integration Guide

This guide is for developers integrating ZenKey into their Web applications as well as backend services for clients.

1.0 Background

ZenKey is a secure bridge between your users and the apps and services you provide. The platform is a joint undertaking of the Mobile Authentication Taskforce, a joint venture of the four major US wireless carriers.

ZenKey leverages encryption technologies in a user's mobile phone and mobile network. The platform packages multiple factors of authentication into a streamlined experience for app and website providers, taking advantage of the unique capabilities and insights of the wireless carriers. It then applies those capabilities to provide an easy and secure way to register, login, and perform other types of authorizations within apps and services. The result for Service Providers is a better user experience and a more secure link to your users.

ZenKey makes integration easy by following the OpenID Connect (OIDC) authentication protocol.

1.1 OpenID Connect

OpenID Connect (OIDC) is an authentication protocol based on the OAuth 2.0 specification. It uses JSON Web Tokens (JWTs) obtained using OAuth 2.0 flows. The ZenKey SDK uses OIDC to support developers creating experiences in web and native applications. You can read more about OIDC here.

1.2 Authorization Flow

ZenKey is simple to use – one method to authenticate into all of your apps and websites (when those third parties have enabled ZenKey). These user flows can take place on the user's primary device, which has the ZenKey app installed, or on a secondary device, such as desktops and tablets.

1.2.1 Authorization on a Primary Device

Users establish their mobile device as their primary device by installing the carrier specific ZenKey app on that device. After completing a simple initial setup, users are ready to use ZenKey with third-party applications. Pressing the ZenKey button in a third party app or website from their primary device starts the authentication process.

Note: This primary device is also the device users can use to authenticate requests from other devices, such as desktops and tablets. See Section 1.2.2 Authorization on Secondary Devices.

High-level Architecture on a Primary Device

Primary Device Flow

Step 1: The Service Provider's mobile app or website makes an authorization code request to the local ZenKey app.

Step 2: The ZenKey app determines the appropriate wireless carrier to perform SIM and user authentication with and returns an authorization code to your Redirect URI (see section on Redirect URI).

Step 3: Your backend server may make a token request for user info or other resources which the user consented to share with you.

1.2.2 Authorization on Secondary Devices

Users can also use ZenKey to authenticate on devices other than their primary device, such as a tablet or desktop. These secondary devices rely on the user's primary device to complete the authentication process.

User's pressing the ZenKey button on a secondary device will see a visual and numeric code as a part of the secondary device authorization process. This code allows the user to associate that secondary device with their primary device. From there, they are then instructed to open the ZenKey application on their primary device, where they will be able to complete the authentication request.

High-level Architecture on a Secondary Device

Secondary Device Flow

Step 1: The user is taken to a website where they can select the appropriate carrier. This is known as the carrier Discovery UI website, and is where the user chooses the carrier associated with their primary device. If the user is authorizing a secondary device from an app on a tablet, the SDK will use a webview for this step.

Step 2: The user then scans the visual code or enters the numeric code into the ZenKey app on their primary device.

Step 3: Once the user approves the request in the ZenKey app on their primary device, the carrier Discovery UI website gets redirected to perform authorization with a login_hint_token.

Step 4: Your backend server makes an authorization code request to the appropriate carrier, to perform SIM and user authentication, receives the auth code back at your Redirect URI.

Step 5: Your backend server may make a token request for user info or other resources which the user consented to share with you.

1.3 User Data

To create a secure experience, user info is only shared via a web request from your secure backend to the user's carrier backend. By using a backend server to make calls to the user's carrier, and not the client application, the clientId, clientSecret and user ID token are not revealed to your client.

The ZenKey services itself does not accumulate the personal data used for authentication. That data remains secured by the user's wireless carrier. Encrypted user information is only shared with Service Providers upon user consent. Users are able to choose whether to share their data and specifically what data will be shared with each participating Service Provider.

2.0 Getting Started

To get started integrating the ZenKey with your applications, there are a few things you should do:

  • Register your application - Access the Service Provider portal to register your application and obtain a valid clientId and clientSecret.
  • Identify user information data you want to capture - The ZenKey enrollment process includes asking for personal user data. The ZenKey services itself does not accumulate the personal data used for authentication. That data remains secured by the user's wireless carrier. Encrypted user information is only shared with Service Providers upon subscriber consent. Users are able to choose whether to share their data and specifically what data will be shared with each participating Service Provider. There are various user data "scopes" already defined in the ZenKey which you can select to be captured during the enrollment process, such as email address, name, phone number.
  • Identify if you need custom redirect URIs - Redirect URIs will be used for callbacks to several ZenKey services
  • Identify user information data you want to capture - The ZenKey enrollment process includes asking for personal user data. The ZenKey service itself does not accumulate the personal data used for authentication. That data remains secured by the user's wireless carrier. Encrypted user information is only shared with Service Providers upon subscriber consent. Users are able to choose whether to share their data and specifically what data will be shared with each participating Service Provider.
    • Because applications must get authorization to access user information, scopes must be defined to allow actions. There are various user data "scopes" already defined in ZenKey which you can select to be captured during the enrollment process. Examples of these are email address, name and phone number. These scopes are used to verify users. OpenID is the only required scope and is added by default on every request. All others are optional depending on the needs of your application.
  • Identify if you need custom redirect URIs - Redirect URIs will be used for callbacks to several ZenKey services.
  • Decide to require PIN and/or Biometric - You can choose if you'd like to require the user to authenticate with a PIN and/or a biometric from their primary device (e.g. finger print, facial recognition, etc). In your setup, you can choose to have an experience with or without requiring both a PIN or biometric.

2.1 Integration Options

In order to support all possible backend technology stacks, ZenKey does not provide SDKs for specific languages or frameworks. Instead, this guide describes the HTTP request flow required to integrate with ZenKey.

We strongly recommend that you leverage an OIDC certified relying party library to abstract away the implementation details of OIDC authentication. Find one here

To aid in the implementation, we provide example applications in several popular languages and frameworks:

3.0 Authentication Flow

The web and server implementation supports authorization on both primary and secondary devices.

If you are implementing ZenKey on a website, the authentication flow begins with a carrier Discovery UI. After a user clicks the ZenKey button on your site, they are taken to a web page that contains a visual and numeric code used to link the web request to the ZenKey application on their primary device.

When supporting iOS and Android implementations, the SDK handles carrier Discovery UI. The step is either skipped, because the app is on the user's primary device, or automatically invoked.

3.1 Carrier Discovery UI

Section 3.1 and it's subsections are handled by the iOS or Android SDK within your application on a user's primary device.

The Carrier Discovery UI web page presents the user with a visual and numeric code. The user is prompted to open the ZenKey application on their primary device to authorize the request. If the user is on a device with a SIM card installed, they will be prompted to choose their carrier before preceeding in to the ZenKey app of through the visual code flow outlined above.

The first time a user goes through this step on a device, they create a link between the browser and their ZenKey account known as a Trusted Browser. On subsequent requests to authenticate on that browser, the user will skip the visual and numeric code flow. Instead a push notification will be sent to their primary device, allowing for a more seamless approval of the request.

ZenKey handles all of the logic associated with which of these two Carrier Discovery UI experiences the user should be presented.

3.1.1 Redirect User-Agent

https://discoveryui.myzenkey.com/ui/discovery-ui?
    client_id=CLIENT_ID
    &redirect_uri=REDIRECT_URI
    &state=STATE
Parameter Description
CLIENT_ID Your ZenKey clientId obtained in the SP Portal.
REDIRECT_URI Your backend endpoint to be called on success. This must exactly match the value specified in the SP Portal.
STATE An anti-forgery state token. Generate a unique session token and store it. You will need to match this token with the authentication response to verify that the user is making the request, and not a malicious attacker.

3.1.2 Response

The user-agent will be redirected to your specified REDIRECT_URI with the LOGIN_HINT_TOKEN, MCCMNC and STATE URL parameters. The LOGIN_HINT_TOKEN will be used in the Authorization Code request (Section 3.3). The MCCMNC parameter will be used in the OIDC Discovery request (Section 3.2). The STATE parameter in the response should match the STATE parameter sent with the request exactly.

Parameter Description
LOGIN_HINT_TOKEN This will only be returned if the request is made by a secondary device, such as a desktop or tablet. Requests that originate on a user's primary device will not return this parameter.
MCCMNC Six digit code that identifies the user's carrier. You will need to store this for subsequent calls.
STATE Validate against the token generated earlier.

3.2 OIDC Discovery

Section 3.2 and it's subsections are handled by the iOS or Android SDK within your application on a user's primary device.

Perform OIDC Discovery to fetch the OpenID Configuration Document for the user's carrier. This call will provide information about the carrier's OpenID configuration, including all necessary endpoints and public key location information. Use https://discoveryissuer.myzenkey.com/.well-known/openid_configuration as the DISCOVERY_URL variable in your implementation.

3.2.1 Request

https://discoveryissuer.myzenkey.com/.well-known/openid_configuration?
    client_id=CLIENT_ID
    &mccmnc=MCCMNC
Parameter Description
CLIENT_ID Your ZenKey clientId obtained in the SP Portal.
MCCMNC Six digit code that identifies the user's carrier.

3.2.2 Response

The response contains the OpenID Configuration Document. Ensure that you fetch the OpenID Configuration Document on each authentication request, as it differs based on the user's carrier.

3.3 Request Authorization Code

Section 3.3 and it's subsections are handled by the iOS or Android SDK within your application on a user's primary device.

Request an authorization code from the user's carrier.

3.3.1 Redirect User-Agent

https://AUTHORIZATION_URL?
    client_id=CLIENT_ID
    &login_hint_token=LOGIN_HINT_TOKEN
    &redirect_uri=REDIRECT_URI
    &response_type=code
    &scope=SCOPES
    &state=STATE
Parameter Description
AUTHORIZATION_URL The carrier's authorization endpoint from the OpenID Configuration Document.
CLIENT_ID Your ZenKey clientId obtained in the SP Portal.
LOGIN_HINT_TOKEN The LOGIN_HINT_TOKEN from the carrier Discovery UI response.
REDIRECT_URI Backend endpoint called on success. Must exactly match the value specified during registration. The response contains code and state URL parameters. The code parameter will be used in the Request ID Token request. The state parameter should be validated against the value in response.
STATE Use the token generated earlier.
SCOPES Scopes are used by an application during authentication to authorize access to a user's details, like name and address. Which scopes are available to you are denoted in the SP Portal. You should also include the openid scope with your request to indicate that you intend to use OIDC to verify the user's identity.

3.3.2 Response

The user-agent will be redirected to the specified REDIRECT_URI with these URL parameters.

Parameter Description
CODE The authorization CODE is used in the Request ID token request.
STATE Validate against the token generated earlier.

3.4 Request ID Token

The final step in the authorization process is to retrieve a token from the carrier. Regardless of the client which has performed the authentication flow (e.g. desktop, mobile app), this step, the token request, should always be performed from a secure server so as not to leak your client credentials.

The token request returns two important JSON Web Tokens: an ID_TOKEN and an ACCESS_TOKEN. The ACCESS_TOKEN will provide access to the user granted scopes via the user info endpoint. The ID_TOKEN will provide information about the completed authentication flow – for instance the scopes granted and the context which the user authorized (see section 3.3).

Request tokens from the user's carrier.

3.4.1 Request

POST https://TOKEN_URL?
Content-Type: application/x-www-form-urlencoded
Authorization: Basic BASE64_CLIENT_ID_AND_SECRET

grant_type=authorization_code
    &code=CODE
    &redirect_uri=REDIRECT_URI

  POST /token HTTP/1.1
  Host: https://TOKEN_URL
  Content-Type: application/x-www-form-urlencoded

  {
  “grant_type”="authorization_code”,
  “code”= CODE,
  “client_assertion_type”= CLIENT_ASSERTION_TYPE,
  “client_assertion”=CLIENT_ASSERTION
  }
Parameter Description
TOKEN_URL The carrier's token endpoint from the OpenID Configuration.
CODE The CODE from Authorization Code response.
CLIENT_ASSERTION_TYPE SP must define this assertion type.
CLIENT_ASSERTION Signed JWT.

3.4.2 Response

Parameter Description
ACCESS_TOKEN The ACCESS_TOKEN is used in the Request User Info request.
TOKEN_TYPE A bearer Access token.
REFRESH_TOKEN Only available with the offline_access scope.
EXPIRES_IN Lifetime of the current token.
ID_TOKEN The ID_TOKEN is a JWT that contains user profile information.

3.5 Request User Info

Having successfully completed a token request, it's possible to request user information from the carrier. The carrier will share the data associated with the scopes requested in the Authorization request, based on user approval. This information can be retrieved from the user info endpoint. The request should be issued from a secure server. This information can be used in the same way you would otherwise provide user information in your application, however the tokens you use to procure it should not be shared with any public clients.

Request user info from the user's carrier:

3.5.1 Request

GET https://USER_INFO_URL
Content-Type: application/json
Authorization: Bearer ACCESS_TOKEN
Parameter Description
USER_INFO_URL The carrier's user info endpoint from the OpenID Configuration.
ACCESS_TOKEN The access_token from the ID Token response.
...

3.5.2 Response

The response will contain JSON with the user information requested by your scopes and approved by the user.

Example:

{
    "sub": "mccmnc-123456789",
  name": "Jane Doe",
  "given_name": "Jane",
  "family_name": "Doe",
  "birthdate": "0000-03-22",
  "email": "janedoe@example.com",
  “email_verified”:”true”,
  "address": {
           "street_address": "1234 Hollywood Blvd.\n address line 2",
           "locality": "Los Angeles",
           "region": "CA",
           "postal_code": "90210-3456",
          "country": "US"
          },
  "postal_code": "90210-3456",
  "phone_number": "+13101234567",
  “phone_number_verified”:”true”
}

4.0 Account Migration

Migration will be supported in a future release.

When users change carriers, ZenKey provides you with the support you need. This section describes the migration process and best practices.

4.1 Migration Process

Take a look at the various interactions between user, Service Provider, carrier and ZenKey when a user ports his/her account from one carrier to another.

Sample User Account Attributes

  • Phone's Internal Sub= 001001-carrierid
  • Phone=555
  • User has visited at least one Service Provider
  • SP sees a SUB=001001-B
  • SP has created a user federated to verify=001001-B

Process Flow

  1. The user migrates phone 555 from mobile provider MNO1 to MNO2 by keeping the current device but changing the SIM.

  2. After migrating the phone number from the carrier to carrier (e.g., within 15 minutes), the user tries to connect to a Service Provider app, and the SP triggers a login prompt with the phone number.

  3. The SP SDK submits a discovery request with the new mccmnc to retrieve the OpenID configuration for MNO2.

  4. The SP SDK constructs the authentication URL to MNO, opening in the device browser to MNO2's web authentication endpoint.

  5. MNO2 sees the mobile user agent and posts a banner encouraging the user to download the CCID app.

  6. The user downloads, installs, and launches the CCID application for MNO2 .

  7. MNO2 notices that the user is not yet registered for the new phone number and:

    a. Asks: “Would you like to register a CCID?” or “Would you like to PORT your CCID from your previous MNO?”

    b. Upon seeing that the device has a recently migrated phone line, offers a migration option.

  8. The user selects the option to migrate the existing CCID and is redirected in a WebView to MNO1’s authentication endpoint. (Because the MNO1 authentication request contains the port_data scope, MNO1 knows the authentication is for migration.)

  9. MNO1 completes the user authentication before returning the user to MNO2: a. MNO1 may require the user to perform multiple recovery methods because EAP-AKA (SIM) authentication will not work for the user. b. MNO1 signs a port token for each SP using the slow rotating key present in the OpenID configuration reference.

  10. The user completes MNO2 account setup steps:

    a. MNO2 prepopulates the registration page with the previous name, email, address, etc.

    b. The user chooses a new pin.

    c. MNO2 stores port tokens for each of the previous Service Providers used at MNO1.

  11. MNO2 asks if the user wants to port his/her previously-defined consents for each of the SPs, and then returns the user to the Service Provider application with an authentication code.

  12. The Service Provider issues an access_token and id_token:

    • SUB=002002-Z
    • AKA: port_token: signedjwt {old sub : 001001-B }
  13. The Service Provider does not recognize this suband instead uses the ISS to access MNO1’s port_token signing key, and verifies the signature of the port_token.

  14. The Service Provider updates the user's subin its database with the new value. For example, from 001001-B to 002002-Z.

4.2 Migration Best Practices

When an SP first authenticates a user, the first id_token should contain a single subject claim. The SP should store this as a reference rather than a phone number or email address which could later change.

If an SP receives a new id_token that contains an AKA claim and an unrecognized sub, the SP should take the following steps:

  1. Open the AKA port_token.
  2. Verify the port_token issuer is a trusted carrier. NOTE: The SP portal will contain a list of valid iss URLs.
  3. Use the port_token :iss value to extract the OpenID configuration` of the old MNO.
  4. Use the OpenID configuration to extract the JWKs for the old MNO.
  5. Use the key ID (KID) in the port_token to identify which JWK key to use to verify the token's signature.
  6. If the SP has a recorded a user with the old subject, update the references to the new subject from the new carrier.

Note: Because a user may choose to not port his/her CCID user account, or change carriers by getting a new phone number with the new carrier, the Service Provider should host methods to update the CCID references.

5.0 Next Steps

In a database where you store information about your users, you should record the sub as the primary identifier of a ZenKey user because their phone_number and email may change.

Depending on whether the user is registering or signing in, you will want to create or fetch their user record from your data store, respectively. You may also choose to enrich this user record with information received from the User Info response.

Once you have completed the ZenKey authentication flow, return a session using the session management strategy you're already using for your application. Discard the tokens used throughout this flow.

Support

For technical questions, contact techsupport@myzenkey.com.

License

Copyright 2019 XCI JV, LLC.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

NOTICE: © 2019 XCI JV, LLC. ZENKEY IS A TRADEMARK OF XCI JV, LLC. ALL RIGHTS RESERVED. THE INFORMATION CONTAINED HEREIN IS NOT AN OFFER, COMMITMENT, REPRESENTATION OR WARRANTY AND IS SUBJECT TO CHANGE

Last Update: Document Version 0.9.13 - October 11, 2019