mozilla/id-specs — pull request #16 by warner (2012-07-07 00:47:15+00:00)
Title: Chains

minor tweaks to the cert-chain section

I noticed the "delegate" field went away.. good idea. So I think signers will fall into two cases:

* RPs (or designated/delegated-to RPs) who are signing a user key: `allowChaining=false` and `principal.email` limits the delegation to a specific user. The chain looks like:
1. A.com/.well-known/something -> pubkey A
1. [iss=A.com, principal.email=bob@A.com, exp, publicKey=B] .sign(key=A)
1. [aud=domain, exp] .sign(key=B)
* RPs delegating to another RP-like key: `allowChaining=true` and `principal.domain` (or maybe `principal.email`, although it seems unlikely) is used to limit the delegation. The "load balancers with separate keys" use-case looks like:
1. A.com/.well-known/something -> pubkey A
1. [iss=A.com, principal.domain=A.com, exp, publicKey=B] .sign(key=A)
1. [iss=A.com??, principal.email=bob@A.com, exp, publicKey=C] .sign(key=B)
1. [aud=domain, exp] .sign(key=C)
* and the bigtent use case looks similar:
1. browserid.org/.well-known/something -> pubkey A
1. [iss=browserid.org, principal.domain=A.com, exp, publicKey=B] .sign(key=A)
1. [iss=??, principal.email=bob@A.com, exp, publicKey=C] .sign(key=B)
1. [aud=domain, exp] .sign(key=C)
* `exp` can be used in both

(what should the `iss` of the second (delegated-to) cert be? It feels like the only place where `iss` is relevant is in the very first cert, as it tells the verifier where to find the first key).

There's an asymmetry that feels slightly odd (but probably safer): both cases are really delegating authority to a second key, but `allowChaining` is required if the first key has `principal.domain` instead of `principal.email`, or if the second key wants to have a `principal` field instead of `aud`. The number of words needed to describe that makes the flag seem a bit artificial. Maybe the rule is "if allowChaining=false, the next certificate must be the last one (i.e. the assertion)".

What might seem cleaner? Here's a straw-man.. if we didn't use `allowChaining`, but instead relied on `principal` and `exp` to control delegated power, would it still be safe? It *would* mean the RP couldn't prohibit delegation: users could build arbitrarily long certchains, but they'd still be limited to their one `principal.email=`. And there's a relevant maxim from the obj-cap world (from Ka-Ping Yee) which says "don't prohibit what you can't prevent". Since users can sign as many assertions as they want (until `exp` runs out), prohibiting them from delegating to other keys isn't really any safer, but would annoy a user who wants to e.g. delegate to a cluster of per-browser short-expiry keys and keep their main key mostly offline (exactly analogous to the load-balancers scenario for the RP).

The extra flag is appropriately conservative and opt-in: nothing new happens unless it's present. But I'm looking for a way to define what exactly it enables that doesn't make the normal "enable aud=" case seem out-of-place.