From Chrome 122, the Disconnect API for Federated Credential Management API (FedCM) is available. The Disconnect API allows relying parties to disconnect their users from the identity provider's account without relying on third-party cookies. Also, there are a couple of updates to FedCM's same-site handling.
Disconnect API
When a user creates an account on a relying party (RP—the site using the identity provider for authentication) through identity federation, the identity provider (IdP—the service which provides authentication and account information to other parties) typically records the connection on its server. The stored connection allows the IdP to keep track of RPs that the user has signed into and optimize their experience. For example, to have a better experience when the user later returns to the RP, the user account with the IdP is treated as a returning account, which allows features such as auto reauthentication and personalized buttons showing the account used.
Sometimes, IdPs offer an API to disconnect the account from an RP. However, a disconnect flow is authenticated and requires the IdP cookies. In a world without third-party cookies, when the user visits the RP, there is no browser API for the RP to disconnect from the IdP. Because there may be multiple IdP accounts from the same IdP linked to a given RP, the disconnect flow requires knowing which account is being disconnected.
The Disconnect API allows the user to disconnect the IdP account from the RP on the browser as well as on the IdP server by signaling it to the specified endpoint. The user needs to have gone through identity federation using the Federated Credential Management API (FedCM). Once the user is disconnected, they are treated as a new user the next time they try to sign in to the RP using the IdP.
Disconnect the IdP from the RP
If a user has previously signed into the RP using the IdP through FedCM, the
relationship is memorized by the browser locally as the list of connected
accounts. The RP may initiate a disconnection by invoking the
IdentityCredential.disconnect()
function. This function can be called from a
top-level RP frame. The RP needs to pass a configURL
, the clientId
it uses
under the IdP, and an accountHint
for the IdP to be disconnected. An account
hint can be an arbitrary string as long as the disconnect endpoint can identify
the account, for example an email address or user ID which does not necessarily
match the account ID that the account list endpoint has provided:
// Disconnect an IdP account "account456" from the RP "https://idp.com/". This is invoked on the RP domain.
IdentityCredential.disconnect({
configURL: "https://idp.com/config.json",
clientId: "rp123",
accountHint: "account456"
});
IdentityCredential.disconnect()
returns a Promise
. This promise may throw an
exception for the following reasons:
- The user hasn't signed in to the RP using the IdP through FedCM.
- The API is invoked from within an iframe without FedCM permissions policy.
- The configURL is invalid or missing the disconnect endpoint.
- Content Security Policy (CSP) check fails.
- There is a pending disconnect request.
- The user has disabled FedCM in the browser settings.
When the IdP's disconnect endpoint returns a response, the RP and the IdP are disconnected on the browser and the promise is resolved. The disconnecting user accounts are specified in the response from the disconnect endpoint.
Set up IdP config file
In order to support the Disconnect API, the IdP must support a disconnect
endpoint and provide the disconnect_endpoint
property and its path in its IdP
config file.
{
"accounts_endpoint": "/accounts",
"id_assertion_endpoint": "/assertion",
...
"disconnect_endpoint: "/disconnect"
}
Disconnect the account on the disconnect endpoint
By invoking IdentityCredential.disconnect()
, the browser sends a cross-origin
POST
request with cookies and a content-type of
application/x-www-form-urlencoded
to this disconnect endpoint with the
following information:
Property | Description |
---|---|
account_hint |
A hint for the IdP account. |
client_id |
The RP's client identifier. |
POST /disconnect HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity
account_hint=account456&client_id=rp123
Upon receiving the request, the IdP server should:
- Respond to the request with CORS (Cross-Origin Resource Sharing).
- Verify that the request contains a
Sec-Fetch-Dest: webidentity
HTTP header. - Match the
Origin
header against the RP origin determine by theclient_id
. Reject if they don't match. - Find the account that matches the
account_hint
. - Disconnect the user account from the list of RP's connected accounts.
- Respond to the browser with the identified user's
account_id
in a JSON format.
An example response JSON payload looks like this:
{
"account_id": "account456"
}
If the IdP wishes the browser to instead disconnect all accounts associated with
the RP, pass a string that does not match any account ID, for example "*"
.
Checking /.well-known/web-identity
is now skipped when the RP and IdP are same-site
When developing a FedCM system, testing or staging RP server domains may be the
subdomains of the production IdP server. For example, the production IdP server
is at idp.example
and both the staging RP server and the staging IdP server
are at staging.idp.example
. However, since the well-known file must be placed
at the root of the IdP server's eTLD+1, it has to be at
idp.example/.well-known/web-identity
and it's the production server. Since
it's not necessarily possible for developers to place files in the production
environment while under development, this prevents them from testing FedCM.
Starting from Chrome 122, if the RP domain and IdP domain are the same, Chrome skips checking the well-known file. This way, developers will be able to test in such a scenario.
Subresources can now set same-site login status
Previously, Chrome has only allowed setting the login
status (for
example, using the Set-Login: logged-in
header) when the request is the
same-origin
with all ancestors. This prevented logins through the
same-site
fetch()
requests setting login status.
For example, think about a website that lets users enter their username and
password on idp.example
, but the credentials are posted to login.idp.example
with fetch()
. Recording the login status to the browser using the Login Status
API wasn't possible because the two domains are cross-origin and same-site.
With this change, we have relaxed the requirement for the Login Status API to be
the
same-site
with all ancestors and makes the above example possible to set
login.idp.example
's login status using an HTTP header (Set-Login:
logged-in
).
Summary
By using the Disconnect API, FedCM can now disconnect the RP from the IdP
without relying on third-party cookies. To do so, call
IdentityCredential.disconnect()
on the RP. With this function, the browser
sends a request to IdP's disconnect endpoint so that the IdP can terminate the
connection on the server, and then on the browser.
We've announced that /.well-known/web-identity
check is skipped when the RP
and the IdP are the same-site, for testing purposes. Also, setting a login
status through an HTTP response header from the same-site IdP subresource is now
possible.