Having a finger service as a directory to find information about users and services appears to be absolutely necessary if ad-hoc information sharing between people and services is to be possible. But just having a way to finger a person or service is less than 1/2 the battle. The real challenge is making it possible for services to update their user’s finger information in an ad-hoc manner. I explore the issues around dynamic finger update in this article.
Contents
2 Requirements
2.1 Start with an absurdly simple data format
2.2 Keep going with an absurdly simple protocol
2.3 Updating the pointers
2.4 Updating the access control permissions
2.5 Submitting proposed permissions descriptions
3 Updating the finger service, an example
3.1 Wait a minute, what about the late bound e-mail security hole?
3.2 Isn’t the list of folks able to see the calendar going to likely be dynamic and so Google will be endlessly updating the finger permissions?
3.3 Does telling the requester about additional identifiers associated with the service open up a possible security hole?
3.4 Why couldn’t Google just ask for two identifiers in one request?
3.5 Oh come on, why isn’t this just LDAP?
3.6 Fine, if it’s not LDAP then why isn’t it WebDAV?
1 Update a calendar services’ location - a scenario
Dax has decided to host her personal calendar with Google. As part of the set up process Google asks Dax if she wants to update her finger service to point her calendar at Google. Dax agrees and is forwarded to the finger service along with a request to add her Google calendar as a choice for her calendaring entry. Dax authenticates to her finger service and her finger service prompts Dax for how she would like, if at all, to include Google Calendar in her finger results. Dax specifies that Google should be listed as her personal calendar service but not her business calendar service.
2 Requirements
2.1 Start with an absurdly simple data format
Directories bloat. One suspects it’s a corollary of Parkinson’s Law for data (data expands to fill the space available for storage). But we don’t have to start off bloated. We can start off with a directory that initially contains exactly one table with two columns (on a per entity basis). One column is the identifier of the service being sought and the other is the URI. Any further information needs to be retrieved from the service being pointed at.
This approach has instant problems. For example let’s say we have an identifier URN:SomeStandardOrgId:Calendar. But wait, the user has two calendars, one for work and one for business. We can easily imagine returning two results. But should we further disambiguate? Maybe have an entry for a personal versus a business calendar? Surely there is other interesting data we could throw in?
It’s pretty bloody obvious that if finger is successful then before it’s done it will look like LDAP (which, given its success and long history I’m going to guess probably now looks a lot like DAP). So I’m not suffering from any illusions that this time it will be simpler. No, it won’t. But every once in a while you have to burn the ships and start anew.
So my argument is that rather than putting in say a name/value bag that can be searched on (and creating a language to go with it - should it be DASL or OData?) we either just have a single identifier for a calendar (and so can return multiple results) and we also allow for more distinct identifiers such as URN:SomeStandardOrgId:Calendar:Personal. In other words we hack the data into the identifier.
This will mean that the same service will be identified multiple times in the finger service but that’s fine. Given that it is a non-goal to replace true directories but rather to create an indirectory one suspects we can get pretty far with a very simple proposal.
2.2 Keep going with an absurdly simple protocol
It’s all just name/value pairs so the protocol should just focus on that. No need to get fancy. For now we should just focus on reading/updating data in a single user’s directory.
2.3 Updating the pointers
When a service wants to update its user’s finger service it’s job, first and foremost, is to provide a set of service identifiers and associated values that it wants to update. So in theory an update should contain just two data points, the service identifier (e.g. this is a calendar service) and the URI for that service. The main downside to this approach is that it can potentially leave the directory in an inconsistent state. In the previous calendar example we showed how a single calendar service could show up under multiple service identifiers. If the service is only allowed to change one pointer at a time and the change is to replace one calendar service with another then the system can be viewable halfway through the change. In ACID terms this means we don’t have isolation.
I suspect this is a sufficiently nettlesome problem that we need to support updates that allow the value of multiple service identifiers for a single user to be updated in a single request.
2.4 Updating the access control permissions
Remember how I said that the finger service would just have a two column table? I lied. Wow, Parkinson’s law hits really fast.
Because one of the key issues for a successful finger service is privacy. We don’t want stalkers finding people. We don’t want spammers harvesting identities. We don’t want to help the black hats by making it easier to find users with potentially compromised services. Etc. So we need to expect that the finger service will enforce access permissions.
But let’s think about a simple scenario. Dax has given permission to Martok to see her calendar in Google. But the utility of that permission will be quite limited if when Martok’s calendar application tries to find Dax’s calendar service the finger service won’t accept Martok’s request to find out where the heck Dax’s calendar is at.
So this argues that when updating data in finger the updater also needs to provide permission data - who has the user authorized to see this information? Strictly speaking however this update is more a hint than anything else. In other words the service is saying ”Look, user X is using me as a calendar service and has allowed the following users to access their calendar so you should let the following users also discover where the user’s calendar is.”
This isn’t nearly as complex as it sounds. The ACL list would literally consist of a series of email addresses. How those email addresses would be validated is discussed later.
And yes sharing all this data with the finger service is more than a little scary. Plus there are a number of practical issues discussed later in the article that lead me to believe that the way permissioning will really work is that permissions will be controlled first and foremost by the user of the finger service on a ’universal’ basis, e.g. ’anyone in my address book can see where my services are located’.
2.5 Submitting proposed permissions descriptions
A problem with sticking a finger service in the middle of everything is that it has the real potential to slow innovation. For example, let’s say there is a new service foo whose service identifier is URN:SomePrivateOrg:Foo. A user signs up for a foo service and now the foo service wants to update the user’s finger service so other users can find the user’s instance of the foo service. However when the foo service sends an update to the user’s finger service the finger service is likely to reject the request saying ”Huh? What’s a foo service?”
This is not an unreasonable reaction on the part of the finger service. One can imagine that a critical part of the update process is when the finger service turns around to the user and says ”Hey user, I got a request from service X asking to be your Calendar service, this means that anyone trying to see your free/busy time or check out your calendar is going to go to service X, are you super duper sure you want to do this?”
But the finger service can’t provide that level of protection if it’s dealing with a service identifier that it doesn’t recognize.
I can imagine some ways of trying to tackle this problem, such as having an industry registry with localized strings where finger services can pick up ’safe’ descriptions of new services but that’s a heck of an infrastructure to build and probably isn’t going to be available any time soon.
So I think in the meantime we need to go for the ’user empowering’ (read: we believe in your inalienable right to commit security suicide) option which is to let the service that is trying to update the finger directory put in a human readable description of what the heck the service identifier they are trying to update actually does. A finger service could then prompt the user ”Dear user, service X wants to update your service directory with some new service type I don’t recognize. I have no idea what the heck this is or what it means and you are pretty much opening yourself up to eternal security damnation if you agree to this. So you probably shouldn’t. But if you care this is what the service claims the identifier does but hey, they could (and probably are) lying through their teeth.”
Anyone want to take bets on how close to 100% of users will click yes even with that warning? But that’s o.k. the little padlock or the green glow will fix everything. (Was that bitter?)
3 Updating the finger service, an example
In this example Dax has just signed up with Google’s calendar service. Dax’s identity provider has no relationship with Google. As described here Google was able to authenticate Dax using her identity provider (IdP) even though Google had no previous relationship with that provider. So the next step is for Google to send a request to the IdP asking to update Dax’s finger status. So Google first asks Dax’s IdP where the finger update service endpoint is using, well, finger, obviously. Generally the finger update service endpoint is always public so no proof of identity was needed (note however that smart IdPs will return a URL for any submitted user identifier to prevent people fishing for validate identifiers). Google then sends a request to the finger update service endpoint asking to update various service identifiers with Dax’s Google calendar service URL and also specifying the e-mails of anyone Dax has approved for access. This will essentially be an OAuth request where Dax will end up being redirected to her IdP who will confirm that she accepts the changes. Dax confirms and the changes are made as Dax is redirected back to Google.
Note that this entire flow just requires adding some arguments to the OAuth Web Server flow. It doesn’t require any fundamentally new protocol machinery.
3.1 Wait a minute, what about the late bound e-mail security hole?
The problem, which I’ve referred to before, is that email addresses are late bound identifiers. So if I say ”joe@example.com” can access my service and at some point Joe Johnson, who was the person behind joe@example.com, loses that address and now Joe Jehoshaphat has it, my ACL will still be in place and the wrong person will have access.
What we need is a way to exchange a late bound identifier like an email address with a persistent identifier that is guaranteed to always follow the person and not the email address. But the infrastructure needed to enable swapping out e-mail addresses for persistent identifiers should, if we do it right, be implementable on top of the finger infrastructure. In fact ideally what will be sent across the wire is a list of doublets, one part identifying an identity provider and the other part a local identifier.
3.2 Isn’t the list of folks able to see the calendar going to likely be dynamic and so Google will be endlessly updating the finger permissions?
A simple case is that Dax says ”let everyone in my address book see my free/busy time” in which case every time someone gets added or removed from Dax’s copy of her address book at Google the Google calendar service will need to go over to Dax’s finger service and update the list of folks who can discover her calendar service in the first place.
One solution is to just ask Google. In other words somebody shows up with a request to Dax’s finger service asking to see where Dax’s calendar is located. The Finger service knows that Dax has her personal calendar at Google and let’s say her work calendar at Exchange Online. Dax’s finger service could fire off two requests to each service asking ”Hey, should I let this person see Dax’s calendar service location?”
This approach however does have a few problems. First, it’s very prone to leak data. An attacker can see where connections are going from the finger service and make a pretty good guess about things like ”Hey, there is a user called Dax” and then ”Oh and that user probably uses Google and Exchange”. So much for privacy. The performance is also likely to be less than one might like since every incoming request ends up resulting in one or more outgoing requests before it can be answered.
My suspicion is that in practice this problem doesn’t really need to be solved. My suspicion is that the way users will really manage their finger service is they will say things like ”Anyone in my address book can see my services”, their finger service will be syncing to where ever their address book is kept and call it a day. They will have the choice of making more restricted settings but in the general case I think just having that level of validation is probably enough.
Keep in mind that finger services that are associated with corporate identities will almost certainly be backed by full directories who can play all the access control tricks one could ever want. For those kind of customers I expect that services will either synch the full directory contents (including groups, rules, etc.) or really will outsource requests to the corporate directory.
In other words if someone is using Google Apps through their company then when someone tries to access one of the employee’s Google Apps accounts Google will forward the request to the corporation for fulfillment or will fulfill it with a local copy of the corporation’s directory. This approach is acceptable because the corporations pay enough money to make it economically feasible.
3.3 Does telling the requester about additional identifiers associated with the service open up a possible security hole?
Possibly. It’s a trade off. I suspect this trade off will have to be made depending on the nature of the identifier being updated.
3.4 Why couldn’t Google just ask for two identifiers in one request?
Because if we do that we are essentially tunneling an application protocol inside of an application protocol. We need to create a compound wrapper to contain each of the individual requests and quite possibly a compound response format (assuming the semantics are not all or nothing which I think would be odd in our case). That is a lot of complexity to save a round trip.
3.5 Oh come on, why isn’t this just LDAP?
ASN.1 in the browser? Sounds like fun. And what a wonderful barrier to entry for anyone wanting to run their finger service. ”Step 1, LDAP”. I doubt anyone will make it to step 2. LDAP is wonderfully successful but only in places where the price is worth the reward (e.g. the enterprise).
3.6 Fine, if it’s not LDAP then why isn’t it WebDAV?
Hum... resources... properties.... named retrieval.... updates.... I’ve seen this story before. It was called WebDAV. And no whining about how to run WebDAV in the browser since XMLHTTP was literally invented for WebDAV. My current desire is to see finger folded into the OAuth 2.0 world and so I’d like to see a solution that is in keeping with how OAuth 2.0 works. This would be something much simpler than WebDAV. But once the standards machinery is done who knows where we end up.
One thought on “Thoughts on updating finger services”