Verify token before enrollment

We have PI setup and working fine with an LDAP backend but when users enroll tokens (in particular TOTP via regular authenticator apps) we can’t find any way to verify the token before enrollment (like how Google does it).

The desired flow is Present QR for scanning→Prompt the user to enter the code from their app→Fully enroll the token. Without confirming the code the token shouldn’t be enrolled. In our limited rollout so far about half of our (technical!) users fail to scan TOTP codes no matter what wording we put on the enrollment page and then get locked out.

Any ideas how to accomplish this?

These are your techinical guys?

I do not want te meet the others! :wink:

Did you use the enrollment wizard?
privacyIDEA does not do this. You will have to create your own enrollment page.
Here is an article about creating your own user portal:

You might also consider using the privacyIDEA authenticator app.
This allows for a 2step enrollment. I.e. the smartphone generated a 2nd part of the secret.
On the one hand you avoid simple token compromising (
and you also have the effect, that the user needs to “enter” before the token is enrolled.
But I am not sure, if your users will be able to handle this.

Yes, we used the enrollment wizard. In fact I think that’s what caused the problem - we automatically generated a TOTP token but some of them though “I don’t want that, I want to enroll my yubikey” and then that failed for some reason, or they abandoned the session and came back later and in both cases found themselves unable to log in because PI had already enrolled the initial TOTP token.

We have considered writing our own user portal (and that’s desirable to keep the same appearance as the rest of the site) but that’s obviously a significant amount of effort and not worth doing during our initial pilot. The article you link to covers enrolling a token in the same manner that the PI website does it - without confirmation. Is there an API sequence you’d recommend that allows confirmation before enrollment?

I think our technical users have an entirely reasonable expectation here - every other service I have ever used with MFA requires entering a code (or tapping a Yubikey pad or whatever) before an MFA token is fully enrolled and no matter what wording is on the PI enrollment page it’s very surprising for users that the code is enrolled immediately on PI.

Are there any plans to implement this functionality?

It is only since Google poisende the impression of the users :wink:

No, there is no plan to mimick Google.

The APIs would be:

POST /token/init
POST /validate/check

If you fail, you need to delete the token again

DELETE /token/<serial>

Take a look at the privacyIDEA Authenticator and 2step. It is better.

@Fraser_McCrossan I would like to have some more details and some of your thoughts from you.

You say, that half of the technical people failed to scan the QR code.
What does “failed to scan” mean?
Do they scan the QR code and then their App does not work - Does it display “wrong” OTP values?
Do they simply hit “done” without scanning the QR code?
Do they try to scan the QR code and their smartphone does not recognize it - do they have no OTP app installed?
It would be interesting, to get some more information here to know, what you actually want to/need to avoid.

Example: Why does Google ask for an OTP value? Because there are 1.23 million crap OTP apps out there and Google does not know, which OTP app the user will use. crap means, that a QR code can have a lot of different parameters (OTP algo, hash algo, length of OTP value, time window…) and most of the apps will ignore some of the parameters and thus generate wrong OTP values. The most crappy app is the microsoft authenticator, since it ignores everything and does what it thinks is cool - well, a common aspect about microsoft.

This is probably why Google does it this way. But in an enterprise environment you have a different scenraio. Users will not come with 1.23 mio different apps. The IT department will say, “these two apps are supported. Dont bother me with anything else”. So as always this would be a problem of your workflows.


What should happen if the user enters a wrong OTP value during enrollment?
Should the dialog ask for a correct value indefinitely?

To be able to present a QR code to the user, we actually need to create an OTP secret and create a token object.
What should happen with the actually created token object, if the user is not capable of entering a correct OTP value?

Thanks for your comments.

My apologies, by “failed to scan” I meant “they didn’t scan”. Perhaps they hit “done” or perhaps they just navigated elsewhere. It’s also possible that they scanned with a faulty app, as you noted above.

Also to clarify, our situation is much more like Google’s than an enterprise environment. We are a government-funded organization mandated to offer service to a wide variety of users at other institutions. Many of those users work at universities and will most likely already have the Duo app installed, or maybe one of the common TOTP apps. So they will indeed be coming in with 1.23 million other apps. Requiring the use of the privacyIDEA app is certainly an option but we are already struggling with the issues involved in deploying MFA to such a diverse user base and requiring a specific app makes it more difficult. We lack the funding to send hardware tokens to all users, and we also have to deal with occasional users who do not have a smartphone.

To answer your specific questions with our preferences:

What should happen if the user enters a wrong OTP value during enrollment? Should the dialog ask for a correct value indefinitely?

Yes. Or cancel enrollment after a limited number of attempts.

What should happen with the actually created token object, if the user is not capable of entering a correct OTP value?

It should not be enabled or used until the user can enter a correct OTP.

Actually that brings up another point: if we enable the policy passOnNoToken then PI disallows login if any tokens are present, including disabled tokens. That means we have to use the API flow you give above and delete any token that has not been confirmed. If there was an option to consider only enabled tokens then the API flow would be simpler:

  1. Create a token, display the QR code then disable it
  2. Request an OTP.
  3. Enable the token and test the OTP. If it matches, we’re done.
  4. OTP didn’t match, disable it again and go to step 2

This would avoid users being locked out of MFA-protected services as soon as they begin the MFA enrollment process.

Thanks for the feedback!

One note: If you have a very volatile user base I would got for the settings:

  • TOTP
  • 30 secs
  • SHA1

because I think this is what every app out there supports.