Custom HOTP factors

We’ve opted into the early access “Custom TOTP” feature.

I have generated a new factor profile, and I can successfully enrol the factor for my test user with the API. However when I attempt to verify the factor it always fails with (403) Forbidden.

The factor is HOTP (0 counter-based, not time-based), using a Base32 shared secret, and I’m using the API here to enrol them:

Factor Profile:
factorType : token:hotp
provider : CUSTOM
vendorName : CUSTOM
_links : @{enroll=}
status : ACTIVE
enrollment : OPTIONAL
profiles : {@{id=xxxx; name=YubikeyHOTP; default=False; _embedded=}}

Example enrolled user factor:
id : xxxx
factorType : token:hotp
provider : CUSTOM
vendorName : YubikeyHOTP
status : ACTIVE

To rule out any issue with my hardware token, I tested with a duplicate secret in Google Authenticator, and my hardware token and GA correctly issue the same sequence of token codes.

I’m wondering if I’m missing something obvious on the Okta setup side. The first thing I notice is in the UI section where the custom factor profile is configured, it uses "Time-Based TOTP’ in its terminology. Is this actually the correct place to be adding HOTP profiles? Or should there be another section for HOTP?

My custom factor profile is configured with:
TOTP Length: 6
HMAC Algorithm: HMacSHA1
Time step: 15 seconds
clock drift interval 3

I don’t see how the two are compatible, since the configured TOTP profile uses a time-step, which should not apply to a counter-based OTP model. (I think there is some mislabeling on Okta’s side between HOTP and TOTP (although, to be fair,TOTP is just HOTP with a predictable counter…)

It turns out the procedure works to create a TOTP factor when factorType = token:hotp so you are correct, more of a labelling thing. I’ve opened a support case to see if there is/will be a way to add a true HOTP (counter based) factor profile. :crossed_fingers: