Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

Brokering FedCM via an on-device application

TL;DR;

This document goes over an extension to FedCM to allow it to talk to a local application as an intermediary to the Identity Provider (IdP). Native application brokers are a class of native applications that run outside the scope of the web browser and can interact with an Identity Provider (IdP) to sign a user in. This is useful in scenarios where a given application might be signed into an IdP and the in-browser web application wants to leverage this sign in state for browser scenarios. It could also be used for web applications that want to leverage the sign in state of the operating system itself.

Context

FedCM is a Web Platform API that allows the browser to intermediate Relying Parties requesting accounts from Identity Providers.

It does so by introducing a protocol that a cooperating relying party (a website you are trying to log in to) and identity provider (a website that you are already typically logged in) have to conform to, allowing the browser to mediate between the two.

More details about FedCM here:

The Problem

A key aspect of the FedCM protocol is that there are two endpoints that are exposed by the Identity Provider that require the user to be logged in to the IdP: the accounts endpoint and the id assertion endpoint.

The first is an endpoint that, given a session cookie, returns all of the accounts that the user is logged in to, which the browser uses to build a mediated account chooser. The second is an endpoint that, given a session cookie and a specific account, which the browser uses to generate a cryptographic token that allows the user to login to the website.

This often works well on desktop, because, for the most part, the user is logged in to their identity providers on desktop in the browser (think, google.com, facebook.com, twitter.com, github.com, microsoft.com, gmx.de, web.de, etc), and so the user gets to reuse these accounts to login to other websites.

The problem is that this is not universal on the desktop and is far less the case on mobile devices: In those cases, users are largely logged in to native applications (e.g. the facebook native app, the GMX native email app, a company managed Authenticator app, etc.) rather than their web counterparts (e.g. facebook.com or gmx.de website).

For some IdPs, a meaningful part of their users are not seamlessly logged in to their Web Apps.

The Proposal

The proposal being explored here is to introduce a new transport for FedCM, called FedCM-Over-Services, that the browser can use to talk to locally installed Apps as an alternative to HTTP, and vice versa (as a mechanism that the native app can use to talk to the browser).

In this proposal, the browser takes a FedCM request as it normally would, but now supports a new convention that allows a cooperating application to expose itself as a FedCM Identity Provider.

Each native platform works differently, so each requires integration with native apps differently:

Android

On Android, the browser and the IdP's native app talk to each other in two ways:

  1. Bound Services (org.w3.FedCM). These carry the credentialed requests FedCM needs to make without showing any UI: the accounts endpoint and the id assertion endpoint. They use the standard Messenger/Bundle protocol, with request and reply message codes. The payloads are the same JSON that the HTTP endpoints return.
  2. Activities launched through Intents. These cover the interactive steps: the Continuation API (continue_on), the IdP login URL (login_url) and full delegation of the sign-in UI to the app in active mode (org.w3.fedcm.ACTION_ACTIVE_MODE_VIEW). The app returns its result with Activity.setResult().

All of the other uncredentialed requests are made through HTTP (e.g. the well-known file, the config file, the client metadata endpoint).

The Bound Service transport is a graceful fallback: the browser always fetches the accounts endpoint over HTTP with cookies first. It only tries the native app if that fetch fails.

For enterprise scenarios, policy can be set in the browser to specify which type of transport to attempt first, or possibly to mandate a specific transport.

On the IdP side, the IdP is required to expose a Service (a) in their manifest file and (b) as a class that extends Service, and respond to requests for the accounts endpoint and the id assertion endpoint.

When the IdP receives a message, it uses its internal OS storage to get their session credentials and is responsible for making HTTP requests to their backends on their own (e.g. without requiring the IdP to keep the cookies in sync between the app and the browser).

The IdP is able to reliably determine who is calling the app (via Message.sendingUid) and needs to make a determination if it should reply to it or not (e.g. it can hard code the list of browsers as trusted callers).

On the Browser side, the browser assumes that the IdP is complying to the convention, and degrades gracefully when they are not (e.g. invalid responses or app not installed), just like it handles HTTP errors (400s and 500s).

The browser uses Digital Asset Links to make sure it is talking to the right app, before binding to a service or launching an activity.

Note

In Chromium, this is implemented behind the FedCmNativeIdPs feature (chrome://flags/#fedcm-native-idps).

For example, lets say a website, say rp.com, calls into the FedCM API to get accounts from idp.com:

const credential = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.com/fedcm.json",
    }]
  }
});

The browser would go through its usual FedCM flow and at some point figure out that the user is not logged in to idp.com.

The browser can then try to see if the user is logged in to the equivalent native application for idp.com.

The end-to-end flow looks like this:

sequenceDiagram
    participant RP as rp.com (web page)
    participant B as Browser
    participant W as idp.com (HTTP)
    participant A as com.idp.app (native)

    RP->>B: navigator.credentials.get({identity})
    B->>W: GET well-known, config (uncredentialed)
    B->>W: GET accounts_endpoint (with cookies)
    W-->>B: error / not signed in
    B->>B: queryIntentServices("org.w3.FedCM")
    B->>B: Verify the package against idp.com via Digital Asset Links
    B->>A: bindService() + Message{url: accounts_endpoint}
    A-->>B: Message{reply: accounts JSON}
    B->>RP: Show account chooser
    RP->>B: User selects an account
    B->>A: Message{url: id_assertion_endpoint, body: POST data}
    A-->>B: Message{reply: {"token": ...} or {"continue_on": ...}}
    B-->>RP: Resolve promise with token
Loading

Origin Verification

Before the browser talks to an app on behalf of an origin, it needs to know that the app really represents that origin (e.g. that “com.idp.app” speaks for https://idp.com).

On Android, this is established with a bi-directional statement between the origin and the app: (a) the https origin needs to point to the app and (b) the app needs to point to the https origin. This is the same mechanism used by Verified App Links:

https://developer.android.com/training/app-links/verify-applinks

The way the first statement (a) is made is with Digital Asset Links: a well-known file (e.g. https://www.example.com/.well-known/assetlinks.json) that is hosted in an origin and describes which apps can act on its behalf.

For FedCM, the browser checks for the delegate_permission/common.use_as_origin relation. This is the relation IdPs already publish for Trusted Web Activities, Custom Tabs and Auth Tab. For example, the following .well-known file states that, for “https://www.example.com”, the "com.example.app" android package name (signed with the given sha256\_cert\_fingerprints) can act as that origin:

[{
  "relation": ["delegate_permission/common.use_as_origin"],
  "target" : { "namespace": "android_app", "package_name": "com.example.app",
               "sha256_cert_fingerprints": ["hash_of_app_certificate"] }
}]

The second statement (b) is made in the AndroidManifest.xml file that is shipped with every Android App.

For example, the following snippet in and AndroidManifest.xml file states that “com.example.app” can handle “https://www.example.com/products\*” urls:

<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW" />               
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data
    android:scheme="https"
    android:host="www.example.com"
    android:pathPrefix="/products" />
</intent-filter>

If only statement (b) was made, without a corresponding (a) from the origin, any malicious app would be able to intercept and handle urls from other apps (e.g. “my.malicoius.app” could intercept “https://facebook.com” urls). If only statement (a) was made, without a corresponding (b) statement, any malicious origin could drive traffic to any app (e.g. “https://malicious.com” could make every link clicked on Android go to the wrong app).

When both (a) and (b) are used in conjunction, Android is able to verify that a specific app’s intent filter is responsible for handling a specific set of URLs.

This is used on a variety of things, but most notably on deep-linking: if an android user using an email client app clicks on https://www.example.com/products/1234.html, the user is directed to “com.example.app” rather than the default browser.

The browser runs the same verification for every kind of native interaction (Bound Services, Continuation/Login activities and delegated UI activities):

  1. It asks PackageManager for all the packages that handle the relevant intent (e.g. queryIntentServices(new Intent("org.w3.FedCM"))).
  2. It checks the candidate packages one at a time against the IdP origin's Digital Asset Links (use_as_origin), using the same origin verifier that Chrome uses for Trusted Web Activities and Custom Tabs.
  3. It picks the first package that verifies. If no package verifies, the browser acts as if no app were installed.

When those conditions are met, the browser is able to connect to a service in an Android App that is guaranteed to represent the origin.

Package Visibility

The browser discovers FedCM apps by querying for the intents they handle. On Android 11+, a browser that doesn't hold the broad QUERY_ALL_PACKAGES permission can declare these intents inside <queries> instead, so it gets least-privilege package visibility:

See for more information: https://developer.android.com/training/package-visibility/declaring

<queries>
  <!-- Discover Bound Services for the Accounts and ID Assertion endpoints -->
  <intent>
    <action android:name="org.w3.FedCM" />
  </intent>

  <!-- Discover Continuation API / Login activities -->
  <intent>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:mimeType="application/web-identity+json" />
  </intent>

  <!-- Discover activities that accept a fully delegated sign-in UI -->
  <intent>
    <action android:name="org.w3.fedcm.ACTION_ACTIVE_MODE_VIEW" />
  </intent>
</queries>

The Accounts and Id Assertion Endpoint

Once the browser knows what the package name is, it uses the agreed-upon ahead of time convention of FedCM-Over-Services.

When the transport is used

  • Accounts endpoint. The browser first fetches the accounts_endpoint over HTTP with cookies, exactly like regular FedCM. If that fetch doesn't produce a valid accounts list (for example the user isn't signed in, the request returned an HTTP error, or the response was invalid or empty), the browser resolves and binds to the IdP's native app and sends it the same request. If the native app also fails (no verified app installed, connection failure, invalid JSON), the request fails just as it would have without native app support.
  • ID assertion endpoint. If the accounts came from the native app, the browser sends the id_assertion_endpoint request to the same native app, over the same bound connection. Otherwise it goes over HTTP.

The browser keeps one connection per IdP origin for the whole FedCM transaction, so the accounts and id assertion requests reuse the same binding. The browser unbinds from the service when the transaction ends, or when the service dies or disconnects (any in-flight request then fails).

The message protocol

The service is identified by the org.w3.FedCM intent action. The browser and the app exchange Android Messages, and their Bundles carry the following keys:

Direction Message.what Bundle key Type Description
Browser → App 1 (request) url String The endpoint being requested, e.g. the accounts_endpoint or id_assertion_endpoint URL from the IdP config file.
Browser → App 1 (request) body String (optional) The request body. For the id assertion endpoint, it is byte-for-byte the application/x-www-form-urlencoded POST body the browser would have sent over HTTP (client_id, nonce, account_id, disclosure_text_shown, params, …). Absent for the accounts endpoint.
Browser → App 1 (request) headers Bundle of String → String (optional) Extra request headers. Reserved; not currently sent.
App → Browser 2 (response) reply String A JSON string in exactly the same format as the corresponding HTTP endpoint response.

The browser sets Message.replyTo on the request, and the app sends its response back to that Messenger. If the app replies with any other what code or with no reply, the browser treats it as a failed fetch.

Because the reply uses the HTTP JSON formats, everything built on top of those responses works unchanged. For example, the id assertion reply can be any of:

{ "token": "..." }
{ "continue_on": "https://idp.com/continue?..." }
{ "error": { "code": "access_denied", "url": "https://idp.com/error" } }

A continue_on reply triggers the Continuation API as usual, which itself may be served by a native activity.

Browser side

At run time, after origin verification has resolved a package and service name, the browser binds to the service and sends it the request:

Intent intent = new Intent("org.w3.FedCM");
intent.setComponent(new ComponentName(verifiedPackageName, verifiedServiceName));

ServiceConnection connection = new ServiceConnection() {
  @Override
  public void onServiceConnected(ComponentName name, IBinder service) {
    Messenger serviceMessenger = new Messenger(service);

    Message msg = Message.obtain();
    msg.what = 1; // MSG_FEDCM_REQUEST
    Bundle bundle = new Bundle();
    bundle.putString("url", "https://idp.com/fedcm/accounts");
    // For the id assertion endpoint only:
    // bundle.putString("body", "client_id=123&nonce=456&account_id=1234&...");
    msg.setData(bundle);

    msg.replyTo = new Messenger(new Handler(Looper.getMainLooper()) {
      @Override
      public void handleMessage(Message reply) {
        if (reply.what != 2) { /* MSG_FEDCM_RESPONSE; treat as failure */ return; }
        String json = reply.getData().getString("reply");
        // Parsed exactly like the HTTP accounts / id assertion response.
      }
    });
    serviceMessenger.send(msg);
  }

  @Override
  public void onServiceDisconnected(ComponentName name) {
    // Any in-flight request fails.
  }
};

context.bindService(intent, connection, Context.BIND_AUTO_CREATE);

IdP side

The cooperating Identity Providers must have had, ahead of time, declared that it supports the agreed upon service in their Android manifest file:

<service android:name=".FedCMService" android:exported="true">
  <intent-filter>
    <action android:name="org.w3.FedCM" />
  </intent-filter>
</service>

Which then, at run time, gets the message from the browser:

public class FedCMService extends Service {
  static final int MSG_FEDCM_REQUEST = 1;
  static final int MSG_FEDCM_RESPONSE = 2;

  private final ExecutorService executor = Executors.newSingleThreadExecutor();

  class IncomingHandler extends Handler {
    IncomingHandler() { super(Looper.getMainLooper()); }

    @Override
    public void handleMessage(Message msg) {
      // Checks that the calling app is trustworthy
      // e.g. should probably use the browsers allow list
      String callingApp = getPackageManager().getNameForUid(msg.sendingUid);
      if (!TRUSTED_BROWSERS.contains(callingApp)) {
        return;
      }
      if (msg.what != MSG_FEDCM_REQUEST) {
        super.handleMessage(msg);
        return;
      }

      Messenger replyTo = msg.replyTo;
      String url = msg.getData().getString("url");
      String body = msg.getData().getString("body"); // null for accounts

      // Network calls to the IdP's backend must happen off the main thread.
      executor.execute(() -> {
        String replyJson;
        if (url.endsWith("/fedcm/accounts")) {
          replyJson = "{\"accounts\":[{\"id\":\"1234\",\"name\":\"Alice\",\"email\":\"alice@idp.example\"}]}";
        } else if (url.endsWith("/fedcm/assertion")) {
          replyJson = "{\"token\":\"" + mintTokenFor(body) + "\"}";
        } else {
          replyJson = "{\"error\":{\"code\":\"invalid_request\"}}";
        }

        Message reply = Message.obtain(null, MSG_FEDCM_RESPONSE);
        Bundle bundle = new Bundle();
        bundle.putString("reply", replyJson);
        reply.setData(bundle);
        try {
          replyTo.send(reply);
        } catch (RemoteException e) {
          // The browser went away.
        }
      });
    }
  }

  @Override
  public IBinder onBind(Intent intent) {
    return new Messenger(new IncomingHandler()).getBinder();
  }
}

When the native IdP Android Application replies back to the browser, it can return credentialed responses like the accounts endpoint and the id assertion endpoint, using its own internal storage to authenticate to its backend services.

Continuation API and Login URL

Some steps need the user to interact with the IdP. For example, the IdP may need multi-step authentication or explicit user interaction (such as accepting terms of service or selecting a profile), and then it returns a continue_on URL from the id assertion endpoint. Or the user may not be signed in to the IdP at all, and the browser has to open the IdP's login_url.

Instead of opening these URLs in a Custom Tab, the browser can send them directly to the IdP's installed Android application.

Intent Resolution & MIME Type

When the browser needs to open a continue_on or login_url URL, it queries PackageManager for an activity that can handle:

  • Action: Intent.ACTION_VIEW
  • Category: Intent.CATEGORY_BROWSABLE
  • Data URI: The continue_on / login_url URL
  • MIME Type: application/web-identity+json

If a matching app is installed and verified via Digital Asset Links (delegate_permission/common.use_as_origin) for the URL's origin, the browser launches the activity directly (with startActivityForResult). Otherwise, or if the launch fails, the browser falls back to opening the URL in a Custom Tab, as it would without native app support.

AndroidManifest.xml Example

<activity
    android:name=".FedCmContinuationActivity"
    android:exported="true">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https"
              android:host="idp.example"
              android:pathPrefix="/continue" />
        <data android:mimeType="application/web-identity+json" />
    </intent-filter>
</activity>

Native Equivalent of IdentityProvider.resolve() and IdentityProvider.close()

When the user completes the continuation flow inside the native IdP activity, the app returns the resulting ID assertion token back to the browser via Activity.setResult():

// Inside FedCmContinuationActivity after successful user sign-in
Intent resultIntent = new Intent();
resultIntent.putExtra("org.w3.fedcm.TOKEN", idAssertionToken);
setResult(Activity.RESULT_OK, resultIntent);
finish();

The browser interprets the activity result as follows:

Activity result Meaning
RESULT_OK with an org.w3.fedcm.TOKEN string extra The native equivalent of IdentityProvider.resolve(token). Only valid for a continue_on launch: it immediately resolves the pending navigator.credentials.get() promise in the relying party's web page.
RESULT_OK without a token The user has finished signing in to the IdP. Only valid for a login_url launch: the browser marks the IdP as signed in (the equivalent of Set-Login: logged-in) and fetches the accounts again.
Anything else (e.g. RESULT_CANCELED) The native equivalent of IdentityProvider.close(). The flow is treated as dismissed by the user.

If an app returns a token for a login_url launch, or a token-less RESULT_OK for a continue_on launch, the browser rejects the request.

Delegating the Sign-In UI to the Native App

In some cases, the IdP would rather show its own native account chooser than have the browser show its accounts bottom sheet. For example, the IdP may want its native UI for multi-account management, step-up authentication, or other flows that the browser's UI doesn't support.

The IdP config file (fedcm.json) stays platform-neutral. Instead, the IdP signals this choice at run time in its accounts endpoint response (over HTTP or over the Bound Service):

{ "error": "use_native_ui_delegation" }

The browser only honors this signal in active mode (mode: "active", i.e. called from a user gesture such as a button click) with a single IdP in the request. In every other case, the response is treated as an invalid accounts response.

When the signal is honored, the browser skips its account chooser. It resolves a Digital Asset Links-verified activity for the IdP's config URL and launches it with the following intent:

Intent field Value
Action org.w3.fedcm.ACTION_ACTIVE_MODE_VIEW
Category Intent.CATEGORY_DEFAULT
Data URI The IdP config URL (e.g. https://idp.com/fedcm.json)
org.w3.fedcm.RP_ORIGIN extra The origin of the top-level relying party (e.g. https://rp.com).
org.w3.fedcm.ASSERTION_PARAMS extra The URL-encoded parameters the browser would have POSTed to the id_assertion_endpoint: client_id, nonce, mode, fields, params, type, …. It is built by the same code as the HTTP request body, so new parameters automatically reach native apps too. account_id and disclosure_text_shown are empty, because the app runs its own account chooser and disclosure UI.
org.w3.fedcm.LOGIN_HINT extra (optional) The loginHint passed by the RP, if any.
org.w3.fedcm.DOMAIN_HINT extra (optional) The domainHint passed by the RP, if any.

The browser does not launch the app if the request was dismissed while verification was in progress, or if the browser is currently not allowed to show UI (e.g. while an automated agent is driving the tab). In those cases, and when no verified app is found, the request is treated as dismissed.

The IdP declares the activity in its manifest:

<activity
    android:name=".FedCmSignInActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="org.w3.fedcm.ACTION_ACTIVE_MODE_VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="https" android:host="idp.com" />
    </intent-filter>
</activity>

And returns its result with Activity.setResult(). Exactly one of a token or an error code is expected:

// Success: resolves navigator.credentials.get() with the token.
Intent result = new Intent();
result.putExtra("org.w3.fedcm.TOKEN", token);
setResult(Activity.RESULT_OK, result);

// Failure: the native equivalent of the id assertion endpoint's Error API.
Intent result = new Intent();
result.putExtra("org.w3.fedcm.ERROR_CODE", "access_denied");
result.putExtra("org.w3.fedcm.ERROR_URL", "https://idp.com/error?code=access_denied"); // optional
setResult(Activity.RESULT_OK, result);

finish();

The browser trusts the native app's error exactly as much as an IdP HTTP error response. It resolves ERROR_URL against the config URL and rejects the request if the error URL is cross-site with the IdP. Any other result (e.g. RESULT_CANCELED, or RESULT_OK without a token or error code) is treated as the user dismissing the flow.

Note

These intent action and extra names are a public contract between browsers and IdP apps. They are namespaced under org.w3.fedcm and must not change once shipped.

The Login Status API

Note

This part is still under development in Chromium: the service is registered, but it does not yet persist the login status.

The browser exposes itself as a Bound Service that conforms to a certain convention that accepts “SetLogin” requests from native IdPs.

<service
  android:name=".LoginStatusService"
  android:exported="true">
  <intent-filter>
    <action android:name="org.w3.FedCM.LOGIN_STATUS" />
  </intent-filter>
</service>

And the corresponding browser implementation:

/** Android Bound Service accepting login status updates from external native IdP applications. */
@NullMarked
public class LoginStatusService extends Service {
    private static final String TAG = "LoginStatusSvc";

    public static class LoginStatusBinder extends Binder {
        public boolean setLoginStatus(String status, String origin) {
            // ... writes to browser storage ...
            return true;
        }
    }

    private final IBinder mBinder = new LoginStatusBinder();

    @Override
    public @Nullable IBinder onBind(Intent intent) {
        return mBinder;
    }
}

So, ahead of time, the browser expects that the Android native app would tell the browser when their users are logging in and out of their native apps.

In Chromium's implementation, LoginStatusService is implemented as an exported Bound Service that accepts login status updates from native IdP applications.

iOS

Needs definition. This is doable on enterprise managed devices through some of the enterprise management services on the platform, a consumer focused implementation would need some investigation.

Mac

Needs definition. We do this today with Edge and Chrome plugins to tunnel into a native broker.

Windows

Needs definition. We do this today with Edge and Chrome plugins to tunnel into a native broker.

Relationship with Native App Payment Handlers

FedCM Native App IDPs build upon the architectural precedence established by Android Native Payment Handlers (used by the Web PaymentRequest API). Both mechanisms solve a fundamental challenge: allowing a Web API in the browser to discover, verify, and delegate credential or transaction workflows to an installed native Android application representing a web origin.

Shared Architectural Patterns

  1. Zero-Configuration Relying Parties: Relying parties call standard Web APIs (navigator.credentials.get() or new PaymentRequest()) with HTTPS config URLs. The browser transparently detects whether an installed Android application can fulfill the request without relying party code changes.
  2. Bi-Directional Origin Verification: Both systems require two-way cryptographic verification before invoking an app:
    • The web origin must declare the Android application's package name and certificate fingerprint in .well-known/assetlinks.json.
    • The Android application must declare support for the origin in its AndroidManifest.xml.
  3. Activity Result Protocol: When launching interactive UX (such as a payment sheet, a continuation/login screen, or a delegated sign-in UI), both APIs use Android Activity results (Activity.setResult(Activity.RESULT_OK, resultIntent)) to return cryptographic tokens or responses back to the browser tab.

Intentional Architectural Simplifications in FedCM

While Payment Handlers established the foundation, FedCM Native App IDPs introduce several intentional simplifications:

  • Origin Verification (DAL): Payment Handlers require both Digital Asset Links (handle_all_urls) and an HTTP-fetched Payment Method Manifest (payment-manifest.json). FedCM requires only Digital Asset Links (delegate_permission/common.use_as_origin), eliminating extra network requests since use_as_origin is already widely deployed by Identity Providers for AuthTab and Custom Tabs.
  • App Discovery & Filtering: Payment Handlers use <meta-data> tags (default_payment_method_name or @array) in AndroidManifest.xml to filter candidates before verification. FedCM queries all services declaring org.w3.FedCM and relies strictly on DAL verification (delegate_permission/common.use_as_origin) to filter authorized apps, keeping manifest declarations minimal.
  • IPC Mechanism: Payment Handlers use formal AIDL interfaces (IsReadyToPayService.aidl) and typed Android Parcelables. FedCM uses Android Messenger and Bundle with plain string keys (url / body / headers for requests, reply for responses) whose payloads mirror the HTTP endpoints, providing a lightweight protocol that avoids AIDL version-skew across independent IdP app updates while reusing FedCM's standardized JSON schemas.

References and Further Reading

WebViews

We currently have FedCM disabled in WebViews, and I think that, with this mechanism, we would be able to enable it.

Because FedCM, running in the WebView’s process space can leverage the native application state directly to gather the users account, and has the ability to then use the continuation API in its own address space, we would enable federation to work on WebViews with the following properties:

  • The user isn’t required to login (or to be logged in) to the IdP in the calling App’s process space (e.g. in the WebView’s cookie jar)
  • The IdP shares with the calling App’s process space an JWT / access token, which is narrowly scoped to the specific app, allowing the user to login to the App with the IdP
  • The IdP shares with the calling App’s process space enough information to construct an account chooser (namely, the user’s name/email/picture)

Because FedCM is already distributed with JS SDK across without requiring websites (and apps) to change, this can be deployed at scale to all apps using webviews.

Security Considerations

Privacy Considerations

We don’t think there are any privacy considerations that go beyond what has already been considered in FedCM: the ability to talk to Android native apps only changes the transport, but maintains the privacy properties of the protocol that’s running on top of it.

Open Questions

  1. Can background services make external HTTP requests?
    1. Yes, just out of the main thread, so need an Executor

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors