Yubikey (FIDO2) and Okta Gotcha!
Recently, I came across an issue using Yubikeys (FIDO2) with Okta. Users successfully enrolled their Yubikeys in Okta, but when prompted by applications to use the factor, were unable to login using them. They were greeted by an error "This security key doesn't look familiar. Please try a different one."
We had distributed Yubikeys and instructed users to perform a self-enrollment via our Okta Custom URL Domain. We had configured an MFA enrollment policy within Okta to prompt enrollment upon login.
Custom URL Domain and IWA
Externally, this is typically configured as a cname and pointed to your Okta Service url. Internally, it is pointed to an IIS Okta IWA farm to support single sign on. When using IWA, if the user is internal to your network, they will get redirected to the Okta Service url. When external, the redirection will not occur, and the browser will be accessing your Custom URL Domain.
Now that we have a basis for the common configuration, let's talk about WebAuthn.
A key part of WebAuthn and why it is resistant to phishing attacks is due to the domain name being stored on the authenticator. Since most phishing attacks are hosted on fake websites, the authenticator will compare domain names that were stored during the registration process. - Okta
... When using WebAuthn, this risk is eliminated due to the fact that the authenticator (or phone in this case) will verify the domain name for the user. This eliminates the risk of human error in entering the credentials on a malicious website. - Okta
WebAuthn requires that the domain accessing the authenticator is stored/registered on the Authenticator.
In the above example, we directed users to enroll their Yubikeys using the Custom URL, but if they were internal they were redirected and subsequently enrolled the Yubikeys under the Okta Service URL, not the Custom URL.
When the Okta application was created and the Identify Provider metadata was generated, Okta used the Custom URL for the SingleSignOnService location. Because the enrollment took place under the Okta Service URL and the authentication request was coming from the Custom URL, the authenticator wouldn't recognize the source domain, and refused to grant access. Our solution was to modify the metadata to match our Okta Service URL.
More discussion on this topic can be seen on Github.