After researching various webhook implementations, I have noticed a trend in the security mechanisms they use.
Visual Studio Team Services webhooks use Basic Authentication.
Microsoft Graph webhooks sends a plaintext "clientState" in the body of each webhook call. The receiver validates the clientState against a known value. This is similar to Basic Authentication, in that a plaintext credential is sent over the wire with each request.
Slack outgoing webhooks use a very similar technique to Microsoft Graph: a plaintext "token" is sent in the body of each request. The receiver validates the token against a known value. Again, very similar to Basic Authentication: a plaintext credential is sent over the wire with each request.
In all the above examples, the credential never expires. Also, there's only one "token" value per hook, which means there is no way to gracefully rotate a token if it becomes compromised.
My understanding on Basic Auth is that it is generally avoided because it requires the client to store credentials in plaintext, which is a security risk.
Moving on, Github and Box webhooks use shared secrets and signatures for authentication.
The security mechanisms used for webhooks stand in contrast to the security mechanisms used by their respective API - they all use OAuth 2.0 and JWT bearer tokens.
I'm yet to see a webhook implementation that uses token based authentication - e.g., a platform that sends a JWT bearer token in the Authorization header.
My question is: what are the reasons that webhook implementations tend towards less secure mechanisms like Basic Authentication? Why don't they just use OAuth 2.0 and JWT, just like their own API does?