Discover how to create & login with passkeys in cross-origin iframes with our guide. Learn about iframes in WebAuthn, security policies, & implementation.
Vincent
Created: June 3, 2024
Updated: October 1, 2024
Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.
2.1 Basic iframe
2.3 Secure iframe (Sandboxed iframe)
3.1 Login with Passkeys in Cross-Origin iframes
3.2 Create Passkeys in Cross-Origin iframes
3.3 Use Cases for Passkeys in iframes
3.3.1 Federated Identity
3.3.2 Payments
5.1 Set Permission Policy to publickey-credentials-get and publickey-credentials-create
6.1 Challenge 1: Permission Policy Configuration
Week after week, more and more organizations announce their passkey rollouts (e.g. lately Visa, Mastercard or Vercel). As developers and product managers from other companies follow these role models, more use cases of passkey implementation are discussed.
One case we are constantly asked for is how passkeys work in iframes, as iframes are widely used in modern web development to embed content from different sources seamlessly. In the context of passkeys and WebAuthn, iframes come with their own set of challenges, especially concerning security and user interactions.
This blog post provides a comprehensive guide on using passkeys and WebAuthn in iframes. We will
By the end of this post, you will have a clear understanding of how to leverage passkeys within iframes.
Recent Articles
⚙️
Why Passkey Implementation is 100x Harder Than You Think – Misconceptions, Pitfalls and Unknown Unknowns
📖
WebAuthn Autocomplete for Passkey & Password Autofill
📖
WebAuthn Conditional Registration Extension
📖
WebAuthn Passkey QR Codes & Bluetooth: Hybrid Transport
📖
WebAuthn pubKeyCredParams & credentialPublicKey: CBOR & COSE
iframes, or inline frames, are HTML elements that allow developers to embed another HTML document within the current document. This capability is widely used to incorporate content from external sources, such as videos, maps, and other web pages, into a website.
Let’s have a look at the different types of iframes.
Subscribe to our Passkeys Substack for the latest news, insights and strategies.
SubscribeThe basic iframe is the most commonly used type. It simply embeds content from another URL within the current page.
<iframe src="https://example.com"></iframe>
This basic iframe is often used to include static content, like an article, within a web page.
Responsive iframes are designed to adjust their size based on the screen size or the container they are placed in. This ensures that the embedded content looks good on all devices, including desktops, tablets, and mobile phones.
<iframe src="https://example.com" style="width: 100%; height: 500px;"></iframe>
CSS media queries can also be used to make the iframe adjust dynamically based on the viewport size.
A secure or sandboxed iframe restricts the actions that can be performed within the iframe. This is useful for embedding content from untrusted sources or for enhancing security.
<iframe src="https://example.com" sandbox></iframe>
The sandbox attribute can include various restrictions, such as:
<iframe src="https://example.com" sandbox="allow-scripts allow-same-origin"></iframe>
The sandbox attribute allows scripts to run but restricts potentially dangerous actions, like form submissions or plugin usage.
Become part of our Passkeys Community for updates and support.
JoinCross-origin iframes embed content from a different domain. They are commonly used for integrating third-party services, such as payment gateways or social media widgets. Due to security restrictions, these iframes have limited access to the embedding page's content and vice versa.
Cross-origin means that the content being loaded is from a different origin, where an origin is defined by the
combination of the scheme (protocol), host (domain), and port number. For example, https://example.com
and http://example.com
are considered different origins because they use different schemes (HTTP vs. HTTPS).
Similarly, subdomains are treated as separate origins from their parent domains. For instance, https://example.com
and https://sub.example.com
are cross-origin, even though they share the same base domain. This separation ensures
that scripts and data from one subdomain cannot directly interact with those from another without explicit permission,
enhancing security.
Ben Gould
Head of Engineering
I’ve built hundreds of integrations in my time, including quite a few with identity providers and I’ve never been so impressed with a developer experience as I have been with Corbado.
10,000+ devs trust Corbado & make the Internet safer with passkeys. Got questions? We’ve written 150+ blog posts on passkeys.
Join Passkeys CommunityHere are examples to illustrate the concepts of cross-origin and same-origin:
Cross-origin example:
Embedding content from https://payment.example.com into a webpage hosted on https://www.mystore.com. These are cross-origin because they have different domains.
Same-origin example:
Embedding content from https://www.example.com/shop into a webpage hosted on https://www.example.com/blog. These are same-origin because they share the same scheme, host, and port.
Cross-origin iframes differ from basic iframes in that the source is from another domain, whereas a same-site iframe has its source from the same domain as where it is embedded.
<iframe src="https://anotherdomain.com"></iframe>
Using passkeys in iframes introduces new capabilities and constraints that developers need to understand, primarily revolving around setting the correct permissions and ensuring secure user interactions within the embedded context.
Historically, the Web Authentication API was disabled by default in cross-origin iframes, primarily due to security concerns. This limitation meant developers had to redirect users or use pop-up windows for authentication, leading to a less seamless user experience.
In passkeys / WebAuthn, there are two core operations (also called ceremonies):
The two operations were and are not supported equally in cross-origin iframes:
At first, the login via cross-origin iframes was made possible but cross-origin creation not yet because there wasn't anyone with a use case.
Recent advancements (e.g. in Chrome 123) have introduced support for the creation of cross-origin iframe passkeys under specific conditions. However, as of May 2024, not all browsers fully support the creation of passkeys via cross-origin iframes, although login is possible with most browsers.
Moreover, cross-origin iframe support (for register and authentication operations) is already incorporated into the ongoing WebAuthn Level 3 specification, expected to be generally available by the end of 2024. Browsers still need to catch up to the specification. It seems likely that by the end of 2024, coverage for cross-origin registration of passkeys will become a reality in major browsers, lifting the most significant technical limitation for using passkeys in cross-origin iframes.
In the following parts of the blog post, we assume the use of cross-origin iframes.
Want to find out how many people can use passkeys?
View Adoption DataThe following tables provides an overview of the browser / standard support for authenticating / logging in via passkeys in cross-origin iframes:
Browser/Standard | First-Party-Context | Third-Party-Context |
---|---|---|
Required in WebAuthn Level 2 | ✔️ | ✔️ |
Required in WebAuthn Level 3 | ✔️ | ✔️ |
Implemented in Chrome | ✔️ | ✔️ |
Implemented in Firefox | ✔️ | ✔️ |
Implemented in Safari | ✔️ | ✔️ |
As of May 2024, the creation of a passkey in a cross-origin iframe is not yet possible in all browsers. The following table provides an overview of the browser / standard support for the registering / creation of passkeys in cross-origin iframes:
Browser/Standard | First-Party-Context | Third-Party-Context |
---|---|---|
Required in WebAuthn Level 2 | ✔️ Details | ❌ |
Required in WebAuthn Level 3 | ✔️ Details | ✔️ Details |
Implemented in Chrome | ✔️ Details | ✔️ Details |
Implemented in Firefox | ✔️ Details | ✔️ Details |
Implemented in Safari | ✔️ Details | Awaiting signal for implementation |
If you’re interested in more background to this development and support, we recommend having look at this GitHub issue and this Pull Request.
There are two major use cases for supporting passkeys in cross-origin iframes.
Enabling passkeys in cross-origin iframes is crucial for federated identity scenarios where multiple domains are involved but the same user accounts should be used.
Let’s take the following scenario. You’re a multinational company like KAYAK and have different domains for different regions:
However, you have one central identity management system that enables users to log in with the same account and credentials on all these domains. The WebAuthn standard would pose a challenge to these scenarios, as the passkeys can be bound to only one domain (Relying Party ID), e.g. www.kayak.com.
To overcome this challenge, you would use an iframe from the origin www.kayak.com on all your other domains. So you embed an iframe with www.kayak.com origin on www.kayak.us and on www.kayak.de (cross-origin iframe). Otherwise, the usage of your “www.kayak.com”-bound passkeys on these other domains would not be possible due to the phishing-resistance of passkeys.
On a site note: There is an ongoing discussion to allow “related origins” to access passkeys without iframes, but there is no support yet in browsers.
Also for seamless payment flows, the usage of passkeys in cross-origin iframes plays an important role. Consider the following scenario: A customer wants to buy new shoes on a merchant’s website (e.g. www.amazon.com). This merchant’s website allows the customer to pay via the bank account (e.g. at www.revolut.com) and thus requires the user to log into the bank’s website (this is a simplified process). The user logs in to the bank’s website with a passkey that is bound to the bank’s Relying Party ID, e.g. “revolut.com”.
To avoid redirecting the user from the merchant’s website (www.amazon.com) to the bank’s website (www.revolut.com) in the checkout process and let the user log in there to the bank’s account, a cross-origin iframe can be used. Hereby, the user stays on www.amazon.com and uses the passkey in the cross-origin iframe for authentication that they created for www.revolut.com.
Thus, integrating passkeys via cross-origin iframes in payment flows ensures secure and streamlined transactions across consumers, merchants and banks:
Consumers | Merchants | Banks |
---|---|---|
|
|
|
In the context of payment and passkeys, we also recommend taking a look at our blog post on Secure Payment Confirmation (SPC) and dynamic linking with passkeys.
In general, integrating passkeys within iframes offers several benefits, mainly by improving the UX and security. Here’s a breakdown of these advantages:
Enhanced User Experience
Improved Security
Implementing passkeys in iframes involves some key steps to ensure security and functionality. We provide a detailed guide for developers. Please see also the example implementation at https://cross-origin-iframe.vercel.app/.
The HTTP Permissions-Policy
header helps to allow or deny the use of certain browser features in a document or within
an iframe element. To enable passkey logins in an iframe, you must set
the publickey-credentials-get
and
publickey-credentials-create
permission policies. The policies allow the embedded content to invoke the necessary
WebAuthn API method to authenticate (navigator.credentials.get({publicKey})
) with and create a
passkey (navigator.credentials.create({publicKey})
).
<iframe src="https://passkeys.eu" allow="publickey-credentials-get; publickey-credentials-create"></iframe>
The HTTP Permissions Policy
was previously called Feature Policy
. Under Feature Policy
, you could grant a feature
to a cross-origin iframe by either adding the origin to the header origin list or including an allow
attribute in the
iframe tag. With Permissions Policy
, adding a cross-origin frame to the origin list requires that the iframe tag for
that origin must include the allow
attribute. If the response lacks a Permissions Policy
header, the origin list
defaults to *
(all origins). Including the allow
attribute in the iframe grants access to the feature.
To ensure that cross-origin iframes not specified in the origin list are blocked from accessing the feature, even if
the allow
attribute is present, developers can explicitly set the Permissions Policy
header in the response.
In Chrome 88+, Feature Policy
can still be used but acts as an alias for Permissions Policy
. Other than syntax
differences, the logic remains the same. When both Permissions Policy
and Feature Policy
headers are used
simultaneously, the Permissions Policy
header takes precedence and will override the value set by the Feature Policy
header. Please also see
this blog post by the Chrome team for more
implementation details.
Ensure the HTTP response headers from the iframe’s source URL include the relevant ´Permissions-Policy`. This is crucial for cross-origin support.
Permissions-Policy: publickey-credentials-get=\*, publickey-credentials-create=\*
For more granular control, you can specify particular origins allowed to embed the iframe content.
Permissions-Policy: publickey-credentials-get=("https://passkeys.eu"), publickey-credentials-create=("https://passkeys.eu")
Ensure that the iframe content requires a user action to trigger passkey authentication. This can be done using event listeners for clicks or form submissions within the iframe. This process is also called transient activation.
In this context, see also our blog post on Safari user gesture requirements.
In the following, you find a full sample code snippet of an index.html
file hosted
on https://cross-origin-passkey.vercel.com that uses a cross-origin iframe for passkeys via https://passkeys.eu.
Implementing passkeys in iframes can come with a set of challenges that developers need to address to ensure a smooth and secure user experience. Here’s a detailed look at common challenges and how to overcome them.
Problem: Incorrectly configuring permission policies can prevent the iframe from accessing WebAuthn APIs.
“NotAllowedError - The 'publickey-credentials-create' feature is not enabled in this document. Permissions Policy may be used to delegate Web Authentication capabilities to cross-origin child frames.”
If you don’t add the permission policies correctly, the browser would throw the following error:
Solution:
Double-Check If Allow Attribute and HTTP Headers are Set: Ensure that the allow
attribute and HTTP headers are
correctly set. Double-check that the publickey-credentials-get
and publickey-credentials-create
permissions are
included in both the iframe element and the server's HTTP response headers.
Meta Headers Instead of Web Server Headers: Use <meta/>
headers for defining the permission policies instead of
setting the headers in your web server.
Semicolon instead of Comma in Permissions-Policy: Earlier, Permissions-Policy
was called Feature-Policy
.
Single elements of a Feature-Policy
were separated by a comma instead of a semicolon (which is the standard
for Permissions-Policy
). The iframe Permissions-Policy
follows still the syntax of Feature-Policy
and thus uses
commas. The sandbox / allow
attributes are still separated with a semicolon though (see code snippet above).
Tip: To properly test that your Permission-Policy
headers are set correctly, we recommend to open your browser’s
developer tools, access Application (here: in Chrome developer tools), go to Frames and search for the iframe’s
origin (here: passkeys.eu/). If the Permissions-Policy
is set correctly, publickey-credential-create
and publickey-credential-get
should be listed among the Allowed Features:
Problem: The cross-origin iframe passkey creation or passkey login does not work, and you see the following error in your browser console.
"NotAllowedError - The origin of the document is not the same as its ancestors."
This error appears when using the Safari browser and trying to create a passkey from within the iframe, as Safari does not support cross-origin iframe passkey creation (see above).
Solution: Here, you cannot really do anything as Safari does not yet support the creation of a passkey from within a cross-origin iframe (yet).
Blocked a frame with origin "https://passkeys.eu" from accessing a frame with origin "https://cross-origin-iframe.vercel.app". Protocols, domains, and ports must match.
This error is not directly connected to passkeys but more to cross-origin iframes in Safari in general. As part of Safari’s / WebKit’s initiative to block third-party cookies or access to LocalStorage in a third-party-context, parts of the JavaScript logic might be broken.
Solution: Here, you need to ensure that you are not using third-party cookies inside your iframes, as this causes an error.
Problem: Different browsers may have varying levels of support for WebAuthn and iframe permissions, leading to inconsistent behavior.
Solution: Test the implementation across multiple browsers to ensure compatibility and identify any browser-specific issues.
Steps:
Integrating passkeys within iframes significantly enhances user authentication by improving both security and user experience. This allows for seamless authentication without the need for redirects or pop-ups, ensuring a consistent UX across various sections and sites.
Real-world implementations, such as Shopify's integration of passkeys within their login component, demonstrate the practical benefits and flexibility of this approach.
Can I create passkeys in cross-origin iframes?
Yes, with the right permission policies and transient user activation, you can create passkeys in cross-origin iframes in supported browsers (check our table above).
What are the benefits of using passkeys in iframes?
Benefits include enhanced security, improved user experience, and seamless authentication flows across different domains.
How do I enable passkeys in an iframe?
Set the publickey-credentials-create and / or publickey-credentials-get permission policy, provide the right headers and ensure transient user activation within the iframe.
Table of Contents
Enjoyed this read?
🤝 Join our Passkeys Community
Share passkeys implementation tips and get support to free the world from passwords.
🚀 Subscribe to Substack
Get the latest news, strategies, and insights about passkeys sent straight to your inbox.
We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour
Start for free
Recent Articles
Shopify Passkeys: Analysis of Sign-Ups and Logins with Passkeys
Robert - June 5, 2023
WebAuthn Conditional UI (Passkeys Autofill) Technical Explanation
Vincent - October 20, 2023
Dynamic Linking with Passkeys: Secure Payment Confirmation (SPC)
Vincent - April 20, 2024