# How does FedCM work and how do I use it?

> FedCM (Federated Credential Management) is a browser API for signing in with an identity provider without third-party cookies or redirects. Your page calls navigator.credentials.get with the provider’s config URL; the browser fetches the accounts itself, shows a “Continue as” prompt, and returns a token only after the person continues. Chrome and Edge support it, and loginos is one such provider.

FedCM (Federated Credential Management) is the browser API behind the “Continue as Jane” prompts that appear on some sites, including Google One Tap in Chrome. Your site asks the browser for a sign-in with an identity provider. The browser talks to the provider, draws the prompt and hands your page a token.

Until the person continues, your site learns nothing about them, and the provider can’t tell which of its users is on your site. FedCM is a [draft standard](https://w3c-fedid.github.io/FedCM/) of the W3C Federated Identity Working Group, and Chrome has shipped it since version 108, in 2022.

## Why does FedCM exist?

FedCM exists because federated sign-in used to rely on the same tools that trackers use. Sign-in buttons and one-tap prompts ran in iframes from the provider’s domain, which read the provider’s cookies as third-party cookies. Third-party cookies let embedded content follow people across sites, so browsers restrict them:

- Safari blocks third-party cookies by default.
- Firefox gives each site its own cookie jar (Total Cookie Protection).
- Chrome blocks them in Incognito and for people who turn them off. Google planned to remove them for everyone, then decided in 2024 and 2025 to leave the choice to users. In October 2025, Google said it keeps supporting FedCM.

FedCM replaces the iframe with the browser itself. The browser fetches the provider’s endpoints and draws its own prompt. No request carries both the provider’s cookies and your site’s origin until the person has agreed. Sign-in keeps working where third-party cookies don’t, and the browser can tell a real sign-in from tracking.

## Who does what in FedCM?

FedCM has three parties:

- The **relying party (RP)** is your site. It has a client ID from the provider and calls the API.
- The **identity provider (IdP)** holds the accounts, like Google or loginos. It serves a few JSON endpoints that only the browser calls.
- The **browser** fetches those endpoints, draws the prompt and enforces the privacy rules.

A sign-in runs in six steps:

1. Your page calls `navigator.credentials.get()` with the IdP’s config URL and your client ID.
2. The browser checks the IdP’s login status. If the IdP said nobody is signed in, a page-load call stops here without any request.
3. The browser fetches the IdP’s well-known file and config file without cookies. Then it fetches the accounts endpoint with the IdP’s cookies, but without saying which site is asking.
4. The browser shows the prompt over your page. Your page sees nothing.
5. When the person continues, the browser posts to the IdP’s ID assertion endpoint, now with your origin and client ID, and gets a token back.
6. Your page receives an `IdentityCredential`. It sends `credential.token` to your server, which validates it.

## What does the identity provider serve?

A FedCM identity provider serves a set of endpoints, and the browser treats each one differently:

| Endpoint | Returns | Sends the IdP’s cookies | Tells the IdP the site |
| --- | --- | --- | --- |
| `/.well-known/web-identity` | Where the config file is | No | No |
| Config file | The other endpoints, a `login_url` and branding | No | No |
| Accounts endpoint | The accounts signed in to the IdP | Yes | No |
| Client metadata endpoint | Your privacy policy and terms links | No | Yes |
| ID assertion endpoint | A token for your site | Yes | Yes |
| Disconnect endpoint | The account that was disconnected | Yes | Yes |

The **well-known file** sits at the root of the IdP’s registrable domain, while the config file can live anywhere. The two-step lookup stops an IdP from putting your site’s name in the config URL to track people. The file lists the config file in `provider_urls`. An IdP with a client metadata endpoint must also name its `accounts_endpoint` and `login_url` there:

```json title="/.well-known/web-identity"
{
  "provider_urls": ["https://accounts.idp.example/fedcm/config.json"],
  "accounts_endpoint": "https://accounts.idp.example/fedcm/accounts",
  "login_url": "https://accounts.idp.example/login"
}
```
```json title="Config file"
{
  "accounts_endpoint": "https://accounts.idp.example/fedcm/accounts",
  "client_metadata_endpoint": "https://accounts.idp.example/fedcm/client-metadata",
  "id_assertion_endpoint": "https://accounts.idp.example/fedcm/assertion",
  "disconnect_endpoint": "https://accounts.idp.example/fedcm/disconnect",
  "login_url": "https://accounts.idp.example/login",
  "branding": { "background_color": "#1a1a2e", "color": "#ffffff" }
}
```
```json title="Accounts endpoint"
{
  "accounts": [{
    "id": "1234",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "picture": "https://accounts.idp.example/avatars/1234.png",
    "approved_clients": ["your-client-id"]
  }]
}
```

**Every FedCM request carries `Sec-Fetch-Dest: webidentity`.** Pages can’t set headers that start with `Sec-`, so the header shows that the browser’s FedCM code sent the request, not a script on another site. Check it on the accounts, ID assertion and disconnect endpoints, and refuse requests without it.

The **ID assertion endpoint** is where the IdP decides. It gets a form post with the page’s origin:

```http title="ID assertion request"
POST /fedcm/assertion HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example
Cookie: idp_session=…
Content-Type: application/x-www-form-urlencoded
Sec-Fetch-Dest: webidentity

client_id=your-client-id&account_id=1234&is_auto_selected=false&params=%7B%22nonce%22%3A%228f2c1a%22%7D
```

The IdP must check that the `Origin` belongs to that client ID, because the browser can’t: client IDs mean nothing to it. It answers with JSON like `{"token": "…"}` and the CORS headers `Access-Control-Allow-Origin: https://rp.example` and `Access-Control-Allow-Credentials: true`. The token can be anything the IdP likes, such as an ID token or a one-time code. Instead of a token, the IdP can return an `error`, or a `continue_on` URL that the browser opens in a popup for extra steps.

The **Login Status API** tells the browser whether anyone is signed in to the IdP. The IdP sends `Set-Login: logged-in` or `Set-Login: logged-out` on its own responses, or calls `navigator.login.setStatus()` on its pages. While the status is logged-out, the browser skips the accounts request and a page-load call fails quietly. A call from a click opens the IdP’s `login_url` in a small window instead, and the sign-in page calls `IdentityProvider.close()` when it is done.

## How does a site call FedCM?

A site calls FedCM with one `navigator.credentials.get()` call. Check for support first, because only some browsers have it:

```js title="Your page"
async function signInWithFedCM(nonce) {
  if (!("IdentityCredential" in window)) return null; // use a popup or a redirect instead
  return navigator.credentials
    .get({
      identity: {
        context: "signin",
        providers: [{
          configURL: "https://accounts.idp.example/fedcm/config.json",
          clientId: "your-client-id",
          params: { nonce }, // random, from your server, checked there again
        }],
      },
      mediation: "optional",
    })
    .catch(() => null); // closed, or nobody signed in
}
```

These options shape the prompt:

- **`mode`**: `"passive"`, the default, can run on page load and shows nothing when the person isn’t signed in to the IdP. `"active"` must run from a click, takes exactly one provider, shows a larger dialog and can open the IdP’s sign-in window. Chrome added `mode` in version 132; before that it called these the widget and button modes.
- **`mediation`**: `"optional"`, the default, lets the browser sign a returning person in by itself. `"silent"` does that or fails without any UI, and `"required"` always asks.
- **`context`**: `"signin"`, `"signup"`, `"use"` or `"continue"` changes the prompt’s wording.
- **`loginHint`** and **`domainHint`** show only the accounts that match.
- **`params`**: whatever the IdP needs, like a `nonce`. The spec moved `nonce` here, and the old top-level `nonce` is deprecated.

Automatic sign-in, called auto-reauthentication, only happens for someone who signed in to your site with FedCM before and has one returning account. The credential then has `isAutoSelected` set to `true`, and Chrome does it at most once every 10 minutes. When someone signs out of your site, call `navigator.credentials.preventSilentAccess()`, so the browser doesn’t sign them straight back in. `IdentityCredential.disconnect({ configURL, clientId, accountHint })` removes the connection entirely. In Chrome 136 and later, a passive call can list several providers, and the browser shows all their accounts in one prompt.

## Which browsers support FedCM?

As of October 2026, FedCM works in Chromium-based browsers only:

| Browser | FedCM |
| --- | --- |
| Chrome | Yes, since version 108 (2022), on desktop and Android |
| Edge, Opera, Samsung Internet | Yes, as Chromium-based browsers |
| Firefox | No. Its implementation sits behind a preference that is off by default. Firefox 138 added the Login Status API on its own. |
| Safari | No, on macOS or iOS |

Newer parts arrived later in Chrome: the Login Status API in version 120, `disconnect()` in 122, `mode` and `params` in 132, and several providers in one call in 136. Treat FedCM as an addition: keep a popup or redirect sign-in for browsers without it. [MDN’s FedCM page](https://developer.mozilla.org/docs/Web/API/FedCM_API) tracks support in detail.

## How loginos does it

loginos is a FedCM identity provider. It serves the provider side for you: the well-known file, a config file at `https://loginos.io/fedcm/config.json`, the accounts, client metadata, ID assertion and disconnect endpoints, and the login status. Its ID assertion endpoint only answers pages on your platform’s [domains](https://loginos.io/docs/domains.md), and the token it returns is a one-time code. Your server exchanges that code at [`/oauth/token`](https://loginos.io/docs/oidc.md#post-oauth-token) like a code from the redirect flow, without `redirect_uri`.

You don’t call FedCM yourself. The browser SDK makes the calls and adds a fallback for other browsers:

| SDK call | In Chrome and Edge | In other browsers |
| --- | --- | --- |
| `prompt()` | `get()` in passive mode with `mediation: "optional"` | Resolves `null` |
| `prompt({ auto: false })` | The same, with `mediation: "required"` | Resolves `null` |
| `signIn()` | `get()` in active mode with `mediation: "required"` | Opens a small loginos window |

`signOut()` calls `preventSilentAccess()`, and `disconnect()` calls `IdentityCredential.disconnect()`. The SDK sends the nonce both in `params` and at the top level, so older Chrome versions work too.

```html title="HTML"
<script src="https://loginos.io/sdk/v1.js"></script>
<script>
  const loginos = Loginos.init({ appKey: "YOUR_APP_KEY" });
  const finish = (result) =>
    result &&
    fetch("/api/auth/login/single/token", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(result), // { code, nonce, via }
    });
  loginos.prompt().then(finish);
  document.querySelector("#sign-in").onclick = () => loginos.signIn().then(finish);
</script>
```

The [Continue as docs](https://loginos.io/docs/continue-as.md) have the server route that checks the ID token’s `nonce`, and [How do I add a one-tap “Continue as” login?](https://loginos.io/answers/continue-as-one-tap-login.md) covers testing and the headers that break the window. loginos offers loginos accounts only. If people should sign in with their Google or Microsoft accounts, you need those providers, and if you want to be the identity provider yourself, the endpoints above are what you build.

## Frequently asked questions

### Does FedCM replace OAuth and OpenID Connect?

No. FedCM replaces the browser part of a sign-in: the redirect or the iframe becomes a prompt the browser draws. What the token is, and how your server checks it, is still up to the identity provider. Google One Tap returns an ID token, for example, while loginos returns a code that your server exchanges with standard OpenID Connect.

### Does FedCM need third-party cookies?

No. The browser sends the identity provider’s cookies only to the provider’s own FedCM endpoints, so FedCM works when third-party cookies are blocked. The provider’s session cookie must be `SameSite=None`, because these requests start from another site.

### Is FedCM only for Google accounts?

No. [Google One Tap](https://loginos.io/answers/google-one-tap-alternative.md) uses it in Chrome, but any identity provider can serve the endpoints. Seznam, a Czech internet company, offers its accounts through FedCM, and loginos does too. A site can only use a provider that has given it a client ID.

### Can I use FedCM inside an iframe?

Yes, if the parent page allows it. FedCM is a policy-controlled feature named `identity-credentials-get`, and by default only same-origin frames may use it. Add `allow="identity-credentials-get"` to a cross-origin iframe that needs it.

---

Updated 2026-10-14. Web page: https://loginos.io/answers/how-fedcm-works
