w3c-fedid / FedCM

A privacy preserving identity exchange Web API
https://w3c-fedid.github.io/FedCM/
Other
375 stars 72 forks source link

Allow setting IDP login status from same-site subresources #537

Closed cbiesinger closed 2 months ago

cbiesinger commented 9 months ago

Background

The login status API currently only allow setting the login status on toplevel loads or for subresources who are same-origin with all their ancestors, both when using the JavaScript API and when using the HTTP header.

However, some IDPs want to use one origin for their FedCM endpoints but log in users on a different origin. With the same-origin restriction, this would require a toplevel redirect or opening a popup, which leads to disruptive user experiences especially if the current login flow does not depend on a top-level navigation.

Proposal

We are proposing to relax the same-origin restriction to a same-site (that is, same eTLD+1) restriction. For example:

// This is on a toplevel page on URL https://login.idp.example/
// FedCM endpoints are on https://fedcm.idp.example/
// We are logging in to the IDP.
function login(user, password) {
  if (checkPassword(user, password)) {
    window.cookie = 'loggedin=true';
    // This will send a `Set-Login: logged-in` header
    fetch('https://fedcm.idp.example/set-loggedin');
  }
}

function logout() {
  window.cookie = 'loggedin=false';
  // This will send a `Set-Login: logged-out` header
  fetch('https://fedcm.idp.example/set-loggedout');
}

The login status headers in this example will currently be ignored, but in the proposal would be processed.

Subsequent FedCM calls to https://fedcm.idp.example/fedcm.json would then be allowed:

// This is a toplevel page on https://www.rp.example
// We are logging in to the RP using FedCM with idp.example.

function loginWithIdp() {
  let token = await navigator.credentials.get({identity: {providers: [{
      configURL: "https://fedcm.idp.example/fedcm.json"}]}});
  // Now we are logged in with idp.example!
}

Because the initial login state for an IDP in Chrome is “unknown” and not “logged-out”, this example would actually work initially even in the absence of login status setters. However, if the user is not logged in to the IDP during the very first time FedCM is used with that IDP, we would mark the status as logged-out and require a valid login status header or JS call to update this status. Therefore, it is important that IDPs send a header that Chrome considers valid.

Identity Providers should consider making the subresource request with CORS and credentials included so that their endpoint can verify the correct login state.

Security & Privacy

The same-origin restriction was originally introduced so that an RP can not ‘artificially’ set an IDP’s login status by just making an invisible fetch() request or using an invisible iframe and thus allow potentially-tracking FedCM requests every time.

However, relaxing the restriction to a same-site restriction does not impact the privacy properties, because communication within a site with shared identifiers is already possible (using domain cookies) and is not considered a tracking vector.

User agents should process the login header under the same circumstances as a Set-Cookie header, i.e. as long as the network isolation key is not transient. Note that partitioned cookies use the site (registrable domain) as the partition key, which matches the same-site model in this proposal.

cbiesinger commented 2 months ago

This is fixed by the merged pull request mentioned above (#538)