Federated Credential Management API
A web API for privacy-preserving identity federation.
What is FedCM?
FedCM (Federated Credential Management) is a proposal for a privacy-preserving approach to federated identity services (such as "Sign in with...") where users can log into sites without sharing their personal information with the identity service or the site.
Implementation status
- Chrome Platform Status
- FedCM shipped in Chrome 108.
- The FedCM proposal is open for public discussion.
- FedCM isn't supported in other browsers yet.
- Mozilla is implementing a prototype for Firefox and Apple has expressed general support and interest in working together on the FedCM proposal.
Moving forward, we plan to introduce a number of new features based on the feedback we received from identity providers (IdP), relying parties (RP) and browser vendors. While we hope identity providers will adopt FedCM, please be aware that FedCM is still an API under active development and that backward incompatible changes are expected until Q4 2023.
To minimize the challenges of deploying backwards incompatible changes, we currently have two recommendations for identity providers:
- Subscribe to our newsletter where we will send updates as the API evolves.
- We encourage IdPs to distribute the FedCM API via JavaScript SDKs while the API is maturing, and to discourage RPs from self-hosting SDKs. This will ensure IdPs can make changes as the API evolves, without having to ask all of their relying parties to redeploy.
Why do we need FedCM?
Over the last decade, identity federation has played a central role in raising the bar for authentication on the web, in terms of trustworthiness, ease-of-use (for example, passwordless single sign-in) and security (for example, improved resistance to phishing and credential stuffing attacks) compared to per-site usernames and passwords.
With identity federation, an RP (relying party) relies on an IdP (identity provider) to provide the user an account without requiring a new username and password.
Identity federation delegates authentication or authorization of an individual (user or entity) to a trusted external party (an identity provider or IdP). The identity provider then allows the individual to sign in to a website (a relying party or RP).
Unfortunately, the mechanisms that identity federation has relied on (iframes, redirects and cookies) are actively being abused to track users across the web. As the user agent isn’t able to differentiate between identity federation and tracking, the mitigations for the various types of abuse make the deployment of identity federation more difficult.
The Federated Credential Management API (FedCM) provides a use-case-specific abstraction for federated identity flows on the web, by exposing a browser mediated dialog that allows users to choose accounts from IdPs to login to websites.
FedCM is a multi-step journey to make identity on the web better, and in its first step we are focused on reducing the impact of third-party cookie phase-out on federated identity (see the Roadmap section to see a few steps further).
What do we expect will be affected?
The aim of the Privacy Sandbox initiative is to mitigate all tracking vectors in Chrome. Our first step is to reduce the impact of third-party cookie phase-out which is already happening in other browsers, and is planned in Chrome for 2024. While removing these cookies can help reduce third-party tracking, it also impacts other cross-site use cases.
Through community effort and our research, we learned there are a few identity federation related integrations that are affected by third-party cookie phase-out:
- OpenID Connect Front-Channel Logout
- OpenID Connect Session Management
- Iframe-based background token renewal
- Iframe-based login widgets
FedCM's first goal is to reduce the impact of third-party cookie phase-out on identity federation and above is a list of areas we expect to be affected. If there are any additional use cases that we've not listed, we encourage you to engage and share feedback.
Who should use FedCM?
We expect FedCM to be useful to you only if all these conditions apply:
- You're an identity provider (IdP).
- You're affected by the third-party cookie phase out.
- Your RPs are third-parties. If your RPs are SameParty, you may be better served by First-Party Sets.
You're an IdP
FedCM requires support from an identity provider. A relying party cannot use FedCM independently. If you are an RP, you can ask your IdP to provide instructions.
You're affected by the third-party cookie phase out
You should only use FedCM if your current integration is affected by the third-party cookie phase out.
If you're unsure if your identity federation will continue to work after Chrome's third-party-cookie phase-out, you can test the effect on a website by blocking third-party cookies on Chrome.
If there is no discoverable impact on your identity federation without third-party cookies, you can continue using your current integration without FedCM.
If you aren't sure what to check for, read more about the known features that the phase-out is expected to affect.
Your RPs are third-party
If you're an identity provider whose RPs are within the same party as your IdP, we expect First-Party Sets may be a better option. First-Party Sets allow related domain names owned and operated by the same entity to declare themselves as belonging to the same first-party. This allows the same party's third-party cookies to work, even after third-party cookie phase-out.
First-Party Sets can't always be used. However, if your RPs are SameParty, consider using First-Party Sets.
How will users interact with FedCM?
Currently, FedCM's primary focus is to mitigate the impact of third-party cookie phase-out. Users can enable or disable FedCM in Chrome's user settings.
FedCM is designed to be protocol-agnostic and offers the following authentication-related functionalities.
Check out our demo to see how it works.
Sign in to a relying party
When the user lands on the relying party (RP) website, a FedCM sign-in dialog will appear if the user is signed in to the IdP.
If the user doesn't have an account on the RP with the IdP, a sign-up dialog appears with additional disclosure text such as the RP's terms of service and a privacy policy if they are provided.
The user can complete sign in by tapping Continue as.... If successful, the browser stores the fact that the user has created a federated account on the RP with the IdP.
If the user closes the UI manually, an entry would be added to the settings UI and the UI won't be displayed in the same website for a period of time. The UI will be reenabled after the period, but the duration will be exponentially expanded. Users can reenable FedCM on the RP manually by either going to the settings page or clicking on the PageInfo UI (a lock icon beside the URL bar) and reset the permission.
RPs are expected to work on browsers which don't support FedCM. Users should be able to use an existing, non-FedCM sign-in process. Learn more about how sign-in works in the FedCM.
Setting to enable or disable FedCM
Users can enable or disable FedCM in settings on Chrome on Android. Go to Settings > Site settings > Third-party sign-in, then change the toggle.
They can do the same for Chrome on desktop by going to chrome://settings/content/federatedIdentityApi
.
Roadmap
We are working on landing a number of changes on the FedCM.
There are a few things we know that still need to be done, including issues we heard about from IdPs, RPs and browser vendors. We believe we know how to resolve these issues:
- Cross-origin iframe support: IdPs can call FedCM from within a cross-origin iframe.
- Personalized button: IdPs can display a returning user's identity on the sign-in button from within an IdP owned cross-origin iframe.
- Metrics endpoint: Provides performance metrics to IdPs.
Additionally, there are unresolved issues we are actively exploring including specific proposals that we are evaluating or prototyping:
- CORS: We are discussing with Apple and Mozilla to ensure to improve the specification of FedCM fetches.
- Multiple-IdP API: We are exploring ways to support multiple IdPs to coexist cooperatively in the FedCM account chooser.
- IdP Sign-in Status API: Mozilla has identified a timing attack issue, and we are exploring ways for an IdP to proactively notify the browser of the user's sign-in status to mitigate the issue.
- Sign in to IdP API: To support various scenarios, when a user is not signed in to the IdP, the browser provides a UI for the user to sign in without leaving the RP.
Finally, there are things we believe still need to be done, based on feedback from Mozilla, Apple and TAG reviewers. We are working to evaluate the best solutions for these open questions:
- Improving user comprehension and matching intent: As Mozilla noted, we’d like to continue exploring different UX formulations and surface areas, as well as triggering criteria.
- Identity Attributes and Selective Disclosure: As our TAG Reviewers noted, we’d like to provide a mechanism to selectively share more or less identity attributes (such as emails, age brackets, phone numbers, and so on).
- Raising the Privacy Properties: As Mozilla suggested here, we’d like to continue exploring mechanisms to offer better privacy guarantees, such as IdP blindness, directed identifiers.
- Relationship with WebAuthn: As suggested by Apple, we are super excited to see the progress on passkeys and to work on providing a coherent and cohesive experience between FedCM, Passwords, WebAuthn and WebOTP.
- Login Status: As Apple suggested with the Privacy CG’s Login Status API, we share the intuition that the user’s login status is a useful bit of information that can help browsers make informed decisions, and we are excited to see what opportunities arise from that.
- Enterprises and Education: As is clear at the FedID CG, there are still a lot of use cases that are not well served by FedCM that we’d like to work on, such as
front-channel logout (the ability for an IdP to send a signal to RPs to logout) and support for SAML. - Relationship with mDLs/VCs/etc: continue working to understand how these fit within FedCM, for example with the Mobile Document Request API.
How can you develop FedCM?
You need a secure context (HTTPS or localhost) both on the IdP and RP in Chrome to use the FedCM.
Debug code on Chrome on Android
Set up and run a server locally to debug your FedCM code. You can access this server in Chrome on an Android device connected using a USB cable with port forwarding.
You can use DevTools on desktop to debug Chrome on Android by following the instructions at Remote debug Android devices.
Block third-party cookies on Chrome
You can test how FedCM works without third-party cookies on Chrome before it's actually enforced.
To block third-party cookies, use Incognito mode, or choose "Block third-party cookies" in your desktop settings at chrome://settings/cookies
or on mobile by navigating to Settings > Site settings > Cookies.
FedCM is temperarily disabled when third-party cookies are blocked. Starting from Chrome 110, you can force enable it with the Chrome flag: chrome://flags/#fedcm-without-third-party-cookies
.
Use the FedCM API
You integrate with FedCM by creating a well-known file, config file and endpoints for accounts list, assertion issuance and optionally client metadata.
From there, FedCM exposes JavaScript APIs that RPs can use to sign in with the IdP.
Create a well-known file
To prevent trackers from abusing the API, a well-known file must be served from /.well-known/web-identity
of eTLD+1 of the IdP.
For example, if the IdP endpoints are served under https://accounts.idp.example/
, they must serve a well-known file at https://idp.example/.well-known/web-identity
as well as an IdP config file. Here's an example well-known file content:
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
The JSON file must contain the provider_urls
property with an array of IdP config file URLs that can be specified as a path part of configURL
in navigator.credentials.get
by RPs. The number of URL strings in the array is limited to one, but this may change with your feedback in the future.
Create an IdP config file and endpoints
The IdP config file provides a list of required endpoints for the browser. IdPs will host this config file and the required endpoints. All JSON response must be served with application/json
content type.
The config file's URL is determined by the values provided to the navigator.credentials.get
call executed on an RP.
const credential = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
Specify a full URL of the IdP config file location as a configURL
. When navigator.credentials.get()
is called on the RP, the browser fetches the config file with a GET
request without the Origin
header or the Referer
header. The request doesn't have cookies and doesn't follow redirects. This effectively prevents the IdP from learning who made the request and which RP is attempting to connect. For example:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
All requests sent from the browser via FedCM include a Sec-Fetch-Dest: webidentity
header to prevent CSRF attacks. All IdP endpoints must confirm this header is included.
The browser expects a JSON response from the IdP which includes the following properties:
Property | Description |
---|---|
accounts_endpoint (required) | URL for the accounts list endpoint. |
client_metadata_endpoint (optional) | URL for the client metadata endpoint. |
id_assertion_endpoint (required) | URL for the ID assertion endpoint. |
branding (optional) | Object which contains various branding options. |
branding.background_color (optional) | Branding option which sets the background color of the "Continue as..." button. Use the relevant CSS syntax, namely hex-color , hsl() , rgb() , or named-color . |
branding.color (optional) | Branding option which sets the text color of the "Continue as..." button. Use the relevant CSS syntax, namely hex-color , hsl() , rgb() , or named-color . |
branding.icons (optional) | Branding option which sets the icon object, displayed in the sign-in dialog. The icon object is an array with two parameters:
|
Here's an example response body from the IdP:
{
"accounts_endpoint": "/accounts.php",
"client_metadata_endpoint": "/client_metadata.php",
"id_assertion_endpoint": "/assertion.php",
"branding": {
"background_color": "green",
"color": "0xFFEEAA",
"icons": [{
"url": "https://idp.example/icon.ico",
"size": 25
}]
}
}
Once the browser fetches the config file, it sends subsequent requests to the IdP endpoints:
If the RP deploys Content Security Policy (CSP) on the page FedCM is called and enforce connect-src
directive, they must explicitly allow endpoints described in the config file.
Accounts list endpoint
The IdP's accounts list endpoint returns a list of accounts that the user is currently signed in on the IdP. If the IdP supports multiple accounts, this endpoint will return all signed in accounts.
The browser sends a GET
request with cookies, but without a client_id
parameter, the Origin
header or the Referer
header. This effectively prevents the IdP from learning which RP the user is trying to sign in to. For example:
GET /accounts.php HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
The browser expects a JSON response that includes an accounts
property with an array of account information with following properties:
Property | Description |
---|---|
id (required) | Unique ID of the user. |
name (required) | Given and family name of the user. |
email (required) | Email address of the user. |
given_name (optional) | Given name of the user. |
picture (optional) | URL of the user avatar image. |
approved_clients (optional) | An array of RP client IDs which the user has registered with. |
Example response body:
{
"accounts": [{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"approved_clients": ["123", "456", "789"],
}, {
"id": "5678",
"given_name": "Johnny",
"name": "Johnny",
"email": "johnny@idp.example",
"picture": "https://idp.example/profile/456"
"approved_clients": ["abc", "def", "ghi"],
}]
}
If the user is not signed in, respond with HTTP 401 (Unauthorized).
The returned accounts list is consumed by the browser and will not be available to the RP.
Client metadata endpoint
The IdP's client metadata endpoint returns the relying party's metadata such as the RP's privacy policy and terms of service. RPs should provide links to their privacy policy and terms of service to the IdP in advance. These links are displayed in the sign-in dialog when the user hasn't registered on the RP with the IdP yet.
The browser sends a GET
request using the client_id
navigator.credentials.get
without cookies. For example:
GET /client_metadata.php?client_id=1234 HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity
The properties for the client metadata endpoint include:
Property | Description |
---|---|
privacy_policy_url (optional) | RP privacy policy URL. |
terms_of_service_url (optional) | RP terms of service URL. |
The browser expects a JSON response from the endpoint:
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
}
The returned client metadata is consumed by the browser and will not be available to the RP.
ID assertion endpoint
The IdP's ID assertion endpoint returns an assertion for their signed-in user. When the user signs in to an RP website using navigator.credentials.get()
call, the browser sends a POST
request with cookies and a content type of application/x-www-form-urlencoded
to this endpoint with the following information:
Property | Description |
---|---|
client_id (required) | The RP's client identifier. |
account_id (required) | The unique ID of the signing in user. |
nonce (optional) | The request nonce, provided by the RP. |
disclosure_text_shown | Results in a string of "true" or "false" (rather than a boolean). The result is "false" if the disclosure text was not shown. This happens when the RP's client ID was included in the approved_clients property list of the response from the accounts list endpoint or if the browser has observed a sign-up moment in the past in the absence of approved_clients . |
Example HTTP header:
POST /assertion.php HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=Ct60bD&disclosure_text_shown=true
On the server, the IdP should confirm that:
- The claimed account ID matches the ID for the account that is already signed in.
- The
Origin
header matches the origin the RP, registered in advance for the given client ID.
Since the domain verification on OAuth or OpenID Connect relies on a browser redirect, it's critical in FedCM that the IdP server checks an Origin
header value matches the RP's registered origin.
The browser expects a JSON response that includes the following property:
Property | Description |
---|---|
token (required) | A token is a string that contains claims about the authentication. |
{
"token": "***********"
}
The returned token is passed to the RP by the browser, so that the RP can validate the authentication.
Sign in to the relying party with the identity provider
Once the IdP's configuration and endpoints are available, RPs can call navigator.credentials.get()
to request allowing users to sign in to the RP with the IdP.
Before calling the API, you need to confirm that [FedCM is available on the user's browser]. To check if FedCM is available, wrap this code around your FedCM implementation:
if ('IdentityCredential' in window) {
// If the feature is available, take action
}
To request allowing users to sign in to the IdP from the RP, do the following, for example:
const credential = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
The providers
property takes an array of IdentityProvider
objects that have the following properties:
Property | Description |
---|---|
configURL (required) | A full path of the IdP config file. |
clientId (required) | The RP's client identifier, issued by the IdP. |
nonce (optional) | A random string to ensure the response is issued for this specific request. Prevents replay attacks. |
The browser handles sign-up and sign-in use cases differently depending on the existence of approved_clients
in the response from the accounts list endpoint. The browser will not display a disclosure text "To continue with ...." if the user has already signed up to the RP.
The sign-up state is determined based on whether the following conditions are fulfilled or not:
- If
approved_clients
includes the RP'sclientId
. - If the browser remembers that the user has already signed up to the RP.
When the RP calls navigator.credentials.get()
, the following activities take place:
- The browser sends requests and fetches several documents:
- The well-known file and an IdP config file which declare endpoints.
- An accounts list.
- Optional: URLs for the RP's privacy policy and terms of service, retrieved from the client metadata endpoint.
- The browser displays the list of accounts that the user can use to sign-in, as well as the terms of service and privacy policy if available.
- Once the user chooses an account to sign in with, a request to the ID assertion endpoint is sent to the IdP to retrieve a token.
- The RP can validate the token to authenticate the user.
FedCM is designed to not inform the RP of the user's IdP sign-in state until the user explicitly confirms to Continue as and signs in. This means RPs aren't informed of connection to the FedCM API if: the user isn't signed into the IdP, the accounts list endpoint returns an empty list, or the endpoint returns an error.
RPs are expected to support browsers which don't support FedCM, therefore users should be able to use an existing, non-FedCM sign-in process. Until third-party cookies are phased out completely, this should remain non-problematic.
Once the token is validated by the RP server, the RP may register the user or let them sign-in and start a new session.
Call FedCM from within a cross-origin iframe
FedCM can be invoked from within a cross-origin iframe using an identity-credentials-get
permissions policy, if the parent frame allows it. To do so, append the allow="identity-credentials-get"
attribute to the iframe tag as follows:
<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>
You can see it in action in an example.
Optionally, if the parent frame wants to restrict the origins to call FedCM, send a Permissions-Policy
header with a list of allowed origins.
Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")
You can learn more about how the Permissions Policy works at Controlling browser features with Permissions Policy.
Engage and share feedback
- GitHub: Read the proposal, raise issues and follow discussion.
- Developer support: Ask questions and join discussions on the Privacy Sandbox Developer Support repo.