3 ms·
This seems deeply confused. When you are making an API request, you've validated the certificate of the system you're making the request to and in the process
by erikerikson 1y ago
This seems deeply confused.
When you are making an API request, you've validated the certificate of the system you're making the request to and in the process doing so over a secure connection. You've usually authenticated yourself, also over a secure connection, and are including some sort of token validating that authentication which provides your authorization as well.
When you are accepting a call in your web hook, you need to ensure that the call came from the authenticated source which the signature provides. The web hook caller connects using the same certificate validation and secure connection infrastructure. They won't connect if your certificate doesn't validate or they can't establish a secure connection. The signature is their mechanism of authenticating with your API except that they are the authority of their identity.
That last bit is where the the contradiction falls away, the webhook implementer is retaining authentication authority and infrastructure (whether you call them or they are calling you) rather than asking the client to provide an authentication system for them to validate themselves with.
[edit: there's an additional factor. If you move authentication to the web hook implementer you lose control of what authentication mechanisms are in use. Having to implement everyone's authentication systems would be a nightmare full of contradictions. You also open yourself up to having to follow client processes, attend meetings, and otherwise not be able to automate the process of setting up a webhook.]
- losvedir 1y agoI think you're missing the point. You're talking about someone making an API call vs receiving a webhook. However, I believe the article is drawing an obvious, if implicit, parallel to expectations for handling a webhook as customer vs handling an API call in your web app. That is, surely you've worked on a web app where you receive requests from users. Those requests are authenticated (and authorized) in various ways, from OAuth tokens to session cookies to API keys. When you're handling those requests, do you require that they're signed as well? I've rarely seen such a thing (the article points out that AWS does, for example), but most web apps I've worked on don't. We simply take the request for granted (assuming its come over a TLS connection), and then check the credential. The article is asking: if that's good enough for logic on a web app, why not in reverse? A server handling customer requests generally doesn't know their provenance either, and simply relies on the credential (unless you have IP allow-listing and other measures like that). I actually work on webhooks as well, and we sign them (and offer mTLS and various other security measures) but I sort of took all those best practices for granted. Now I'm trying to think through what the actual threat model is here, and why it doesn't apply in reverse to the REST API endpoints that we also maintain. I can see the point of signing rather than an included credential if you allow webhooks to http endpoints, but is that it? Probably better to just not allow non-https delivery URLs anyway.
- erikerikson 1y agoThe credential is proving provenance. [edit: obviously once a credential is handed out it can be misused but any such attack would put signing materials in the hands of an attacker too.]
- quectophoton 1y ago> Now I'm trying to think through what the actual threat model is here, and why it doesn't apply in reverse to the REST API endpoints that we also maintain. I can see the point of signing rather than an included credential if you allow webhooks to http endpoints, but is that it? Probably better to just not allow non-https delivery URLs anyway. My best guess: Maybe signing the webhooks assumes the TLS-terminating middlewares might not be trusted? Or some other middleware between that and the final handler. To the best of my understanding, the two options mentioned in the article require a shared secret: API keys include that secret verbatim in the request, while the signing uses the secret in an HMAC function. If asymmetric cryptography were somehow involved, I would somewhat buy the arguments about validating the origin of the request, because only one party would be able to create a valid signature. But that's not the case here, because with HMAC both parties have access to the same secret used to create a "signature" (which is more like a salted hash, so creating and validating a signature are the same process). So, if both parties can produce the hash for a valid signature, and the secret is known to both ends, and there's no advantage over API keys when using TLS (assuming TLS is not broken), then I can only think that the problem is what happens outside TLS. That's why I think the threat model would be a compromised TLS-terminating proxy, or some compromised component in between TLS-terminating proxy and the final application handling the request. Sounds like zero-trust shenanigans. If I'm misunderstanding anything, I'm more than happy to be corrected.
- deleted 1y ago[deleted]
- eqvinox 1y ago> […] You've usually authenticated yourself, also over a secure connection, and are including some sort of token validating that authentication […] nit: not sure if that's just me but I was confused by this wording; with "authenticated yourself" you're referring to an initial permanent-token/login ⇒ session-token step? I initially thought you were implying something on the same connection the API call is made on, which would have to be TLS client certificates (HTTP bearer auth is already the token itself.)
- erikerikson 1y agoI'm sorry. This is almost surely my poor wording. TL;DR: I was thinking of bearer token auth flows and not intentionally excluding other forms of authentication. Part of the problem is reverse ordering. When calling an API, you generally authenticate yourself, often to obtain a temporary token but it can be in the same call as you note via certificate. Only then do you make the API call that you actually wanted to make. I first wrote about making the API call and only then followed with discussing the authentication. In that, I was thinking of the permanent token to session token model but you're absolutely right that mutual auth could bypass that stage. The certificate-based authentication would still precede the API call processing, but would obviate the use/sending of a token. However, I haven't seen that used in automated APIs because of the management overhead and increased barrier for the more entry level skill end of the customer base. I have absolutely seen it in use for internal service interfaces. Sorry that my words were a tangle, thank you very much for helping me clarify (or at least hopefully do so). [edit: side note that with mutual auth, I've seen that as a gate to even open a socket paired with further authentication using some sort of a permanent token to session token protocol so one doesn't have to preclude the other.]
- paulddraper 1y agoI think you are confused. In either case the server authenticates with TLS and PKI. But for APIs, the client (usually) authorizes with tokens. And for webhooks, the client (usually) authorizes with signed requests. --- You could just as easily imagine API authorization with signed requests (e.g. AWS). Or webhook authorization with tokens (e.g. JIRA can do this). Or where either one uses mTLS (e.g. CMS HETS). That's not how it's usually done. But the client-server requirements for confidentiality and authenticity are the same. The only difference is who is the "client" and who is the "server."
- erikerikson 1y agoI recognize all this. Of course different mechanisms of authentication can be used in APIs. There is also of course a swap in who plays server and client when hitting a company's API vs receiving a webhook request from that same company. The key difference isn't with the mechanism of authentication (although that is different) but who specifies, implements, and maintains the authentication. Webhook providers do a lot of work to avoid putting that on their clients and to keep centralized control over their implementation.
- mfbx9da4 1y agoThe API producer will always retain ownership over the authentication mechanism. The article is comparing the use of a shared secret vs HMAC. For shared secret: Who specifies auth? The webhook producer. Who implements auth? The webhook consumer. For HMAC / signing it's exactly the same parties who do those things. Discussions about mutual TLS and public keys are out of scope.
- erikerikson 1y agoI think the webhook producer tends to implement auth in both scenarios but agree that the webhook consumer executes auth in the webhook case. You perhaps meant this but I was initially confused by what you were trying to say here. You other comment was far more helpful, thank you for making it. In summary of my other comment, it is the case that the implementation and execution roles are the same but the threat surface is very different.
- mfbx9da4 1y ago> If you move authentication to the web hook implementer you lose control of what authentication mechanisms are in use I don't understand where you are coming from. The article is comparing shared secret vs signing. In both those auth methods the "control" remains in the same place. The webhook consumer has to do the auth verification. The webhook sender mandates what authentication method is used. Under none of these scenarios is the webhook consumer providing their own "authentication system".
- erikerikson 1y agoRe-reading the article, I'm confused about where I was coming from too. The article claims that it was last updated May 7th but the two Archive captures[0][1] seem to be broken for me ATM. The link to the blog source on GitHub[2] (linked from the page) just gave me a 404 and searching for the file didn't yield another location so I can't look for a commit timestamp or delta. There is a bit of switching back and forth between speaking from an API provider and an API consumer standpoint and it is possible that in not reading sufficiently carefully I misunderstood. I was also previously oblivious to the context of the product they are marketing here that turns out to include API SDK generation (including a webhook acceptance sdk for validating requests? I don't know). The nuance that the implementer is an API provider providing both direct API access and a webhook delivery API could easily have caused me to misunderstand properly written words that flew over my head in the midst of getting bored with the content in my failure to understand it. A great question from the article, in its current state[3], is asking: are API keys are secure enough for webhooks? In theory, you could validate a webhook request by confirming that the API key matches your in memory copy of that key. Either that or signature validation is usually supplied by the service SDK or example code that you cut and paste anyway. Sadly, for a long time, it was too much to ask some clients to provide HTTPS security for connections and those requests had to be sent over HTTP, which would require alternative mechanisms of supplying non-repudiation (proof the content had not been altered in transit). This may be a forcing factor of the convention and thank you to Let's Encrypt and others for helping the industry shift (though I still find stragglers occasionally). In the current environment of mostly ubiquitous HTTPS any non-secure URL configuration could be rejected by a webhook sender and an API key comparison could be authentication enough while retaining the sender controlled nature of the authentication. However, that newly assumes confidentiality of the API key by two parties which a webhook implementer may not be sufficiently competent to guarantee. This could leave a webhook implementer in the position of processing malicious requests without the valid sender having a mechanism for detecting the breach and exposing the sender of the webhook request to messy, relationship damaging, potentially legal, arguments about whether they leaked a key. The signing process retains private signing materials under the custody of the sender, simplifying the threat model and reducing its surface. So, while you're right that (if we aren't talking about the webhook request implementer using webhook implementer authentication) the webhook consumer isn't providing their own authentication system, they are providing security for the authentication system in the case of API key use. Perhaps this is a version of Postel's law? Personally as a business generating SDKs for APIs I would be inclined to go the other way and encourage customers to generate SDKs with signing rather than encouraging webhooks without signing. Demand is what it is and so are clients so... I can't fault them either. Thank you for helping me understand that I had missed context (or at least giving me an opportunity to respond to the latest version of the page, though my making an error seems more probable). [0] https://web.archive.org/web/20250526130006/https://www.speakeasy.com/blog/webhook-security https://web.archive.org/web/20250526130006/https://www.speak... [1] https://web.archive.org/web/20250526184520/https://www.speakeasy.com/blog/webhook-security https://web.archive.org/web/20250526184520/https://www.speak... [2] https://www.speakeasy.com/_gh-redirect/src/content/blog/webhook-security/index.mdx https://www.speakeasy.com/_gh-redirect/src/content/blog/webh... [3] https://web.archive.org/web/20250527215821/https://www.speakeasy.com/blog/webhook-security https://web.archive.org/web/20250527215821/https://www.speak...