After describing Content-Signature in my last blog, it was picked up by InfoQ. Also had a great private email exchange with Jean-Jacques Dubray in which we discussed various usecases for signature protocols. Firstly, before I dive in, a disclaimer. I am not a security expert and don’t pretend to be one. While I have used various authentication and authorization protocols over the years, I have not been a designer or implementer of them. So, here’s some use cases for Content-Signature:
The NULL Use Case
I think one of the most important aspects of something like Content-Signature is that this information can be ignored by any party in the request/response chain. The signature becomes just another thing that describes the entity being passed around. Why is this important? I’ll give a simple example first, then later in the blog a more complex one.
Consider a simple blog. Let’s say I posted some really stupid comment on somebody’s blog. Its actually very easy to impersonate somebody in the comments section of anyone’s blog. So, if a reader read my stupid comment and thought “Did Bill Burke really say that?!?”, how would they know if I really did post or not? While not that practical in reality, what I could do is sign each comment I made to a blog. That way, a reader could verify my signature if they so desired.
What’s interesting about this use case is that the blog itself doesn’t care about the signature. Nor do most comment readers care about the signature. Only a specific party cares about the signature. With a header based approach like Content-Signature, renderers can completely ignore the signature applied to the comment if they do not care or understand how to process it. This is why something like Content-Signature is better than multipart/signed, IMO. Another interesting thing is that if the blog moved, lets say from Blogspot to WordPress, the import could take along the comment signature with it. Even though the comment is served under a different URL, the signature is still valid.
Authentication, Authorization, and Message Integrity All In One
Another use for Content-Signature is that it could be used for authentication, authorization, and message integrity, all at the same time. When a server received a request signed with Content-Signature, it could look into the metadata of Content-Signature to determine the signer. (This assumes a asymetric key-pair solution) Look up the public key of the signer in private registry. Verify the signature with this public key. If it is successful, the server knows a) that it is the signer that sent the message, and b)that the integrity of the message is good as well. Now that the identity of the signer is known and valid, the server can determine internally whether the signer is authorized to make the request. Because Content-Signature is flexible and allows you to add as much metadata as you wish to the signature, additional information like the request URL, a timestampe, a NONCE, whatever could be added to create a more secure process.
Consider a vacation request application. An employee creates a vacation request form. Signs it by adding a Content-Signature header and posts it to his manager. The manager reads the request form, signs it, forwards the document and appends his signature to the Content-Signature header. Forwards the doc and the new Content-Signature header to HR. HR knows both parties approved of the document and processes the vacation.
Consider a simple order entry workflow where each phase of order fulfillment needs to happen in a specific order. Each phase also needs to know that the previous phases really happened. i.e. don’t ship the product until it has been payed for. It could work like this:
- Customer posts order to order-entry system. Signing it with his information.
- Order entry verifies signature. It also adds an additional signature “order-entry” which is customer-sig+message body.
- Billing gets the order next. It verifies the customer signature and that the “order-entry” signature. Because “order-entry” was created with the customer-sig and message body, the billing system knows that the order is valid and that the exact order was looked at by the order-entry system. The Billing system signs the message with customer-sig+message body.
- Shipping gets the order next. It verifies the customer and billing signatures and ships the product.
Ignorant Gateways and Authorization of Actions
Another use case that JJ talked to me about is the ignorant gateway scenario. Imagine an application that would listen to your twitter messages and forward these messages, via SMS, to your friends’ mobile. You would automatically be billed instead of the application forwarding the tweets. In this case, Twitter is the ignorant, pass-through, gateway. It knows nothing about the whole authorization process. In an imaginary world, this is how it could work:
- You post a twitter message. You sign (“AT&T Auth Code” + “timestamp” + “message-id” + message body) and attach it as a signature to the method.
- The App is listening to twitter. Does an SMS of message and sends along signature too.
- AT&T gets the SMS, looks at the signature. Verifies it came from the user. Because the “AT&T Auth Code” is part of the signature, AT&T knows that “Bill Burke” sent the SMS. Since the “timestamp” and “Message-id” are part of the signature, AT&T can check to see if the SMS is a duplicate. If all of these pass, then AT&T can bill “Bill Burke” instead of the App for the SMS.
This is also an example of authorization of a specific action via a signature. I dont think you need separate signatures for each action you want to authorize. It can just be a matter of concatenating multiple auth-codes within the same signature. The hole in this approach is that hostile apps could trick users into adding an authorization to their signatures. i.e. “pay-me-$20-from-your-bank-account”. This is why it is important for providers be involved in authorization code creation.
A complex workflow could combine some or all of these use cases together with the coordination of many different applications.
What it boils down to, is that, IMO, something like Content-Signature gives you a lot of flexibility when defining a distributed interface. It allows you to combine metadata about a representation to the signing of a representation. Because it is a header, it can be ignored if desired. Since it is a set of simple name value pairs, it is very easy to create and parse. (Well, depending on your platform, actually signing the message might be difficult, but, hey…). Personally, I’m very interested in applying signatures to the RESTful interface we’re creating for our workflow engine. Signatures just seem like a simpler way to manage multi-tier authentication and authorization. Who knows, maybe I’m wrong here…