title | maintainer | created | updated |
---|---|---|---|
Navigations |
samuelgoto |
01/01/2020 |
09/10/2020 |
This is an early exploration of the design alternatives to address this under this threat model.
This section goes over the what and the how. It presuposes that you have read and started from:
- The why: the problem statement and the motivations and the topology of the parties involved.
- The why not: the alternatives considered (e.g. the prior art, the status quo and the requestStorageAccess API).
We'll then go over the high-level overview and a breakdown into two smaller problems:
- The Consumer API (i.e. the interface between the RP and the Browser) and
- The Provider API (i.e. the interaction between the Browser and the IDP).
In the first part of the last section will go over the (slightly less controversial) Consumer API and the useful separation between:
- The Sign-in API and
- The Authorization API.
Finally, we'll then enumerate a series of alternatives for the (much more contentious) Provider API:
- The Permission-oriented Variation
- The Mediation-oriented Variation
- The Delegation-oriented Variation
From a high level perspective, the browser acts as an mediator between two parties: the relying party and the identity provider.
The browser exposes two distinct interfaces for the intermediation:
- The Consumer API to allow a relying party to request and receive an identity token and
- The Provider API to allow an identity provider to provide an identity token
We'll go over each of these separately next.
The consumer API is the Web Platform privacy-oriented API that relying parties call to request information from a specific identity provider, to be used in replacement of the current redirect/popup affordances that are currently used.
From the perspective of The Privacy Threat Model, there are two notably distinct uses of federation:
While both are implemented on top of OAuth as different scopes, the former (typically deployed with the openid
oauth scope) captures a meaningful volume of usage (we estimate it be around 80% of the use) at a much more controlled surface area (including transactions done at the front channel with idtokens as opposed to access tokens), whereas the latter is much more powerful and used less frequently (as well as done primarily on the back channel).
Lets first turn to the former use, and then go over authorization following that.
Simply put, the Sign-In API is a Web Platform affordance that takes an identity provider as input and returns a directed basic profile as output. It substitutes the navigational/popup affordances currently used.
We don't know yet exactly what it should look like, but here is an example that can serve as a starting point:
// This is just a possible starting point, largely TBD.
let {idToken} = await navigator.credentials.get({
provider: "https://accounts.example.com",
// other OpenId connect parameters
});
Another notable alternative worth considering is a declarative API that would allow embedding the user experience inline in the content area while still keeping the cross-origin separation before user consent. For example:
<input type=”idtoken” provider=”https://accounts.example.com”>
Upon invocation, the browser makes an assessment of the user's intention, for example making sure that the API was used as a result of a user gesture.
From there, the browser proceeds to mediate the data exchange with the chose identity provider via The Provider API.
Upon success, the consumer API results into a directed basic profile. For example:
{
"iss": "https://accounts.idp.com",
"sub": "110169484474386276334",
"aud": "https://example.com",
"iat": "2342342",
"name": "Sam G",
"email": "[email protected]",
"email_verified": "true",
"profile": "https://accounts.google.com/default-avatar.png",
}
The directed basic profile is signed into a JWT and then returned back to the relying party which can effectively get the user logged in. Here is an example of what a signed JWT looks like for the payload above.
Another notable form of deployment of federation is over top level navigations.
Because a significant part of federation is deployed over well-established protocols (e.g. OpenID, SAML), their HTTP profile is somewhat easy to spot. For example, for OpenID Connect requests/responses we could look at HTTP requests that have:
- a client_id parameter
- a redirect_uri parameter
- a scope parameter
- an accompanying .well-known/openid-configuration configuration
Responses can be matched when they match:
- a redirect to the previously used redirect_uri
- an id_token parameter
It is an active area of investigation to determine:
- which and how many of these patterns we would want to use (too few and you over-classify, too many and you under-classify),
- whether the same approach would work for other protocols (e.g. SAML).
- whether we need an opt-in / explicit API and if so which (e.g. perhaps a special URL marker, like a reserved URL parameter or a scheme)
Relying Parties often rely on more services from IDPs which are gathered via subsequent flows to get the user's authorization to release access to broader scopes. Notably, there is a long tail of these scopes, with little to no commonalities between them (say, access to calendar, photos, social graphs, etc).
To allow users to continue accessing broader scopes, we expose a new API to mediate that flow. For example:
navigator.credentials.requestAuthorization({
scope: "https://idp.com/auth/calendar.readonly",
provider: "https://idp.com",
});
Now that we looked at the surface area introduced for relying parties, lets turn into The Provider API and see what are the options under consideration for the intermediation between the user agent and the identity provider.
The purpose of the Provider API is to fulfill the invocation of The Consumer API by coordinating with the identity provider.
From the perspective of The Privacy Threat Model, the Provider API has a much wider set of choices and trade-offs:
- Because of the classification problem, we want to prevent a tracker from abusing this API by impersonating an IDP to track users.
- Because of the RP tracking problem, we want to promote directed identifiers as much as we can.
- Because of the IDP tracking problem, we want to keep IDPs involved only to the extent that they justifiably need to.
We also want to make sure that:
- There is a credible path towards eventual browser interoperability (e.g. firefox, safari, edge)
- The scheme reaches an economically viable equilibrium for all parties involved, from a design of incentives perspective
- The scheme handles gracefully federation on non-web platforms (e.g. Android, iOS, PlayStation, etc)
- We minimize the deployment and activation windows (e.g. server-side / client-side and user-behavior backwards compatibility) for relying parties and identity providers
- The scheme has a deliberate and well informed extensibility and ossification model, i.e. make extensible where innovation is constructive and ossify where there is less rapid iteration going on and there a direct value in terms of privacy/security.
We believe we all still have a lot to learn from each other (browser vendors, identity providers, relying parties, etc) in choosing the mean between the extremes of excess and deficiency with regards to the trade-offs of privacy, usability and economic viability.
Having said that, in the following section we'll enumerate some of the most prominent variations under consideration and their trade-offs.
We'll try to go over the thought process and the biggest considerations to be made starting from the most basic thing that we could do to some of the most involved.
The approaches are categorized into three general approaches:
- The Permission-oriented Variation
- The Mediation-oriented Variation
- The Delegation-oriented Variation
The simplest approach is to have WebID offer APIs that allow cross-origin data sharing for sign-in and authorization use cases that works much as they do today, but with the user agents providing warnings and consent moments to the user when new tracking risks appear.
An expanded exploration of this approach with its benefits and drawbacks can be seen here.
Naturally, the next set of formulations try to address these two shortcomings at the cost of the autonomy of the IDP and the ossification of parts of the flow.
In this formulation, the browser pulls the responsibility for itself to drive the profile exchange, enabling it to (a) bundle the consent moments described in the formulation above and (b) steer users to safer defaults.
An expanded exploration of this approach with its benefits and drawbacks can be seen here.
The last alternative under consideration enables the user agent to finally address the The IDP Tracking Problem mechanically.
In this formulation, the IDP delegates the presentation of identity assertions to the Browser. It accomplishes that by making the browser generate a public/private key pair and have the IDP sign a certificate attesting that the browser's private key can issue certificates for a certain JWT.
The biggest benefits of this variation are:
- The delegation mechanically solves the The IDP Tracking Problem: it keeps the IDP unaware of where the user is signing-into while still enabling the user to recover its account while moving around.
- Because there aren't any IDP Tracking Problem nor any RP Tracking Problem, this can possibly be a zero-prompt, consequence-free UX.
The biggest drawback of this variation is that it leads to a JWT that is not backwards compatible with the existing server-side deployment of relying parties (which are expecting the IDP to sign JTWs, not the Browser), which is O(K) hard to change.
An expanded exploration of this approach with its benefits and drawbacks can be seen here.
The Provider Authorization API fulfills the request from the Consumer Authorization API.
It is clearly not possible to enumerate all the various scopes that are in use, so it is clearer that:
- the IDP needs to be involved in the authorization flow
- the browser needs to apply the lowest common denominator policy (e.g. assume that the flow implies both the IDP Tracking Problem as well as the RP Tracking Problem)
To the best of our knowledge, we believe that business users (employees of a corporation) have a different set of privacy expectations compared to consumers, in that the accounts issued to employees are owned by the businesses (as opposed to the relationship a consumer has with social login providers). It is also clear to us too that the current deployment of businesses makes a non-trivial use of personal machines owned by employees, rather than machines that are issued by the business (which have a much easier ability to control enterprise policies).
We believe that the controls should take that distinction into consideration, and that the biggest challenge is adversarial impersonation.
This is still an active area of exploration, but to give a sense of direction, we are actively exploring making an abrupt separation between personal profiles and work profiles. The intuition here is that browser profiles are the closest delineation that can make a separation between personal use of your browser versus work use of your browser, along with the privacy expectations in each mode.
In addition to the separation, and with the user's permission/control/understanding, it seems like it would be beneficial for business admins to have the ability to set work policies on a per-profile basis.