Search code examples
iframeresponse-headerswebauthnfidohttp-permissions-policy

Using `navigator.credentials.get()` in cross-origin iframe gives error "'publickey-credentials-get' feature is not enabled in this document"


Getting the error while logging into an iframe through webauthn.

The 'publickey-credentials-get' feature is not enabled in this document. Permissions Policy may be used to delegate Web Authentication capabilities to cross-origin child frames.

Here is the link to the example https://jsfiddle.net/14kj25nr/. I have registered a user "test_account" directly through webauthn.io and then tried to login into it through jsfiddle. It says to use publickey-credentials-get, but I couldn't find a way to use it to get it to work. Any help would be appreciated.

Update 1:

I have added the allow attribute for the iframe allow="publickey-credentials-get". It still gives me the same error. The example in the fiddle is updated.

Update 2:

From IAmKale's suggestion. I made the following changes but still got the same error. Updated the allow attribute of iframe allow="publickey-credentials-get *".

I use the Requestly chrome extension to add the Permissions-Policy header in the RP's response. It can be seen in the below screenshot that I was able to successfully add the header in the response. But still getting the same error. Could it be some jsfiddle specific issue? Or is there anything I am doing wrong? I am using Chrome Version 96.0.4664.110. enter image description here

Update 3:

When I use the iframe in localhost instead of jsfiddle, I am getting webauthn chrom pop-up. But the log-in is still unsuccessful, the server returns POST https://webauthn.io/assertion 400.


Solution

  • Expanding on Tim's answer, the site embedding the RP will need to add the following allow attribute:

    <iframe src="..." allow="publickey-credentials-get *" />
    

    The spec is a little ambiguous about this, but digging into Permissions Policy a bit I believe the RP also needs to set the following HTTP header in the response to the URL specified in the iframe's src:

    Permissions-Policy: publickey-credentials-get=*
    

    If you want more granular control you can whitelist specific URLs that are allowed to embed the RP's site:

    # Only specific sites
    Permissions-Policy: publickey-credentials-get=("https://example.com")
    

    With https://example.com being the URL of the page that's embedding the RP's site in the <iframe>

    Once both pieces are in place I think you'll be able to trigger navigator.credentials.get() in the iframe.