| The Goldilocks API | Dan Callahan | 26/09/13 07:49 | The Get API did too little. By introducing always-on session management,
the Observer API did too much. Nevertheless, we *must* standardize on something to unblock various native efforts. Rather than take another stab in the dark, let's buy ourselves time by standardizing on a basic, v1 API that doesn't do session management. Something that behaves like the much-beloved .get(), but mitigates its one flaw by registering the login callback somewhere accessible to the browser. In this way we could close the loop, support redirect-based loginflows, and handle chrome-initiated logins. The maintainers of django-browserid, James Shore, and many others have enthusiastically endorsed the idea of building a v1 API without session management, and tackling that as a separate problem. Let's heed those calls and deliver a simple foundation, suitable for inclusion in Firefox, and easy to integrate into existing sites. This feels like a "Q4 Goal" to me. Does it to you? -Callahad PS: This explicitly punts on cross-domain SSO and automatic session renegotiation for the v1 API. Those are extremely advanced, niche use cases that need more exploration and experimentation before we bake them into Firefox. Sites that need them can continue to use the shim-supported Observer API in the interim. |
| Re: The Goldilocks API | Dan Callahan | 27/09/13 07:59 | On 9/26/13 9:49 AM, Dan Callahan wrote:For instance, the API could look like this: navigator.id.configure({ login: function (assertion) { ... }, }); navigator.id.prompt(); This behaves exactly like navigator.id.get -- no session management or other magic. It invokes the configured login callback by default. If you want custom behavior for a button ("Change Email" / "Add Email" / "Subscribe" / etc.), you can override the behavior by passing an alternative callback to the prompt function: navigator.id.prompt(function (assertion) { ... }); It is an error to call prompt with an override if .configure() has not previously been called. Because the login callback is available to the browser, Native UI can initiate logins, and we can queue login events to fire automatically -- once -- in response to redirects or email verification links. There's no always-all session management. How does that feel to people? -Callahad |
| Re: The Goldilocks API | Sean McArthur | 27/09/13 11:38 | Is there a reason we can't keep the methods that already exist? I feel like
that is less complex for users: "Use .request() and watch(). If you want session management, add a onlogout handler to watch()." Basically, the change would be that if you omit a onlogout handler, we don't do session management. Likewise if you pass a function to request(). > ______________________________**_________________ > dev-identity mailing list > dev-id...@lists.mozilla.org > https://lists.mozilla.org/**listinfo/dev-identity<https://lists.mozilla.org/listinfo/dev-identity> > |
| Re: The Goldilocks API | Dan Callahan | 27/09/13 15:41 | On 9/27/13 1:38 PM, Sean McArthur wrote:Discussing things in terms of watch and request makes it really, really hard to talk about new behaviors in isolation. (I tried with two people off-list, and it totally threw them.) So yes, this API *could* be seamlessly integrated into the existing Observer API, but let's leave that to a separate discussion. -Callahad |
| Re: The Goldilocks API | Dan Callahan | 27/09/13 16:01 | On 9/27/13 2:25 PM, Michael Kelly wrote:
> I really like this proposal! It solves a lot of the issues > django-browserid has had with the watch API. Yay, thanks! The maintainer of the Drupal module also mentioned, and I quote, "this fixes so many things. All of my problems were related to session management in the Observer API. All of my workarounds were because of that." > This is the only part I understand. Why must configure be called first? This constraint ensures that the browser always has access to a login callback (the one defined in .configure), which is mandatory for supporting platforms like Windows Phone and Chrome on iOS, amongst other things. -Callahd |
| Re: The Goldilocks API | Sean McArthur | 27/09/13 18:54 | Alright, I can start on this api on Monday. I'll act like it's configure
and prompt. That's just a few lines in include.js anyways. I wonder if that confusion comes from already identifying watch() to mean session management. I wonder if it would make more sense to people who have never seen navigator.id |
| Re: The Goldilocks API | Lloyd Hilaiel | 28/09/13 01:17 | Rembemer the last time we did this? Then it was a cage-match between Observer (an "events" based API) and watch (what we have today). APIs are hard, who wants to go shopping?
My optimism comes from the fact Goldilocks and Paris proposals are really close - and I believe either sets us up for the next huge wave of adoption and application of browserid protocols (in mozilla products at scale, and pending that multi-million user dogfooding and commitment, on the internets at large). The differences seem to be: 1. should we ask sites to tell us when a user logs out (by calling .logout()) 2. should we fire .onlogin events only once after a login occurs, or should we fire them as long as we believe a user is logged in. Either Paris or Goldilocks comes with tradeoffs and some implementation challenges, and some nasty corner cases. But I believe the net result of either is something that solves the 80% case much better and more simply than what we have today. What we need now is two people to sit down and do their best to reason about the tradeoffs in a dispassionate manner and come to a well thought out joint decision. First question: Does anyone think the general direction of Paris/Goldilocks is wrong? (divesting from session management - logout completely in the shim, and )? Second question: Does anyone have a problem with Dan and I having a cage match in Bulgaria (he'll be here with me on sunday, we'll film it and put it on youtube) and coming back to the list in agreement with a concrete proposal? <3, Lloyd
> Rather than take another stab in the dark, let's buy ourselves time by standardizing on a basic, v1 API that doesn't do session management. > Something that behaves like the much-beloved .get(), but mitigates its one flaw by registering the login callback somewhere accessible to the browser. In this way we could close the loop, support redirect-based loginflows, and handle chrome-initiated logins.> _______________________________________________ > dev-identity mailing list > dev-id...@lists.mozilla.org > https://lists.mozilla.org/listinfo/dev-identity |
| Re: The Goldilocks API | Jared Hirsch | 28/09/13 07:49 | +1 cage match, great idea
|
| Re: The Goldilocks API | Dan Callahan | 30/09/13 13:31 | On 9/27/13 9:59 AM, Dan Callahan wrote:Shane brought up an excellent point: We can't support custom behavior in this way for the same reason we can't use the .get() API -- it hides the callback from the user agent, so we can't invoke it if we have to redirect the user during login. So we'll move ahead with the rest of the proposal, and ignore this clause. Are there any other blind spots or corner cases that this makes worse? -Callahad |
| Re: The Goldilocks API | Shane Tomlinson | 01/10/13 00:24 | Thanks for mentioning the problems with passing the callback to prompt, Dan.
One final question, does the basic premise still hold that RPs only call .configure if they believe the user is not signed in? It seems so, I just want to make sure. There are still "closing the loop" issues [1] we could work to take care of, but this API is *SO* much simpler. Vastly simplified. Usable. Nice work. Shane [1] - https://groups.google.com/d/msg/mozilla.dev.identity/cTN4ik4vHGQ/eYEG7oS8X-cJ |
| Re: The Goldilocks API | Dan Callahan | 01/10/13 00:43 | On 10/1/13 2:24 AM, Shane Tomlinson wrote:I think that's up to the RP. You need to call .configure() on any page with a login button, or any page that returnTo references, but beyond that... Still, it's probably a good idea to reccommend calling .configure() on all pages so that the user can initiate a login through browser chrome. Since we're not trying to manage state, the call to .configure() wouldn't necessarily need to set up a communication iframe or do any of that business. -Callahad |
| Re: The Goldilocks API | Shane Tomlinson | 01/10/13 00:49 | I'm not following, if one of the purposes of calling configure with
onlogin is to allow post-verification redirect, for shimmed implementations, the communication iframe is needed to see if the user is signed in. Shane |
| Re: The Goldilocks API | Dan Callahan | 01/10/13 01:04 | On 10/1/13 2:49 AM, Shane Tomlinson wrote:Sorry, I took a bit of a mental leap. Right now, .watch() *always* needs to do a bunch of network stuff to fire the appropriate callbacks. .configure() only needs to set up that communication when it's in the process of completing a post-verification redirect (or a normal redirect-based login). That means we have the ability to optimize away the communication_frame most of the time (not actively trying to log in? don't set it up.) So, how do we know if the user is in the midst of a login? Shove something into sessionStorage, like we do with returnTo :) .configure() could look for a signal there, and decide to set up the communication iframe or not based on that. Does that make sense? -Callahad PS: We wouldn't need to implement this particular optimization immediately. Our first pass just needs to get the API design right; we can do fun optimizations after that. |
| Re: The Goldilocks API | Dan Callahan | 01/10/13 01:24 | On 10/1/13 3:04 AM, Dan Callahan wrote:...And this is all premature optimization :) Presume normal communication iframe semantics for now. Sorry for the derail! -Callahad |
| Re: The Goldilocks API | Francois Marier | 01/10/13 07:15 | On 01/10/13 03:43, Dan Callahan wrote: > I think that's up to the RP. You need to call .configure() on any pageSome of the feedback I got about the watch API is that until https://github.com/mozilla/browserid/issues/3035 is fixed, setting up Persona on every page is too expensive. All we can tell these RPs right now is to use the get API and only load include.js on the login page. Francois |
| Re: The Goldilocks API | Austin King | 01/10/13 13:25 | I like the proposal!
I think we should document configure as being required on every page. * Gives us flexibility in the future * "Don't make me think" for developers * Probably this API won't have the same overhead as the Watch API did I would like to see websites call navigator.id.logout. I'd like lloyd and callahad to publish cagematch highlights, such as explaining why the trade-offs for logout don't add up. Bikeshedding: Sorry... I'd like to see "navigator.id.authenticate" instead of prompt. * navigator.id.configure * navigator.id.authenticate * navigator.id.logout Great work everybody! -- ozten > > Francois |
| Re: The Goldilocks API | Sean McArthur | 01/10/13 13:27 | Which localStorage? Shame on us if we pollute (nor can we trust) the
storage of the RP site. To access login.persona.org localStorage, we would need to setup an iframe... > ______________________________**_________________ > dev-identity mailing list > dev-id...@lists.mozilla.org > https://lists.mozilla.org/**listinfo/dev-identity<https://lists.mozilla.org/listinfo/dev-identity> > |
| Re: The Goldilocks API | Dan Callahan | 01/10/13 13:41 | On 10/1/13 3:25 PM, Austin King wrote:Logout adds a huge hurdle for potential RPs. Generally speaking: - Every single major site that's attempted to implement Persona has gotten logout wrong. GNU MediaGoblin got this wrong, and only found it 24 hours before their 0.5.0 release. Ting gets (got?) this wrong. GNU Mailmain v3 got this wrong. And so on. These are projects from really smart people. If they're all getting it wrong in the same way (just clearing their own session cookie, not calling .logout), then there's likely something wrong with our API. - Hooking logout means we can't fit into existing frameworks like OmniAuth, since they don't provide those hooks. Eliminating .logout means we fit like a glove, and our integration story is trivial. - Needing to hook logout means that sites must write custom code to keep Persona-specific state to track which login mechanism their user used. - Logout implies that we're keeping track of the user's preferred session state on that site. If Persona has a long-lived opinion, and any ability to act on it, then we're back into risking "inifinite login loop hell," as peterbe put it. Full session synchronization enables some really, really beautiful things, but even adding logout is empirically very difficult for our users in their chosen tools / libraries / frameworks. -Callahad |
| Re: The Goldilocks API | Austin King | 01/10/13 13:48 | I'm not arguing for Persona controlled sessions, of course.
Did we consider calling logout as an optional "hint" to improve the Persona experience? Why? Logout improves our UX, but isn't strictly necessary. -- ozten > > -Callahad > > _______________________________________________ > dev-identity mailing list > dev-id...@lists.mozilla.org > https://lists.mozilla.org/listinfo/dev-identity |
| Re: The Goldilocks API | Dan Callahan | 01/10/13 13:53 | On 10/1/13 3:48 PM, Austin King wrote:Tell me more :) -Callahad |
| Re: The Goldilocks API | Austin King | 01/10/13 13:58 | Some UX for Fx Desktop prototypes have different state depending on if
the user is signed into a website or not. For the shim, maybe we want to improve the user's security once they sign out of a website (by clearing out storage or whatever). Sorry this is somewhat hand-wavy. |
| Re: The Goldilocks API | Francois Marier | 01/10/13 14:35 | On 01/10/13 16:25, Austin King wrote:One of the advantages of being in the logout loop (in some way) is that it makes it possible to implement Real Logout (tm) in the future. We already lost an RP a while back because he had to teach his users to go to login.persona.org after logging out of his site to ensure that they were actually logged out and couldn't just log back in without a password. Francois |
| Re: The Goldilocks API | Lloyd Hilaiel | 02/10/13 01:06 | On Oct 2, 2013, at 12:35 AM, Francois Marier <fran...@mozilla.com> wrote:The major highlight for me from the cage match was a point about 3rd party cookies and the communication iframe in general. So in our basic, external persona offering, we need to work everywhere. Current browser vendor trends toward locking down cookies are positive, having privacy preserving defaults is behavior we want to rally behind and encourage. But values aside, the behavior of iOS7 effectively neuters our communication iframe. It makes it so that to Just Work Everywhere, we need to really seriously consider the constraint of restricted third party cookies. Because our iframe being isolated is now more than a 20% case, I think our basic offering must just work in the face of it. The thing about the goldilocks api (which I prefer to think of as a subset of .watch), is that it says our primary API *never* relies on returning assertions when we're rendered in a 3rd party context (the iframe). I think this is very sound reasoning. If we release (for example) an SSO feature and it doesn't work for more than 20% of the web, then it will generate more disappointment than joy. If we encourage sites to set short lived cookies and use persona for automatic session extension, and more than 20% of the time users are logging in every couple hours, it will cause grief and complaints - it will cause user sadness (reference - the etherpad persona integration inside mozilla). Think back (or spend some time with shane) and talk about all of the complexity and time we've spent trying to keep the communication iframe limping along so that our primary API continues to work. It's been major cost, and the result today is many of the features of that API are just broken today. Don't get me wrong, we've mitigated this - our response to the iOS7 release demonstrates creativity and swift action. But we didn't, we can't, fix it - all we can do is gracefully degrade for increasing percentages of our user population. So while I think there is a little bit of work to go into how we actually execute this change gracefully, the core premise that our primary API really needs to work everywhere is sound. A final point is I think our core strategy needs to be native everywhere, so we can leverage all of the firefox products to drive forward and prove out (at scale) persona protocols, and hopefully the persona experience. A reduction of ambition (and in turn of necessary complexity in native implementations) is highly compatible with that goal. This is why I push towards us being decisive here. Doing less, and doing it better. lloyd (P.S. in the interest of full disclosure, I do believe that there still is an opening here to gracefully *upgrade* and offer incremental advanced features for environments that we control (all the firefoxes), or for advanced and critically important use cases - but I'm on board with starting from the platform of goldilocks). |
| Re: The Goldilocks API | Shane Tomlinson | 02/10/13 01:11 | I'm pulling in quotes from both Sean and Austin and responding to both.
+1. We don't know what fields of theirs we may be overriding. We can't trust them to not intentionally overwrite ours. Shoving any sort of data into the RP's localStorage makes me *extremely* uncomfortable. Maybe we can use a cookie scoped to login.persona.org instead. Something that does not pollute the RPs data space.
> Bikeshedding:Thanks for bringing up logout Ozten. Dan, I am trying to understand the API and how it operates better. Say we go with the plan that we tell RPs to include include.js and call .configure on every page load, for the given reason that it helps native implementations where there may be a signin button in chrome (a feature we experimented with [1][2] 2 years ago). The user clicks signout on the RP. On the user's next visit, we believe the user to be signed in. Do we automatically sign them in? Yesterday in IRC [3] it sounded like the proposal is that we would not automatically sign the user in. If that is the case, we would not need logout. If however, we do sign the user in automatically, we must keep .logout. Shane =================== [1] - https://github.com/shane-tomlinson/browserid_addon [2] - https://shanetomlinson.com/2011/mozilla-session-api-tutorial/ [3] - http://irclog.gr/#show/irc.mozilla.org/identity/326651 |
| Re: The Goldilocks API | Lloyd Hilaiel | 02/10/13 01:11 | On Oct 2, 2013, at 11:06 AM, Lloyd Hilaiel <ll...@mozilla.com> wrote:I hit send too quickly. Not never. I guess I'm over simplifying. Post email verification and the redirect flow present challenges. But at least we can attack those in isolation. Interestingly, both of those cases involve login.persona.org being rendered in a first party context, and immediately redirecting back to the site. If we could figure out a safe way to pass an assertion back to the site during redirect... lloyd |
| Re: The Goldilocks API | Shane Tomlinson | 02/10/13 01:32 | On 02/10/2013 09:11, Lloyd Hilaiel wrote:
> On Oct 2, 2013, at 11:06 AM, Lloyd Hilaiel <ll...@mozilla.com> wrote: > >> The thing about the goldilocks api (which I prefer to think of as a subset of .watch), is that it says our primary API *never* relies on returning assertions when we're rendered in a 3rd party context (the iframe). > > I hit send too quickly. Not never. I guess I'm over simplifying. Post email verification and the redirect flow present challenges. But at least we can attack those in isolation. > > Interestingly, both of those cases involve login.persona.org being rendered in a first party context, and immediately redirecting back to the site. If we could figure out a safe way to pass an assertion back to the site during redirect... Sean and I spoke of passing an assertion from the dialog->RP using the URL hash, since the hash never leaves the browser. He said that when he brought that idea up before, it quickly got the beat down for security reasons, mentioning in particular the problems that Facebook had with OAuth. Is there more information about the problems they faced? What are the specific concerns with the approach? Shane |
| Re: The Goldilocks API | Jan Wrobel | 02/10/13 04:15 | OAuth2 implicit grant passes an auth token in a fragment component of
a Location header: http://tools.ietf.org/html/rfc6749#section-4.2 The RFC does not mention any fundamental problems with this, it only says: " Developers should note that some user-agents do not support the inclusion of a fragment component in the HTTP "Location" response header field. Such clients will require using other methods for redirecting the client than a 3xx redirection response -- for example, returning an HTML page that includes a 'continue' button with an action linked to the redirection URI. " and also: " When using the implicit grant type, the access token is transmitted in the URI fragment, which can expose it to unauthorized parties. " but it does not mention how the token can be exposed. I think one concern is what happens if a malicious site takes a user to a legitimate site passing a fixed token in the URL. Something like: <a href="http://example.org/whoa#persona-assertion-for-evil@user"> If Persona accepts such assertion, it is an equivalent of a Login Cross Site Request Forgery vulnerability. I don't know if there is a reliable protection against this and if there are other problems with # approach. Cheers, Jan |
| Re: The Goldilocks API | Shane Tomlinson | 02/10/13 04:28 | On 02/10/2013 12:15, Jan Wrobel wrote:Thanks Jan, that is very helpful information. |
| Re: The Goldilocks API | Sean McArthur | 02/10/13 15:50 | Yes, the security gaps with Facebook's OAuth were instances of attackers
able to forge app access requests with altered tokens/parameters. It can be done, but it's more surface area to cover. >> <a href="http://example.org/whoa#**persona-assertion-for-evil@**user<http://example.org/whoa#persona-assertion-for-evil@user> >> ">> ______________________________**_________________ > dev-identity mailing list > dev-id...@lists.mozilla.org > https://lists.mozilla.org/**listinfo/dev-identity<https://lists.mozilla.org/listinfo/dev-identity> > |
| Re: The Goldilocks API | Jonathan Brown | 24/10/13 14:53 | Drupal Persona module maintainer here - sorry for the late response to this.
I'm very supportive of the Goldilocks API! For the case of handling change email / add email would it be possible for the RP to add a custom variable when initiating sign in through JavaScript?. Upon successful sign in, this variable would be passed back to the login function along with the assertion. A point I raised previously is that browser initiated sign in is impossible if the information about the site, e.g. site name / logo is passed to navigator.id.request(). I think this needs to be tags in the page <head>. Is this something that could be incorporated into goldilocks? > _______________________________________________ > dev-identity mailing list > dev-id...@lists.mozilla.org > https://lists.mozilla.org/listinfo/dev-identity > |
| Re: The Goldilocks API | Shane Tomlinson | 25/10/13 03:17 | On 24/10/2013 22:53, Jonathan Brown wrote:Hi Jonathan, There was also talk of passing those parameters as part of navigator.id.watch instead of adding new meta tag elements. I'm not sure which way this went in the end. My personal belief is that everything related to Persona should be passed via the JS API, if possible. Adding/changing code in multiple places and in multiple "languages" (HTML/JS) is a recipe for confusion for site developers. In addition, passing data via meta tags forces native BrowserID implementations to parse the HTML (or use the native parser, but then establish a communication channel with the parser), adding additional complexity. Shane |
| Re: The Goldilocks API | Jonathan Brown | 25/10/13 03:38 | Yeah - passing the parameters in navigator.id.watch makes sense.
|