Most of what this article is about concerns first-party caveats only, because (for better or worse) I was trying to keep the discussion fairly basic. I'm glad it piqued your interest enough to read the macaroon paper!
> Instead, the server should HMAC the full set of its own constraints with its own key, and then a single delimiter should be added.
This basically describes a JWT, and there's nothing wrong with doing things that way; it clearly works well for a lot of cases. Macaroons provide flexibility by allowing attenuation and delegation. Hyperdex[0] and this video[1] both discuss cases where those properties may be more desirable, which may serve as clarifying examples.
> I would propose sets of constraints be added atomically with some delimiter to reduce the number of wasted HMAC cycles.
That's perfectly valid, it's also a suggestion from the macaroon paper:
> Macaroons permit many optimizations, in both their primitives and applications. For example, a reduced number of operations can be used for chained-MACs, if caveats are combined as in Figure 9.
Where figure 9 just shows including multiple "caveat assertions" in a single "caveat".
> This exposes 'TS' to potential DoS attacks where anyone can add potentially expensive-to-verify first-party constraints which there server could be tricked into thinking that it had actually added itself.
It's good to point out that this is a vector, but practically it's very easy to mitigate this sort of attack. The entire verification process is controlled by TS, so in the first place any caveats it doesn't understand will be ignored (and verification will fail because not all constraints were met). I strongly prefer failing macaroon verification as soon as possible (even if it opens up the possibility of certain timing attacks; which could at best only reveal supported caveat types and never any secrets). This alone limits the attack surface only to specific caveat formats that TS understands. From there it's easy to add other safeguards if necessary. Verification could limit the number of caveats allowed (the macaroon paper even suggests these limits could be encoded in the macaroon as "structural caveats", although currently no implementations support them), or simply fail if it takes too long to verify. As with all DoS attack prevention the goal is to mitigate as much as possible; simply rate limiting could be effective.
> I guess if you trust your link to the 3rd party, and you trust they will add the proper constraints, the only benefit is you know once they are added they cannot be removed.
When you use "third-party" you seem to be referring to attenuating the macaroon with additional "first-party" caveats. Actual "third-party" caveats can be used to verify context in a third-party system. First-party caveats confirm the context of the target service, but consider that first-party caveats could be added by other components of TS (e.g. in a service-oriented architecture) or by local client software (e.g. a browser extension), not just "third parties."
> We do now actually know which caveats were added by TS versus which were added by FS.
This is not quite true - without storing information about the originally constructed macaroon, TS has no way of knowing which caveats it issued originally and which caveats were appended later by someone else.
[0]: http://hyperdex.org/doc/latest/Authorization/#x11-630002 [1]: https://air.mozilla.org/macaroons-cookies-with-contextual-ca...