This article explains how to try out FedCM in Google Chrome.
We will do our best to keep these instructions up to date as protocol and API changes occur. It will subsequently roll into downstream channels, but with lag in functionality and bug fixes since this is under development.
As of December 2022, FedCM API is available by default on Chrome (versions 108+). See here for a detailed guide on how to use the parts of the API that have been shipped!
Testing can be easier in Incognito mode, Guest mode or with single-use profiles if sign-up status persistence is not desired.
At the moment the only way to reset the sign-up status is to clear browsing data on the Chrome profile. This can be done from the [ClearBrowsing Data (chrome://settings/clearBrowserData)] [Settings] dialog. Under [Advanced] select the [Site Settings] checkbox. Also be sure the time range of data being cleared includes the time when the sign-up status was set.
To test experimental functionality:
- Download Google Chrome Canary. It is best to experiment with the latest build possible to get the most up-to-date implementation.
- FedCM is blocked if third party cookies are blocked. Ensure the Chrome
version you're using is not blocking third party cookies by navigating to
chrome://settings/cookies
. - Enable your experimental FedCM feature. This can be done directly from
chrome://flags
and searching 'fedcm' to see all available features.
The list of experimental features can be found here.
We have been experimenting with methods for helping session management features continue to work that currently rely on third-party cookies. So far the only implemented proposal is an API for Logout.
The Logout API, IdentityCredential.logoutRPs()
which is being explored as a way
to preserve OIDC front-channel logout and SAML Single Signout with loss of
access to third-party cookies in embedded contexts. It is intended to replace
situations where an IDP logging out a user also must log out the user in RP
contexts and would normally do it using iframes with each RP's known logout URL.
The API takes an array of URLs as an argument. For each URL, the browser determines if the user is known to have previously logged in to the RP using that IDP, and if it has, it sends a credentialed GET request to that URL.
IdentityCredential.logoutRPs([{
url: "https://rp1.example/logout",
accountId: "123",
}, {
url: "https://rp2.example/logout",
accountId: "456",
}]);
For security reasons, the IDP does not learn whether any of the network requests succeeded or failed.
To use the LoginHint API:
- Add an array of
hints
to the accounts described in the accounts endpoint:
{
accounts: [{
id: "accountId",
email: "[email protected]",
hints: ["hint", "otherHint"],
...
}, ...]
}
- Invoke the API with the
loginHint
parameter like so:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/config.json",
clientId: "123",
nonce: nonce,
loginHint : "hint"
}]
}
});
Now, only accounts with the "hint" provided will show in the chooser.
To use the UserInfo API:
- The RP must embed an IDP iframe, which will perform the query.
- The embedded iframe must receive permissions to invoke FedCM (via Permissions Policy).
- The user first needs to go through the FedCM flow once before invoking UserInfo.
- In a subsequent site visit, the IDP iframe may invoke UserInfo:
const user_info = await IdentityProvider.getUserInfo({
configUrl: "https://idp.example/config.json",
clientId: "client1234"
});
user_info.forEach( info => {
// It's up to the IDP regarding how to display the returned accounts.
// Accounts are sorted based on RP registration status.
const name = info.name;
const given_name = info.given_name;
const picture = info.picture;
const email = info.email;
}
To use the RP Context API:
- Provide the
context
value in JS, like so:
const {token} = await navigator.credentials.get({
identity: {
context: "signup",
providers: [{
configURL: "https://idp.example/fedcm.json",
clientId: "1234",
}],
}
});
Now, the browser UI will be different based on the value provided.
To use the IdP Sign-in Status API:
- Enable the experimental feature
FedCM with FedCM IDP sign-in status
inchrome://flags
. - When the user logs-in to the IdP, use the following HTTP header
IdP-SignIn-Status: action=signin
. - When the user logs-out of all of their accounts in the IdP, use the following HTTP header
IdP-SignIn-Status: action=signed-out
. - Add a
signin_url": "/idp_login.html
property to theconfigURL
configuration. - The browser is going load the
signin_url
when the user is signed-out of the IdP. - Call
IdentityProvider.close()
when the user is done logging-in to the IdP.
To use the Error API:
- Enable the experimental feature
FedCmError
inchrome://flags
. - Provide an
error
in the ID assertion endpoint instead of atoken
:
{
"error" : {
"code" : "access_denied",
"url" : "https://idp.example/error?type=foo"
}
}
Note that the error
field in the response including both code
and url
is
optional. As long as the flag is enabled, Chrome will render an error UI when
the token request fails. The error
field is used to customize the flow when an
error happens. Chrome will show a customized UI with proper error message if the
code is "invalid_request", "unauthorized_client", "access_denied", "server_error",
or "temporarily_unavailable". If a url
field is provided and same-site with
the IdP's configURL
, Chrome will add an affordance for users to open a new
page (e.g., via pop-up window) with that URL to learn more about the error on
that page.
To use the Auto-selected Flag API:
- Enable the experimental feature
FedCmAutoSelectedFlag
inchrome://flags
.
The browser will send a new boolean to represent whether auto re-authentication was triggered such that the account was auto selected by the browser in the flow to both the IdP and the API caller.
For IdP, the browser will include is_auto_selected
in the request sent to the
ID assersion endpoint:
POST /fedcm_assertion_endpoint HTTP/1.1
Host: 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&is_auto_selected=true
For the API caller, the browser will include a boolean when resolving the promise:
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/manifest.json",
clientId: "1234"
}]
}
});
const token = cred.token;
if (cred.isAutoSelected !== undefined) {
const isAutoSelected = cred.isAutoSelected;
}
To use the DomainHint:
-
Ensure that chrome://version shows 121.0.6146.0 or higher.
-
Enable the experimental feature
FedCmDomainHint
inchrome://flags
. -
Add an array of
domain_hints
to the accounts described in the accounts endpoint:
{
accounts: [{
id: "karenCorp1",
email: "[email protected]",
name: "Karen",
domain_hints: ["corp1", "corp2"],
}, {
id: "otherId",
email: "[email protected]",
name: "Karen",
}, {
id: "karenCorp3",
email: "[email protected],
name: "Karen",
domain_hints: ["corp3"],
}
}, ...]
}
- Invoke the API with the
domainHint
parameter like so:
// This will show the karenCorp1 account.
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/config.json",
clientId: "123",
nonce: nonce,
domainHint : "corp1"
}]
}
});
Now, only accounts matching the hint provided will show in the chooser.
You may also use "any" to show only accounts which list at least one domain hint.
// This will show the karenCorp1 and karenCorp3 accounts.
return await navigator.credentials.get({
identity: {
providers: [{
configURL: "https://idp.example/config.json",
clientId: "123",
nonce: nonce,
domainHint : "any"
}]
}
});
To use the Disconnect API:
- Ensure that chrome://version shows 121.0.6145.0 or higher.
- Enable the experimental feature
FedCmDisconnect
inchrome://flags
.
Add a disconnect endpoint to the FedCM config file. It must be same-origin with the config file.
{
"accounts_endpoint": "/accounts",
"id_assertion_endpoint": "/assertion",
...
"disconnect_endpoint": "/disconnect"
}
Implement the disconnect_endpoint
. It is fetched using a POST credentialed
request with CORS mode:
POST /disconnect HTTP/1.1
Host: idp.example
Referer: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity
account_hint=account456&client_id=rp123
The IdP can then disconnect the account and respond with the
Access-Control-Allow-Origin
and Access-Control-Allow-Credentials
headers to
satisfy CORS, and in the body of the response it should include a JSON with the
account ID of the account that has been disconnected.
{
"account_id": "account456Id"
}
When a user goes through the FedCM flow, the browser stores that (RP, IDP, account)
knowledge in browser storage in order to allow auto reauthn and User Info API to
work correctly in the future. If the browser finds an account in local storage
matching the ID provided, it will note the disconnection of that account. If the
IdP fails by either returning some network error or saying that the disconnection
was unsuccessful, or if the account_id
is nowhere to be found, the browser will
remove from local storage all of the federated accounts associated with the (RP,
IDP).
The button flow differs from the widget flow in several ways. The most significant difference is that the button flow requires a user gesture such as clicking on a sign-in button. This means that a user must be able to successfully sign in with a federated account using this flow. In contrast, the widget flow is an optimized flow that can reduce sign-in friction. This means that if the widget flow is unavailable, a user can still click a "Sign in with IdP" button to continue. See illustrative mocks here.
To use the Button Mode API:
- Enable the experimental feature
FedCmButtonMode
inchrome://flags
. - Make sure to invoke the API behind transient user activation.
- Invoke the API with the
mode
parameter like so:return await navigator.credentials.get({ identity: { providers: [{ configURL: "https://idp.example/config.json", clientId: "123", nonce: nonce }], mode: "button" } });
The browser will send a new parameter to the IdP representing the request type by including
mode=button
in the request sent to the ID assersion endpoint:
POST /fedcm_assertion_endpoint HTTP/1.1
Host: 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&is_auto_selected=false
&mode=button
Note that we currently only include the new parameter in the button flow. Other flow types such as "widget" (name TBD) will be added when Chrome ships this feature.
This API allows users to use other accounts in the account chooser when, for example, IdPs support multiple accounts or replacing the existing account.
To use the Use Other Account API:
- Enable the experimental feature
FedCmUseOtherAccount
inchrome://flags
. - IdP specifies the following in the FedCM config file:
{
"accounts_endpoint" : ...,
"modes: {
"button": {
"supports_use_other_account": true|false,
}
}
}