Browser support for opting out of sync during the Firefox signin flow
Categories
(Firefox :: Firefox Accounts, enhancement)
Tracking
()
Tracking | Status | |
---|---|---|
firefox71 | --- | verified |
People
(Reporter: rfkelly, Assigned: eoger)
References
Details
Attachments
(2 files)
As part of Bug 1570565, we will be adding signin flows to Firefox that result in the user being signed in to the browser, but do not enable sync. The current Firefox signin flow is triggered from the following URL:
https://accounts.firefox.com/?service=sync&context=fx_desktop_v3
Which is, pretty clearly, specific to Sync. We will need to adjust the FxA authentication broker to allow signing in to the browser and enabling other services without enabling Sync and without requiring sync-specific messaging in the flow.
We're still working out some of the details, but I wanted to get this on file for the purposes of tracking the work. Next steps here are to confirm the designed UX for:
- The about:welcome signin flow, in which sync should be optional
- The about:protections signin flow, in which sync should not be mentioned at all
Once we understand the scope of the UX we'll be able to fill in the details of the underlying protocol. I'm pretty hopeful that it won't be a significant change, but don't want to get too far ahead of the UX here.
Reporter | ||
Comment 1•5 years ago
|
||
The about:protections signin flow, in which sync should not be mentioned at all
I'm going to narrow the scope of this but to be just about making sync optional in the about:welcome flow, and spin out a separate bug for the protection-report changes.
I've started a proposal for the FxA-side changes in a corresponding github issue here:
https://github.com/mozilla/fxa/issues/2396
:markh could you please take a look at that proposal and see if it makes sense to you?
Reporter | ||
Comment 2•5 years ago
|
||
A note to self that, if we go the route of removing service=sync
from the signin URL, we'll also need to update all the places where we check that service value post-signin, such as:
- When linking out to various management pages, like "manage account" and "manage devices".
- When deciding whether to allow fxa_status.
Reporter | ||
Comment 3•5 years ago
•
|
||
Here's a summary of the planned changes to the interactions between Firefox and accounts.firefox.com to make Sync optional.
I'm going to walk through it in what may seem like excruciating detail, so that we can use this as a reference for secreview as well as to guide implementation. But I'm not wedded to any of the particular naming conventions etc used here.
The flow for signing in to Firefox involves the following steps, where I am using "FxA" as shorthand to mean "web content running on https://accounts.firefox.com":
- Launch the flow. This involves opening FxA with special query parameters that trigger the behaviours below.
- Status Handshake. FxA sends a
fxaccounts:fxa_status
webchannel message to the browser, telling it about the signin flow that's about to start. The browser replies with some information about its capabilities, which can be used to customize the flow. - User signin. The user enters their credentials in FxA. It sends a
can_link_account
webchannel message to tell the browser the claimed identity of the user, and the browser may reply telling FxA to abort the signin. We use this to show a warning if you're signing in to a browser that may contain another user's data. - Choose what to sync. For new signups, FxA shows a "choose what to sync" page where the user can decide which datatypes to sync. The options displayed are based on the capabilities reported by the browser in step (2).
- Login complete. FxA sends a
fxaccounts:login
webchannel message to the browser, which contains the user's id and email, various auth tokens and keys, and the results of the choose-what-to-sync screen if any.
From there, the browser has everything it needs access the user's account and sync their data up to the cloud.
The current implementation of this flow assumes that the user is signing in to use sync. We're going to keep that flow as-is, but add some extra hooks so that the browser can opt-in to a modified flow where the user has a choice about whether or not to sync at all.
1. Launch the flow
The current flow is launched by navigating to the following URL:
We'll add support for entering this flow without the service
query parameter, which will make FxA responsible for asking the user what services to enable:
2. Status Handshake
The current fxaccounts:fxa_status
handshake message from FxA to the Browser contains the following fields:
fxa_status: {
service: [the service query param, if any],
isPairing: [whether it's trying to execute a pairing flow (which it won't be in this case)],
}
As noted in Comment 2, the browser uses this information to decide whether it will share any existing sign-in state back to web content. Since we may not be connecting for any particular service, let's have this message also echo back the context
parameter, so that code like this can check for context=fx_desktop_v3
rather than service=sync
. So the new message would look like:
fxa_status: {
// As above, plus...
context: [the context query param, if any; "fx_desktop_v3" in this case],
}
The browser responds to this message with a description of its capabilities, and information about the currently-signed-in user (if any):
{
signedInUser: [various sign-in state info, which we're not planning to change],
capabilities: {
engines: [list of sync engines to show on the CWTS page],
pairing: [whether this browser supports the pairing flow],
},
We can modify this response to signal that this browser supports the new, sync-optional signin flow. I think we should also return the OAuth client id for Desktop Firefox in order to replace some uses of service=sync on the backend. So the new response would look like:
signedInUser: [as above],
clientId: "5882386c6d801776", // This is the OAuth client_id for Firefox itself
capabilities: {
// As above, plus...
multiService: true,
},
If context=fx_desktop_v3
was specified but service=sync
was not, and if the browser does not report multiService=true
, we should consider showing an error. Whatever the user was trying to achieve, it probably won't work out.
3. User signin
I don't believe we intend to change anything here. If the user is trying to sign in to a browser where another user was previously signed in, they'll get a wanring about possibly merging their sync data with that other user. The warning is not wrong, but it might be a bit weird for users who don't intend to sync.
Since we're only interested in signing in from about:welcome for now, I think it's safe to assume this flow will almost always be used on a new profile, and we won't expose any users to this weirdness in practice
4. Choose what to sync
If service=sync
was provided in step (1), then behaviour at this step doesn't change - FxA will show the CWTS screen to new signups and will proceed immediately to step (5) for existing users.
If the service
parameter was not provided, we use the new UX provided by :rfeeley. New signups see the CWTS screen with an option to "Don't sync this device", while existing users see a new screen where they have to explicitly choose whether or not to sync this device.
In the future, we'll want a way to signal that we're signing in to Firefox for some other reason, such as to view Monitor data in about:protections. The details of that are deliberately out of scope in this proposal, but the intention is that we do not show any CWTS screens in such a flow.
5. Login complete
The current fxaccounts:login
webchannel message from FxA to the Browser contains the following fields (with some irrelevant ones omitted):
fxaccounts:login {
data: {
// User profile data.
uid,
email,
// Authentication tokens
sessionToken,
keyFetchToken,
unwrapBKey,
// Data from CWTS, if shown
offeredSyncEngines: ["bookmarks", "history", "passwords"],
declinedSyncEngines: ["passwords"],
}
}
For browsers that do not report {multiService: true}
in their capabilities handshake, this message will be unmodified. Such browsers are assumed to always be signing in to Sync.
For browsers that do report {multiService: true}
in their capabilities handshake, we will move the CWTS data into a new services
key, like this:
fxaccounts:login {
data: {
// User profile data, as above.
// Authentication tokens, as above.
// What services the user asked us to enable, and any configuration info for them.
services: {
// In this case, the user asked to enable sync.
sync: {
offeredEngines: ["bookmarks", "history", "passwords"],
declinedEngines: ["passwords"],
}
}
}
}
If the services
object contains a sync
key, then the user opted-in to sync (either explicitly, or by starting the flow with service=sync
in the query params). If it does not, then the user opted out of sync and it should not be enabled in the browser.
Note that even if the user opts out of sync, the browser is still capable of syncing at this point - the authentication tokens and key material provided in the fxacounts:login
message give it essentially full access to any data in the user's account. It's up to the browser to respect the user's choice.
Open questions
How should the browser behave if it receives an fxaccounts:login
message when a user is already signed in? This can happen for legitimate reasons, e.g. if the user changes or resets their password on the web in a signed-in browser. We'll need to be careful that we don't accidentally enable or disable sync in this case.
Reporter | ||
Comment 4•5 years ago
|
||
Mark, Vlad, does the above match your expectations? As I said, I'm not wedded to any names etc here, but wanted to capture the changes to the flow so there's something concrete to discuss as part of the review in Bug 1570572.
Comment 5•5 years ago
|
||
Yes, that sounds great.
How should the browser behave if it receives an fxaccounts:login message when a user is already signed in?
This can happen for legitimate reasons, e.g. if the user changes or resets their password on the web in a signed-in browser.
Can we assume that in those legitimate reasons there will be no/an empty services
object? If so, I guess the browser could use that - although that still means FxA could remotely enable sync, which could be considered either a feature or not :) So another option is simply that if FxA is already configured when we get that message, we refuse to even look at services
? I've no strong opinion here.
Reporter | ||
Comment 6•5 years ago
|
||
Can we assume that in those legitimate reasons there will be no/an empty services object?
Not sending services
in this case seems reasonable to me.
Reporter | ||
Comment 7•5 years ago
|
||
I'd like to add one additional requirement here, which is that we signal to the Fxa server backend whether or not the browser has sync enabled. Previously the backend could tell this by the presence of service=sync
in the login request, and we use that for a variety of purposes listed here.
We can re-work most of those without any help from the browser, but the one piece for which we do need the browser's help is in tracking sync activity metrics. Short-term I'd like to propose that we take advantage of the existing logic in the /certificate/sign
route which takes an optional service
query parameter. When the browser calls signCertificate
currently it does not include a service
parameter. We could have it include ?service=sync
in such calls when sync is enabled, and omit the service
parameter when it is not.
We'll have some followup work to do around enabling other services in the browser, but I expect we'll be able to derive those metrics from OAuth activity rather than /certificate/sign
.
(You might ask: why don't we get sync activity metrics out of the sync server, rather than inferring them from what happens on the FxA server? Great question! We should move to such a world longer-term. But we haven't built the infrastructure for that currently).
Reporter | ||
Comment 8•5 years ago
|
||
I'd like to add one additional requirement here, which is that we signal to the Fxa server backend whether or not the browser has sync enabled.
After slack conversation with :markh, I've spun out a separate issue for this: Bug 1581709.
Comment 9•5 years ago
|
||
Reporter | ||
Comment 11•5 years ago
|
||
As discussed in today's meeting, there's value in separating out the "infrastructural" work of supporting the new sync-optional signin flow from the user-facing work of actually using the new flow from about:welcome. I've filed Bug 1582002 to be specifically about "enable the sync-optional flow from about:welcome" and am changing the title of this bug to reflect that it's about the infrastructural changes to the login flow.
Thus, this bug depends on the corresponding FxA-side changes from https://github.com/mozilla/fxa/issues/2396, and encompasses the following work:
- [ ] Changing the handling of
fxa_status
webchannel message, so that we decide whether to reportsignedInUser
based on thecontext
parameter rather than theservice
param. - [ ] Changing the
fxa_status
webchannel response to include the OAuth client_id andmultiService
capability - [ ] Changing handling of the
login
webchannel message to:- [ ] Only enable sync if there is a
sync
key in theservices
field - [ ] Obtain the user's CWTS selections from said
sync
key intead of from top-level fields in the message - [ ] Not enable/disable sync if we receive a
login
message when we're already signed in
- [ ] Only enable sync if there is a
Assignee | ||
Comment 12•5 years ago
|
||
Reporter | ||
Comment 13•5 years ago
|
||
Vlad and I had a good slack discussion about handling the case where the user is already signed in to the browser, looping back to the bug here to continue it.
How should the browser behave if it receives an fxaccounts:login message when a user is already signed in?
This can happen for legitimate reasons, e.g. if the user changes or resets their password on the web in a signed-in browser.
I was mistaken about the password-change case here; that's actually handle by a different "fxaccounts:change_password" notification so we don't need to worry about any changes on their front.
However, there are two cases where the browser might receive "fxaccounts:login" when it already has a user signed in:
- If the user navigates to https://accounts.firefox.com/signin?context=fx_desktop_v3 and does a fresh sign-in
- If the user's session gets disconnected, and the browser guides them through a "force auth" flow
Can anyone think of any others?
For case (1) I think it's reasonable to treat this like any other signin, using the services
field values selected by the new user. But perhaps there are some subtleties there around handing merging of data that we should take into consideration?
For case (2) I think FxA should avoid showing any choose-what-to-sync or choose-whether-to-sync screens in the force-auth flow. It doesn't seem necessary to allow for users trying to enable or disable services when signing back in to a disconnected Firefox, especially since we don't actually have any other services at this stage. So I propose that the browser should launch the force-auth flow with context=fx_desktop_v3
and no service
parameter, FxA should return an "fxaccounts:login" message with no services
field, and the browser should leave the existing user's service selections alone.
There may be more complexities here though; :eoger, care to weigh in?
Reporter | ||
Updated•5 years ago
|
Comment 14•5 years ago
|
||
Pushed by eoger@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/5f0064458765 WebChannel support for optional Sync. r=vladikoff
Comment 15•5 years ago
|
||
bugherder |
Comment 16•5 years ago
|
||
The following expected results were verified using Windows Pro 10 64-bit and macOS Catalina 10.15 on FF 71.0b7 (20191104135555):
From about:welcome the users reach a Sign in to Continue to Firefox
In the Create account flow the users reach the CWTS (choose what to sync screen) where they can Enable sync for multiple components or choose not to Sync.
All users now have a "Don't sync this device" option which, if clicked, continues the sign in flow and with display in about:preferences#sync as Sync OFF.
There is no "back" button from this screen, but it the browser back button can be used.
The URL for the create account/ sign in from about:welcome has been updated to "https://accounts.firefox.com/?context=fx_desktop_v3".
In the scenario in which the account is logged in multiple devices and a password change is performed on one of them, through a force_auth flow in which the user has to choose again to enable to not sync.
Description
•