In short: I describe why claims are important for every developer and architect (not just the security expert), and I provide some heuristics for helping everybody to reason about claim based systems.
I don't think we did an exceptionally good job in explaining claims based programming and its implications. A lot of the literature on the subject is for security experts, hence it explains claims based programming in terms of the delta that differentiates it from more classical methodologies (ACLs, groups, etc). Other material explains the topic for the non-initiated to security, highlighting how digital identity is made of claims and so on; however the point is often lost, because while the reader can see that identity is expressed in a natural way it is not clear *how* the system is superior to classical approaches. In that case a concept easy to grasp, multiple authoritative sources backing it and some generic coolness are all ingredients for a nice information cascade. It reminds of another eminent (IMHO) information cascade: the schema-first approach to service oriented programming. Schema first is great in a number of occasions, but uselessly onerous in many tactical scenario: you don't really need to concoct an XSD for every message you send internally or to system that will never ever have to interoperate, validate complex messages or manipulate standard entities. And yet, *a lot* of people got is as a dogma (ie, without really understanding why it's useful) and started to apply it everywhere. When their productivity dropped (try to model with XSD everything you do) they blamed the entire web services stack, instead of blaming the blind application of an otherwise perfectly valid architectural consideration. But hey, I digress. However, you get the point: I would hate to see everybody jumping on the claim bandwagon and later dismiss the idea because they tried to use it for making Fourier transforms or because they believed it would have solved <place unrelated problem here>.
Another aspect of common explanations about claim is that they concentrate on how to safely & easily move them from A to B, because historically that's the big problem that the security guys have to worry about. However we spend very little time considering what B is going to do with those claims, once the initial exchange is over and the browser left the login screen. That, together with the confusion between identity and credentials, is the source of existential questions like "but I already registered the email claim from the personal card at signup time. What should I do with the email claim that I get in the token every time the use signs in with the same personal card?".
I believe that claims have the potential of change the way we think about distributed computing, and for the better. I also believe that for actually reaping their benefit to the fullest we need to enable everybody to really understand and reason about this, as opposed to just repeat the core idea as heard from somebody else. That's just the start, the foundation of the castle: we thick skinned server people are good at laying the foundation, but I expect that the most beautiful towers will come from the ones who receive the claims because they have an actual need to know the info they carry.
Ok, enough of this meta-blabbering. Time to see if I can explain the entire thing in different terms.
Claims vs. ACLs & Roles: a kid at your door
It's Saturday night, and you are waiting for a couple of friends to come to your house for dinner. In fact, the actual friend is Mario; you have never seen his wife Silvia and his kid Luigi. The doorbell rings: yes he is Mario, damn I told him not to bring anything and here he is with an expensive bottle of Montepulciano, and that nice lady and the kid must be Silvia and Luigi.
You have a nice dinner and some conversation, then you give the standard tour of the house. Silvia is very fond of your wife's Swarovski collection, and ask to take a closer look at the the butterfly: with extreme care you hand it out, she examines it for a moment and it gives it back to you. Luigi is fascinated as well, and asks to see it: however you are not ready to face your wife's wrath if she finds out you gave to a 8 years old her favorite crystal pet, hence you skillfully glide over the subject and distract the kid with something safer.
Later you walk in front of your stuff, Luigi sees your collection of musical instruments: again you try to hijack the kid on something else, but Mario tells you that Luigi is actually a gifted violin player and very respectful of instruments in general. At that point you allow Luigi to pick up a violin and draw some notes from it, for the delight of everybody.
Ok, we have seen enough. As you may imagine, the above is a metaphor I have set up for making my point about how claim based authentication works in an application. Here there are some considerations about the scene we have described:
- Mario is implicitly guaranteeing for his wife and son, and you trust Mario: thanks to that the woman and the kid are granted access to your house. If they would have come on their own (ie: without Mario) on a Sunday morning and rang your doorbell, depending on your manners & paranoia levels maybe you would not even have opened the door.
The act of entering the house represent successful authentication, and access to the application.
- Authorization decisions need to be made well after the authentication stage took place. Silvia is granted access to the butterfly a good 2/3 hours after having entered the house (we Italians take our time to enjoy meals). This means that whatever system we want to use for handling our authorization needs to be available also AFTER the authentication successfully concluded.
- Our decision process is way too fast for being consciously aware of it, however: why did we grant the butterfly to Silvia but not to Luigi? Because of what we know about the two. The main factor is probably the age: we expect a thirtysomething to pay attention to what she does, while the 8 years old does not enjoy the same trust.
- The violin scene is another authorization moment; it is more complex than the Swarovski case, but it's closer to reality (that is, digital reality). In that case you take an authorization decision because of what Mario claims about Luigi, while your better judgement would default to an access denied. Without Mario's word, Luigi would get a nice 401 (Unauthorized).
The situation above is well modeled by a claim based system. You may list all the data you want to know about the people that Mario is endorsing, in this case age and familiarity with musical instruments. Mario have just to comply and issue tokens expressing those 2 facts, then we are done. You can later take sound authorization decisions without even being in the room and seeing the people involved, you could be granting or denying access via Messenger just by looking at those tokens.
Note: you don't need to have a claim that spells out the relationships (wife or son), because what is important is Mario's endorsement itself. The fact that they are wives or same sex domestic partners or casual friends is important to Mario for his decision about bringing them along or not: but for you what's important is that they are with Mario, you don't need to know the rest because for this scenario it won't make a difference (in other scenarios it might). The reason of this fact is that Mario's endorsing is used for authentication (as opposed to authoriZation) purposes, a process that is successful or fails with nothing in between. In this case the endorsement is proven by a digital signature that Mario performs on the token. In other scenarios the authentication is not based on endorsement, but on some other mechanism: for example a u/p token may contain a username and a password, and if the latter corresponds to a shared secret known by the resource whoever sent the token is considered authenticated. For the reasons above, I am very reluctant to consider username and password as claims. They are not really facts about the subject that carry meaning for my application, they are just a trick I am using for recognizing that whoever is coming at my door is the same one with whom I negotiated a shared secret in the past. The same user may use a different flavor of token, maybe one that negotiates keys a' la Diffie Helman, and he would be the same person despite the fact that the trick for being authenticated is different. I would not consider the session key and other "mechanical" info in the token as claims, for the same reason as above; they don't have any semantic other than the sheer authentication mechanism they enable. In other words, I don't think it is helpful to think of credentials as claims.
Bottom line: the various WS-Security specs define a claim as pretty much anything that ends up being in a token. I don't think that it is useful to consider authentication artifacts as claims, in fact I think it may make things confusing for the developer that uses claims through the app for authorization decisions. Hence, please know that every time i talk about claims I am purposefully excluding passwords, session keys & friends. BTW, that was one of the heated discussions I had with David.
|Since we are at the dispelling game, let me digress further for 30 seconds. X509 certs are NOT tokens!!! The corresponding token profile tells you how to create X509 tokens from X509 certs, but the two things are.simply.not.the.same.|
By extension, CAs are NOT STSes!
Ahh, I feel better now. We can go ahead 🙂
What's the difference with the traditional ACL/role approach? Well, roles would not work very well in our scenario. In your household there's not an official "Swarovski toucher" group to which users need to belong for being able to keep the butterfly: rather, the decision is taken by examining a number of facts about the requestor. We mentioned age, but in fact the factors are so numerous and differentiated that it is simply not possible to hope of codifying them all in something so rigid as usage roles.
Roles are great when resources are part of a pool governed by a single entity. All the PCs and faxes and photocopiers at your workplace are tools intended to support a certain value chain, and you and your coworkers have a well definite place in the value chain too: it is relatively easy to devise a role-privileges relationship. But in less structured environments claims offer more freedom.
Sometimes it may happen that roles are an emergent property of the usage of the application: if authorization-wise all users roughly fall in N categories, it is possible to codify a dynamic role whose memberships are calculated on the fly: however that would be a fairly brittle balance, prone to disruption by any change in the authz logic, and claims are still more expressive.
|Note: a claim can be used for expressing group membership, hence many of the traditional practices are actually a proper subset of what can be accomplished via claims.|
So far we kept the security developer perspective. What's so great about this system for the resource developers (as opposed to the devs of the security systems)? Well, freedom. You can now express your requirements directly at the granularity that you need, using the language that is most appropriate for your business.
Let's say you are an ISV that develops web controls, and you want to write an image gallery & viewer. Today you can provide just the sheer functionality, without much control on how it will be used. In a claim based world, you may expose a databinding for the claim Age and use that info for automatically hiding inappropriate pictures if the viewer is under age. You may even ask for a Nationality claim, and apply the different age limit according to the differences among the various countries' law systems. You may have a map control that databinds to an optional claim IsColorblind, and adjust the map palette accordingly. You may have a control that shows edit UI options or just a readonly rendering according to a role claim. The possibility are endless! And think how great it would to be able to drop those identity aware controls on a website and have the policy be rendered automatically in the login page, so that the user is prompted directly for the info that are actually needed.
All this would be possible without the need of worrying about how those info made their way into the current session, which is great news for decoupling: i don't care if get it from a SAML or from an XrML, what's important is that you give me an http://claims.contoso.org/HairLenght. The authority that emitted the information is, instead, potentially very relevant; and that gives us a nice lead in for the next part.
Profile vs. Token
Claims are a powerful way of obtaining information, but they are not the only one. In fact, until now everything more or less worked without explicitly using them. Relying parties can obtain information about subjects by asking for them in a registration step, via background checks, out of band exchanges, and so on. Once those info have been obtained with a reasonable degree of confidence (degree being dependent on the kind of application: in the case of self asserted info, it's pretty much zero) they become part of the user profile. When the user sign in for a session, sending his credentials for verification, the profile wakes up and application decisions starts to be made according to its values. This is the "hostage identity" concept that we describe in our book: the identity of the user can be used only at the site that stores the corresponding profile, and it's awaken by a successful authentication.
Some of the info about the user can be damn hard for the relying party to obtain: credit score or assurance of a clean criminal record are two obvious examples, but even name and birth date are difficult to get if you are required a high degree of confidence about the validity of the data. That's where the entire claim based system comes to help: by specifying whose authority you respect for the set of claims you are interested into, you empower the subject to leverage his relationship with that authority and obtain a suitable token. The token is cryptographically guaranteed to come from the intended source and all the usual goodness we describe at this point. Fantastic.
Does that mean that we should now use claims and tokens for everything, and free the hostage identity? Hmm, not necessarily. Wine is good, but water is still an appropriate drink in a lot of occasions.
Let's say that a big online book store (bobs) decides to start accepting customers which present a token with name and shipping address issued by some big internet authority. Bobs can now clean their stores of all of the info they now receive from the authority (which is great for liability and a number of other things) and change the authentication logic accordingly. However there are still a lot of data that pertain the business that a subject makes with bobs and that cannot be provided by an external authority: the last 10 books he bought, for example. Hence the new identity context is a composition of what is received in form of claim and what is obtained by the profile, which does not disappear after all but simply can jettison the info that are better obtained from somewhere else. Should the developer know of the difference between the two info? I think so, since it really makes a difference (a date of birth gathered during some questionnaire or a date of birth certified by an authority carry different business weight); however I believe that the API should be uniform, so that information can migrate from one source to the other without disrupting too much the application.
From the above, and from other considerations, I discovered the following principle:
You want to receive in form of claims what you'd have an hard time finding out by yourself
So far that principle proved to be a useful tool when reasoning about claim based systems, especially for understanding how to change existing systems toward the new model. Let's test it on the controversial scenario we mentioned in the opening: should a website using personal cards for authentication ask for the claims it needs at sign in time?
Let's see: if the website needs some PII (personally identifiable information) but cannot store it, the easiest way of finding out those values at every session is asking for the corresponding claims: such claims will be promptly forgotten at every logoff. In that case the signup phase will just ask for the credentials components of the token, plus the PPID.
If the website can or must store that info, for example it needs the email for sending notifications even when the user is not signed in, then it makes little sense to ask for the same info at every sign in. In this case we reverse the interaction: at sign up we require all the claims we need, and at sign in time we just require the credentials (since it's easy to obtain all the other info from the profile).
There is a third case, in which the website needs to store the info for out of session usage but also must guarantee that the info are as up-to-date as they can be. In that case the easiest solution is asking for the same claim set both at sign up and sign in time, making sure that at every sign in we update the profile with any changes we see.
In all the three cases the principle worked pretty well, and in the managed card case works even better. If you find a counterexample please let me know, but until that does not happen I'll keep using it 🙂
Well, that's it. It's 2:10 AM, I got a bit carried away... but I think that this is all stuff we should explore more and I am thinking of other deliverables on the topic. If you have questions or comments, feel free to chime in!