FedCM and Browser Privacy: Designing Account Flows for a New Context
A practical guide to Federated Credential Management, its browser-visible boundaries, and testing account recovery without cross-site tracking assumptions.
Want the structured docs for Identity?
This article lives in the editorial library. For step-by-step setup, reference material, and ongoing updates, jump into the docs section.
Federated Credential Management, usually called FedCM, gives a browser-mediated path for an identity provider to help a relying party sign a user in. Depending on the account and prior permission, the browser may ask the user to choose or approve an account; an eligible returning user may instead be automatically reauthenticated without the same chooser. The application must treat first approval and return sign-in as separate states, and must not assume every flow displays an account chooser. This changes the integration boundary: an application no longer needs to make an embedded identity provider behave like an unrestricted third-party cookie store.
FedCM is an identity API, not a universal sign-in button and not a way to identify an unknown browser. Availability, account state, user consent, browser settings, and the identity provider's policy all affect the result. A product should define the account journey and its fallback before adding a browser API. Use it only for an identity relationship that the user and the participating services are allowed to establish.
Map each public flow to the current W3C FedCM RP sign-in algorithm: the signin request and returned credential are covered there; first-time account creation is described by request permission to sign-up; and returning-account automatic reauthentication is the eligible-account branch of the same sign-in algorithm. This is a reader-checkable boundary: record whether the test used signin, whether a permission surface appeared, whether IdentityCredential.isAutoSelected was true, and whether the server accepted the returned audience and expiry. None of those observations authorizes an account by itself, and a browser that omits a prompt is not evidence of an unknown person or device.
What the browser-mediated flow changes
In a conventional federated flow, a relying party can redirect to an identity provider or embed provider content and then exchange a response. Historically, an embedded provider could also depend on third-party cookies to remember a session. Privacy changes reduce that ambient access. FedCM moves a selected part of the account chooser and assertion exchange into a browser-controlled surface, so the provider can support a user-approved relationship without making every site request the provider's cross-site state.
The browser still does not decide whether an account is authorized for an application. The relying party validates the returned assertion on its server, checks audience and expiry, applies its own account-linking rules, and creates the session that the application actually uses. A successful browser prompt is not proof of an application's authorization policy, and a missing prompt is not proof that a person or device is unknown.
The user-visible account chooser is an important boundary. The browser can show which identity provider and account are involved, while the relying party receives only the information allowed by the protocol and the provider's configuration. The product should explain why sign-in is offered, what account relationship will be created, and what happens when the user declines. Do not hide a decline behind an endless redirect or make unrelated public content depend on a credential.
FedCM does not make all requests private. The relying party still receives the assertion result and can associate the resulting session with activity on its own site. The identity provider still operates its account service and may process the request needed to issue a response. Review URLs, request bodies, logs, analytics, redirects, support tooling, and deletion together. A browser-mediated chooser limits one class of ambient signal; it does not replace a data-minimization review.
The exact API surface and enrollment requirements vary by browser release. Read the browser's current developer documentation and the provider's integration contract, then record the supported release range. Avoid publishing a claim that every browser displays the same prompt or exposes the same account fields. Compatibility guidance is more useful when it names the tested flow and its fallback.
Define the relying-party contract
Start with the relying-party user journey. Identify the page where the user asks to sign in, the accounts that can be offered, the consent or disclosure text, and the application state that must survive a cancel or retry. An identity assertion completes a narrow, visible task such as creating a session or linking an account. It does not silently enroll a user in unrelated analytics or promotional measurement.
Keep account linking explicit. If the user is already signed in locally, show whether the FedCM account will sign in, link, or replace the current account. Require a deliberate action before combining records. If two local accounts would conflict, preserve the current work and provide a recovery route rather than choosing an account based on a browser signal.
The server should validate every response. Check the assertion's issuer, audience, nonce or request binding, expiry, and any provider-specific signature. Rate-limit failed exchanges and make replay handling deterministic. Keep provider credentials and signing keys outside browser logs and source-controlled fixtures. A redacted event can record that validation failed without retaining the full token.
Session creation must have a clear lifetime. Set cookies and other session state according to the application's security policy, rotate or revoke them when the account changes, and expose a sign-out action that actually ends the relying-party session. Do not treat a long-lived browser account chooser as a substitute for server-side logout, account recovery, or permission checks.
An application can support more than one identity provider. Present the choices in terms the user understands, and state whether the providers create separate accounts or can be linked. A provider that is unavailable should not block passwordless, local, or support-approved recovery if those alternatives are part of the product. Keep the fallback accessible and do not repeatedly reopen a declined chooser.
Consent, disclosure, and user control
The first prompt should answer three questions: which service is asking, which account will be used, and what the application will do after approval. Keep the explanation near the action that starts the flow. If the provider returns a display name or avatar, use it only for the stated purpose and let the user correct an unexpected account before a session is created.
Consent is not a permanent authorization for every future operation. Ask again when the relying party changes the purpose, account-linking relationship, or data requested. Store the minimum consent record needed to honor the decision and provide a way to revoke the relying-party session or unlink the account. A browser's remembered choice and the product's legal or contractual consent record are related but not interchangeable.
A declined prompt is a normal product outcome. Leave public features usable, show a local sign-in or recovery route when available, and explain whether the user can try again later. Avoid wording that implies the browser is broken or that the user must disclose an identity to read public material. The accessible status should say what action is available next.
Account selection can expose sensitive context. Do not place provider account identifiers, tokens, or detailed profile data in URLs, screenshots, analytics labels, or exception messages. If support needs to distinguish two synthetic accounts, use a test-only label that does not reveal a real address. Delete temporary fixtures after the support case closes.
The relying party should also explain what happens after sign-out. A user may sign out of the application while the provider remains signed in, or may revoke the provider relationship separately. The interface should distinguish those actions and avoid claiming that one has erased the other. Link to the provider's account controls when the user needs to manage the upstream relationship.
Third-party cookie and storage boundaries
FedCM can reduce an integration's dependence on third-party cookies, but it does not grant a general storage exception. A provider should not assume that a cookie read inside an iframe will work merely because the user approved a FedCM account. The relying party should store only its own session state, and the provider should document any separate first-party route needed for account management.
Storage partitioning can make an embedded provider appear new under a different top-level site. That is a context result, not evidence about the person's identity. The storage partitioning guide explains how to design an empty-context path and a user-controlled first-party handoff. Keep that boundary visible when the sign-in flow opens a provider page.
Do not use FedCM outcomes as a fingerprinting signal. A prompt may be unavailable because the browser, account state, user setting, permission, policy, or release does not support the flow. A prompt may appear for a synthetic account without saying anything about a device. Branch on the user-visible function, not on a collection of browser properties or timing measurements.
Network signals need the same restraint. A provider exchange can reveal the IP address and request metadata required by the service, while the relying party sees its own request context. Review proxy, DNS, WebRTC, and telemetry handling independently; the network identity privacy guide covers why a sign-in result should not be treated as a stable network identity.
Deletion should cover both sides of the relationship. The relying party should remove its session and account-link record according to its retention policy. The provider should offer its own unlink or account-management path. Document which records are required for fraud prevention or audit and which can be removed immediately. Do not retain a full assertion merely because an account once used FedCM.
Build a resilient fallback
A complete flow has a browser-mediated path, a first-party provider path, and a recovery path chosen for the product's audience. The fallback does not work around a browser policy. It is a user-visible route for a browser or provider combination that does not support the primary API, for a user who declines, or for an account that needs help.
The first-party route should use a short-lived, server-authorized handoff. Do not place a credential in the URL. Bind the reference to the intended relying party, account action, and expiry, then invalidate it after use. If the user cancels, the relying party should retain the current form or draft and return to a known screen.
Recovery needs its own ownership and rate limits. Offer account lookup, support verification, or a local credential only where the product already authorizes those choices. Do not ask the user to upload unrelated browsing history or to disable browser privacy controls. Every recovery result should state whether a session was created, whether work was preserved, and what the user can do next.
Failures should be classified before retry. A missing browser API, an unavailable provider account, a declined prompt, an invalid assertion, an expired handoff, and a server timeout have different owners. Record a small redacted event with flow stage, application revision, browser family and version, provider category, and visible outcome. Avoid capturing the entire token or profile when the small packet answers the support question.
Keep an accessible status for each branch. A screen reader user should hear that account selection is available, that approval was cancelled, or that recovery needs another action. Keyboard focus should move to the heading or error that explains the next step. A disabled sign-in control should have a reason and a nearby alternative when the application has one.
Account-flow fallback acceptance matrix
Use the W3C RP sign-in algorithm and the MDN FedCM API reference as the protocol sources. Run each row with synthetic accounts and accept it only when the observable result matches the application contract.
| Observable starting condition | Primary action | User-visible fallback | Acceptance evidence |
|---|---|---|---|
| FedCM is unavailable or the provider cannot offer an account | Do not open a chooser | Offer the first-party provider route or approved recovery | No credential is sent; the fallback page is announced; no relying-party session exists until server validation succeeds |
| The user declines the chooser | End the FedCM attempt | Keep public content and show local sign-in or recovery | The event records declined; current work remains; no session is created |
| The user cancels, the handoff expires, or the server times out | Stop the exchange and invalidate the reference | Return to the known screen with a bounded retry | The page states that sign-in was not completed, the draft is preserved, and a retry cannot reuse the expired reference |
| The assertion fails issuer, audience, nonce, signature, or expiry checks | Reject the response server-side | Show the approved recovery route | The server returns a non-success result, stores only a redacted stage, and the UI never claims sign-in succeeded |
| The returned account conflicts with the signed-in local account | Do not link or replace records automatically | Ask for an explicit link, switch, or recovery choice | Existing work and session remain unchanged until the user confirms; the final session maps to one account |
End-to-end acceptance walkthrough
Use the W3C algorithm and MDN API reference above as the source of truth for the browser steps, and use the provider's documented configuration as the source of truth for eligibility. In a normal product flow, a user opens Sign in, the relying party calls FedCM from a clean test profile, and the configured provider offers one synthetic account. The browser shows the account chooser; after approval, the relying party sends the returned assertion to its server. The server validates issuer, audience, nonce, signature, and expiry, creates exactly one relying-party session, and returns the user to the saved task with an accessible success message. The evidence packet contains the flow stage, provider category, validation result, session result, and visible message, but never the assertion itself.
Use controlled negative runs to identify the owner of a failure:
| Observed result | How to distinguish it | Required acceptance result |
|---|---|---|
| API unavailable | navigator.credentials or the FedCM method is absent or blocked before a provider request | No chooser or credential exchange; show the approved first-party route and record api_unavailable |
| User refusal | The chooser was shown and the synthetic user selected cancel or decline | Record declined; preserve the task; create no session; offer local sign-in or recovery |
| Provider configuration | The API is callable, but the provider is not eligible or cannot offer the configured test account | Record provider_not_configured or provider_account_unavailable; send no assertion to session creation; show the provider route or recovery |
| Server assertion validation | A chooser result reaches the server, but issuer, audience, nonce, signature, or expiry validation fails | Return a non-success result, record only the redacted validation stage, create no session, and show recovery |
The test passes only when the branch label, network behavior, server session state, preserved work, and user-visible message agree. This separates a browser capability result from a user choice, provider setup, and server trust decision without treating any one result as an identity signal.
Test with synthetic accounts
Use provider accounts and relying-party accounts created for the test environment. Start with a clean profile and a known provider state, then test a returning profile separately. Do not place personal addresses, production assertions, or real recovery codes in fixtures. Keep provider and relying-party data in separate systems with separate deletion owners.
Cover the complete user journey: opening the sign-in control, seeing the account chooser, approving, declining, cancelling, returning to the application, using an allowed automatic reauthentication path, signing out, and recovering the account. Assert the visible application result, not just that a JavaScript callback ran. A returning-account test should verify the prior grant, the absence or presence of a chooser, and the resulting server session separately. A test passes only when the server creates the intended session and the page communicates the result accessibly.
Test account edge cases. Use two synthetic accounts, an account already linked to a different local user, an expired provider session, and a provider account that cannot be offered. Check that the application does not silently replace current work or merge records. Verify that a user can return to the previous task after each branch.
Test browser and storage differences without turning them into identity conclusions. Run supported browser families and release ranges with the same application revision, provider configuration, and synthetic data. Record whether FedCM was available, what prompt appeared, the user action, the server result, and the fallback used. If a release changes the prompt or availability, update the support matrix rather than declaring a universal platform change.
Test interruption and recovery. Close the chooser, reload during the callback, lose the network after approval, expire the handoff, and restart the browser. The application should avoid duplicate sessions, preserve non-sensitive form input, and offer a bounded retry. A failed exchange must not be shown as a completed sign-in.
Automated browser tests should keep one profile owner per session. The profile integration guide describes how to isolate storage, record browser identity, and close sessions cleanly. FedCM assertions belong at the application boundary: account choice, server validation, session state, and user messaging. They should not depend on an unrelated list of browser fingerprint values.
Release review and operations
Review the flow when the browser, identity provider, relying-party code, account-linking policy, consent text, or storage model changes. Repeat the same synthetic journey and compare user-visible outcomes. Keep a small fixture set with a stated purpose: first approval, decline and fallback, returning account, account conflict, and recovery. This makes it possible to distinguish runtime, dependency, and application changes.
Publish release notes that name the affected application flow and whether a user needs to act. Do not describe a browser prompt change as a universal conclusion about all platforms. If a fallback is temporarily required, say which browser or provider range is affected and how the user can continue. Remove the note when the tested support matrix changes.
Operational dashboards should report functional events rather than raw identity material. Useful fields include approval or decline, exchange success, fallback reason, recovery completion, and application revision. Keep retention short enough for support and reliability work, restrict access, and provide deletion for temporary test data. Aggregates must not be used to reconstruct a cross-site identity graph.
Incident response should protect the user's current work. If assertion validation fails after a form was filled, keep the form where policy permits, explain the status, and offer the approved recovery path. Do not clear the profile or copy cookies as a first response. Capture the smallest redacted evidence packet, quarantine the failing fixture, and retire it after the investigation.
The product owner should periodically verify unlinking and deletion. Sign-out must end the relying-party session, an unlink action must update the account relationship, and an expired handoff must no longer work. Verify these controls in a clean profile and a returning profile. A privacy-preserving identity flow is complete only when its failure, recovery, and deletion paths are as clear as its approval path.
Support training should use the same vocabulary as the interface. Explain the difference between a provider account, a relying-party session, a linked local account, and a recovery reference. When a support case crosses those boundaries, ask for the smallest synthetic or redacted identifier that locates the failing stage. This avoids asking a user to send a token or a complete browser profile merely to answer a routing question.
Accessibility and localization are part of the identity contract. Translate the provider name, account purpose, decline result, and recovery action without changing their meaning. Test long account names, right-to-left layouts where supported, zoom, reduced motion, and keyboard-only approval. A prompt that is technically available but cannot be understood or reached is not a usable sign-in path.
Keep the integration reversible. A provider or browser release can change availability, so the application should be able to disable the primary path for a bounded audience and continue with the approved fallback. Record the change, the affected flow, and the user action in the release log. Reversibility limits the impact of an unexpected runtime or dependency change while preserving the user's account choices.
Public sources
The W3C FedCM document linked here is a First Public Working Draft, and the MDN API page labels the browser support surface as limited and experimental. Treat those pages as protocol and compatibility references, then verify the provider, browser release, and server contract that the application actually supports.
Related Articles
Take BotBrowser from research to production
The guides cover the model first, then move into cross-platform validation, isolated contexts, and scale-ready browser deployment.