Skip to content

concept: PushToken

Nils Behlen edited this page Apr 30, 2019 · 21 revisions

Rollout Key URI

The creation of the push token is triggered by /token/init. The token enrollment of the push token is also a 2step enrollment. In the first step, the privacyIDEA Server creates a QR code with a key uri like this:


To initialize Firebase on the smartphone without google-services (to choose the Firebase project at runtime), the necessary information has to be provided by the privacyIDEA Server. The information can be extracted from the configuration file 'google-services.json' and 'GoogleService.plist' which are downloaded from the Firebase console for the specific project. The information that is required by the app to initalize firebase differs between iOS and Android, therefore the information for both will be in the QR so the App can extract the needed information. The extended key uri with that information could look like this:



Basically we use the same schema like for the Google Authenticator and the privacyIDEA authenticator. The token type is pipush (in contrast to hotp or totp).


The tokentype is followed by the Label that was created by the privacyIDEA server. This is not necessarily the serial, as this parameter can be modified by policies on the server side and by the user on the smartphone side.


The serial is used to identify the Token and immutable. It is sent to the server when authenticating to assign the correct challenge.

Parameter: Enrollment URL

This parameter is the enrollment URL specified by url. This is the URL, that the push token will contact in the second enrollment step.

Parameter: Time To Live

This optional parameter is a time, for how long the smartphone token can try to register with the second enrollment step (in minutes). The second step could fail to a lot of reasons. So the server can specify how long the phone can try this.

Default value: 10

Parameter: enrollment_credential

This is usually a hex nonce, that the smartphone app needs to present to the enrollment endpoint, to authorize for taking the second enrollment step.

Parameter: v

This is the version of the used cryptographic algorithm or the overall enrollment process. The smartphone app should "know", which version it supports. If the version is higher than the supported version, the smartphone should exit and tell, that the QR code version is not supported on this App version.

default value: 1

Parameter: sslverify

Indicate whether the rollout urls certificate should be verified by the smartphone. This is only for the rollout process.

default value: 1

(Firebase)Parameter: ProjectID

The project ID not only identifies the project, but is also used for the DatabaseURL ( and the StorageBucket ( In the json, it is located at project_info/project_id. Both Android and iOS share this parameter

(Firebase)Parameter: AppID

client/client_info_mobilesdk_app_id for Android

(Firebase)Parameter: AppIDiOS

from GoogleService.plist, the iOS AppID is different from the Android one

(Firebase)Parameter: API Key

client/api_key/current_key for Android

(Firebase)Parameter: Api Key iOS

from GoogleService.plist, the iOS Api Key is different from the Android one

(Firebase)Parameter: Projectnumber

project_info/project_number, both Android and iOS share this parameter

Implementation idea:

We can combine

  • Enrollment Url / Registration Url
  • TTL
  • ProjectID
  • AppID
  • API Key
  • Project Number

into a firebase push service. Store it in its own database and define an Enrollment Policy, which FB Push Service should be used.


Enrollment Endpoint

This is the endpoint that is contained in the QR code. The push token app sends all the necessary data for the 2nd enrollment step to this endpoint.

The normal tokentype endpoint /ttype/push is used.

So the enrollment URL should be of the form

POST https://yourprivacyideaserver/ttype/push
     serial=<token serial>
     fbtoken=<firebase token>
     pubkey=<public key>     

The URL was initially sent in the QR Code, the app needs to add the parameters itself. (Later we could add some further optional parameters)

enrollment_credential This is a secret key to avoid attackers from guessing the serial number and thus taking the second step.

serial is the serial number of the token generated by privacyIDEA in the first step, that was passed in the QR Code.

fbtoken is the firebase token of the smartphone app.

pubkey is the public key of the smartphone app.

On enrollment the smartphone app generates an assymmetric key pair, save the firebase token and the private key and hands the firebase token and the public key to the privacyIDEA Server.

The response from the privacyIDEA to this enrollment URL call contains a public key of the privacyIDEA server.

The token in privacyIDEA

The token is stored in the database with the following information

  • firebase config in privacyIDEA
  • smartphone: public key
  • smartphone: firebase token
  • public key from server
  • private key from server

Authentication Endpoint for Smartphone

First the authentication process is triggered. privacyIDEA needs to get an access token of the firebase service and then send the challenge to the firebase service via:


Content-Type: application/json
Authorization: Bearer <access token>

  "notification": {
    "title": "FCM Message",
    "body": "This is an FCM Message",
  "token": <firebaseokten_of_app>

The body consists of key-value pairs. The keys are the following:

  1. nonce
  2. url
  3. serial
  4. question
  5. title
  6. sslverify
  7. signature

The signature is in Base32 format and the signed string is built like:


For the smartphones reponse, the nonce and serial are signed with the smartphones private key. The response looks like this:

POST https://privacyideaserver/validate/check

Polling Endpoint for Application

The application, where the user logs in, uses this endpoint of privacyIDEA to check, if the user has confirmed the login on his smartphone.

We can utilize the existing endpoint GET /token/challenges/ which is an administrative endpoint.

In the first authenticatoin step the application would memorize the transaction_id and then poll to

GET /token/challenges/
    transaction_id=<transaction id from inital request>
You can’t perform that action at this time.