On Thu, Feb 11, 2010 at 8:21 AM, Miguel Cabeça firstname.lastname@example.org wrote:
I fully understand this. When you say you are signing the request (payload and shape) you are in fact authenticating the source of the request.
When you establish a TLS connection with client certificates you are creating an encrypted AND authenticated channel. Everything that traverses that channel can be assumed to be an authenticated payload.
So, in both cases you have authentication of the payload, albeit on different levels (transport level vs application level)
Sure - what happens to the payload after it has left the TLS
connection? To use SMTP as an example, if you want to allow arbitrary
recipients of an email to verify it was sent by a particular
individual, you do not trust the transport layer security that allowed
the message to be injected. You digitally sign the message itself,
and allow any recipient to verify the message with the signers public
It’s not crazy to imagine a world where requests are accepted via
HTTPS, and then get relayed to their final destination via AMQP. By
relying on TLS, you make it very difficult for that final endpoint to
verify that the message it received is the one sent by the original
The source of our disagreement is that I don’t think we should force
decisions about the transport layer in order to gain a perceived
benefit of simplicity in the application layer. By signing each
request, we gain the ability to, at any link in the chain, verify that
the request has not been tampered with. We gain a huge amount of
application architecture flexibility, and it’s applicable to a much
wider range of problems.
What for? If you already have an authenticated TLS connection, signing the payload inside that channel gives you nothing more but complexity and overhead. Everything is taken care of by the security layer, man-in-the-middle attacks, replay attacks, etc. If you do not have an authenticated TLS connection, signing the payload gives you the necessary authentication of the client, and you have to implement additional protections against the more common attacks.
Again, you’re taking assumptions about the transport layer and forcing
them on the application architecture. If you want to ensure that each
Chef client uses an authenticated TLS connection to talk to the Chef
Server, you should absolutely do that.
I get that, for your use case, you don’t see any practical benefit
to not just using a client-authenticated TLS handshake for
authentication. I, on the other hand, see a bunch of use cases where
there is practical benefit to not using client-authenticated TLS
handshakes for authentication.
What I’m trying to say here is that using payload signing INSIDE an authenticated TLS channel gives you nothing additionally in terms of authentication. The TLS channel can give you encryption, but can also give you optional authentication.
This last feature of TLS could have been used. Instead you are suggesting the use of the encryption feature of TLS (ignoring the authentication feature) and implementing authentication yourself of the payload. Am I making any sense?
Yes - and my response is that, if we did what you are saying, we would
be constraining the way requests can be received and verified by the
system to those that rely on point-to-point TLS connections. While
that is true today in many cases, it is already not true in many Chef
deployments, and may not be true in many future ones.
Or you could use TLS to protect AMQP, or use TLS to protect SMTP, or use TLS to protect any other protocol you choose besides HTTP to transmit Chef requests.
You’re assuming a point-to-point, one client to single host
architecture. You can build an application that relies on transport
layer authentication for security, and by doing so you add the
constraint that it must have all communication occur over that
transport layer. By digitally signing each request, we gain the
flexibility of being able to re-use that functionality across any
transport layer, to serialize and distribute requests in any way we
see fit, and to continually ensure that the payload is exactly as it
was created by the signing client, regardless of intervening
Imagine a scenario where you start building orchestration
functionality around Chef, where each client is gossiping about it’s
current status (“I’m at step one! I’m at step two! I’m the
master!”). In a world where we only had TLS for client
authentication, each of those messages would need to be either sent
via a specific point-to-point connection with every other member of
the quorum, or coordinated through a central server.
In a world where each client signs their own payloads, you have lots
of options. The clients themselves can gossip about their public
keys, they can sign the payload of each gossip request, and they can
do it via multi-cast.
That’s just one example - there are many more.
Don’t get me wrong on this, I’ll use this authentication method when 0.8 is released, but I think It was an unnecessary development effort.
I agree that it might not have been necessary for the use case you
have foremost in your mind (which is a single chef client
communicating with a remote chef server over HTTPS,) but I think it
was absolutely necessary for a huge number of other use cases.
Adam Jacob, CTO
T: (206) 508-7449 E: email@example.com