Previous Entry Share Next Entry
Of Users, Identities and Persons [long]
jducoeur wrote in querki_project
[Semi-technical musings below. I've been starting from a problem and working backwards to a design. Feedback is welcomed.]

So far, I've been focused on making Querki do stuff, so I've largely ignored one very important problem: how do you log into it?

The truth is, it's going to be messy. I posted in my personal journal about a month ago, about the state of identity on the Web, which is a little messed-up right now. But for today, I sort of have to step back from those larger questions and focus on a much more precise one: how are people going to RSVP for our wedding?

As previously mentioned, one of Querki's very first concrete use cases is going to be running the wedding, and I'm now overdue to send out invitations. (Moving and prepping my house for sale took *way* more effort than I anticipated.) And while the invitees aren't necessarily going to be "Querki users" per se, they still essentially have to have identities so that they can respond to the invitations.

I've had this problem in the back of my mind for quite a while, and it introduces all sorts of entertaining problems. It's a special case of a more general problem: how do you invite somebody to use your Space or App? This needs to be dead-easy, especially for the invitees -- if somebody says "please come use this!", I had better not have to do much more than click on a link in an email. So that implies feature number one: we need to be able to embed an "identity" into that link, so as soon as I click it, Querki knows who I am.

OTOH, we need to avoid becoming a spam target, so we have to be careful about this. As an inviter, I can't just assert "Joe Shmoe here is going to use my Space", and start sending him email willy-nilly. Even more important, while I need to be able to say "send an invite to", I must *not* be able to intercept that invite and impersonate that email address. So the process has to have safeguards.

Of course, if I *am* Joe, and I'm already a Querki user, I don't want to have some whole other login just for this wedding site -- I want Querki to know who I am, so that if I log into Querki again (say, through Facebook), I can change my RSVP. Combine that with the fact that many users have a number of online identities (Facebook, Google+, LiveJournal, and a host of others), we want to be able to cope with the complex reality of that. Just to make it more fun, the more sophisticated users may want/need to keep those online identities distinct, even to the point where friends in one network don't even know the other networks exist.

(Yes, I'm pushing my long-held agenda about proper identity management. While I'm refraining from using Querki for crusades, I am going to insist on good information architecture, and this is something most companies are lousy about.)

So -- let's put all of this together. What do we wind up with?

First of all, we need to cope with the notion that a given person can have a number of ways that they log into Querki. This implies two distinct database tables that we mustn't confuse with each other:
  • A User is who I am. I log in as a User, and I can see all of my stuff -- my Spaces, my networks, my notifications, and so on. I think of myself mostly as a User. But...

  • An Identity is how others see me. This has a name, an email address, maybe a friends list on a particular social network, and so on. I *can* have multiple Identities that share the same public information -- but I shouldn't have to.
The key idea here is that a User can have any number of Identities, and other people can only interact with an Identity. I should be able to make things squishy if I want (eg, declare that everything I do goes to *both* Facebook and Google+), but the system ought to encourage me to think about that, at least slightly. Specifically, the system should not *accidentally* leak information from one Identity to the others.

While I suspect the initial Querki UI will be fairly simplistic about this stuff, it's crucial that we get the underlying concepts right -- that way, down the line, it will be possible to have reasonably good privacy with Querki without it being a pain in the ass.

Of course, User and Identity are both hard database tables -- the stuff that Querki is itself built on. But we want to be able to *work* with people in Querki itself -- after all, I started this off by saying that I want to be able to invite people to the wedding. That implies one more concept:
  • A Person is the Querki view of these ideas. It is a Model, much like any other. As a Querki user, I can instantiate a Person, I can make sub-Models that are specialized kinds of Person, and so on. Essentially, a Person is somebody who is in some way related to my Space.
A Person is essentially the application-level view of an Identity, and is how I invite somebody to use my Space. It isn't the same thing as the Identity itself, and that is important: as the inviter, I control the Person object but I can not do anything to the Identity without explicit permission. Indeed, I shouldn't be able to even know the object ID of the Identity -- that would be a potentially nasty security leak.

So the process of inviting people to my wedding looks something like the following:
  • First, in my Wedding Space, I create an Invitee Model. This is a special kind of Person, with added Properties like whether they are coming to the wedding; how many people are accompanying them; whether they are helping run something; and so on.

  • For each Invitee, I specify their email address.

  • I create an email template for the invitations. This is very much like designing a page in Querki -- I do it with wikitext and QL. Inside this template, I use a special Querki function called something like [[InviteLink]].

  • I send out the invitations using a Querki function that takes a list of Persons and an email template. (We will obviously have to put some limits on use of this, to prevent spam. My suspicion is that this is going to be a paid-user thing, with unpaid users only able to send very small amounts of unsoliciated emails, and paid users able to send a moderate number, with somewhat higher limits for emails sent to Identities who have pro-actively registered in this Space. The key, I suspect, is simply to make it uneconomical to use Querki for spam.)

  • In the course of sending the emails, the InviteLink gets turned into a URL. The URL points to the page for the Person object who is being emailed -- basically, your personal login/response page for this Space. This URL also contains a couple of login parameters. One is the object ID of the Person. In the course of sending the email, we look up whether there is already an Identity for that email address; if there isn't, we create one. We combine the OIDs of the Person and the Identity (and probably some hidden salt) to create a hash, and add that as another URL parameter.

  • When Joe gets his invitation, he clicks on the URL. He gets some sort of initial message saying that he is being invited to use my Space in Querki. (This is necessary in order to make it harder to use Querki for phishing.)

  • The system checks the parameters, confirms that the hash matches the Person ID, and logs him in under this Identity. (Which is relatively limited -- we likely will require additional login confirmation before he can do anything outside this Space, even if the Identity is linked to a User with more capabilities.) This code will eventually get pretty complicated, to deal with about a hundred edge cases, but that's a project for another day.

  • He gets shown his Invitee page, which I have set up with a button to say whether he is coming or not.
From a technical POV, that's pretty messy and complicated, but for the end users it should be reasonably easy. I say what I want my Invitees to be able to do; I give their names, email addresses and whatever else I care about; I write and send out the invite email; and the recipients click on the link therein.

Of course, that's all easier said than written -- I suspect the first pass will be kind of crude -- but we'll gradually refine it. The underlying principle is the usual one for Querki: we take a common scenario (inviting someone to come use my Space), and make it as braindead-easy as possible while still being flexible where we need to.

Does that make sense? Am I missing anything crucial? (In particular, do you see places where security is potentially iffy?) If we don't come up with any show-stoppers, it's time to start coding...

  • 1
Question about one of those hundred edge cases:
* Querki user sends emails to a list of People, inviting them to use Application X.
* Two of those People happen to be different Identities of the same User. (Joe, say.)
* Joe clicks on the links in both emails, and accepts the invite in both cases.

...what happens? Does Joe logging in under one Identity implicitly boot him from another Identity he's logged in as?

Not sure -- I'll have to mull that one. The biggest question is what the *right* behaviour there is. Both Identities have been invited, so both should be able to use it. In principle, they should both wind up associated with the same User record.

This implies that Joe will need the ability to specify which Identity he is currently presenting to the Space, which is reasonable -- and indeed, is just a special case of a more general problem of having multiple Identities using the same Space. The problem there is going to be coming up with a UI that isn't entirely wretched.

My gut reaction is that it isn't so much a matter of "booted" as "switched". The top menu bar may need to show, eg, which Identity I am currently operating under, and clicking the second one implicitly switches Identities...

This makes sense to me, but comes with an implicit trap: whenever you log in with an additional identity (or switch to a new identity via the top menu bar), all other Querki tabs/windows you have open become misleading in terms of who you're going to act as.

Mmm -- good point. We'll need to be careful about this topic, since I suspect this is far from the only trap. I'd bet that getting the technical underpinnings right isn't going to be nearly as difficult as the UI...

Yeeess.... sort of. My first instinct was some sort of token system (where the token is the URL) as you have also chosen.

If someone clicks the link and isn't 'logged in' the classic model has been to have the person log in or create an account. If someone is already logged in, it asks confirmation that the link clicker is Person X. This handles the duplicate invite thing because if someone clicks on both links, they first identify as the same identity, which is what gets associated with the token from the URL.

Yeah, there's something to be said for the explicit-login approach. But it introduces additional friction, and the wedding invite case is a good example where that's a hassle. Indeed, I'm somewhat modeling this on eVite, which is a good example of *not* requiring login in order to "join" something; I think they are correct that login would introduce undesireable resistance to replying. (Of course, eVite isn't trying to be anywhere near as sophisticated as Querki about identity. But I think they're correct about the UI.)

It won't surprise me if I wind up wanting both models, really, but we'll see -- I suspect we will need to do some experimenting to get the overall formula right...

  • 1

Log in

No account? Create an account