Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webhook Signatures and Validation #4224

Open
EvanMerlock opened this issue Dec 22, 2024 · 2 comments
Open

Webhook Signatures and Validation #4224

EvanMerlock opened this issue Dec 22, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@EvanMerlock
Copy link
Collaborator

What problem would you like to solve? Please describe:
It should be possible to validate that a given webhook payload came from a specific GoAlert instance and that it wasn't tampered with over the wire.

Describe the solution you'd like:
By signing a webhook payload and sending that signature as an HTTP header, we can validate that (so long as the transport protocol is secure, e.g. HTTPS) a webhook payload came from a specific GoAlert instance. This would also ensure tampering doesn't happen.

Describe alternatives you've considered:
Including a bearer token, basic auth, or other authN/Z protocol as part of the webhook delivery mechanism would give stronger guarantees than "this payload came from this GoAlert instance" (e.g. "this payload came from this GoAlert delivery method") but would involve potentially storing credentials for each webhook delivery method.

Similarly, having signing keys for each webhook delivery method (per user, etc) would cause the same "credential bloat" but would avoid the risk of end-user credential rotation (like basic AuthN/Z or another form of end-user provided credential solution). I think it is a safe assumption to make that an end-user should "trust" all webhooks originating from a given GoAlert instance. Whether or not the application receiving the webhook should act upon a received webhook once it has been validated is likely not a concern of GoAlert which sends the webhook.

Additional context:
Sketching out a solution, it is likely that the simplest approach is to use a single Keyring per instance that can be manually rotated via the API and sign the webhook as it gets delivered. The public key could be accessed via the UI or API (proof that it "came from this specific GoAlert instance") and used by the receiving party to validate. I'm going to try writing this up.

@mastercactapus
Copy link
Member

This makes sense. The primary problem is "proving" that a request came from a trusted application. Webhook URLs can currently contain credentials, which can address some of the concerns, including per-config auth.

What's left is knowing where it came from, and a public/private key approach would work well with that, as any receiving application can then verify.

As for implementation, maybe break this into three parts:

  1. Add a new non-auto-rotating keyring, set a header, add a smoketest to validate
  2. Expose public key and how-to-validate in the UI
  3. For rotation, since the secret is never shared -- and rotating would break everything; is it necessary? Instead, it may make sense to have a top-level GoAlert option that is "reset ALL keyrings" in case of database + encryption key compromise but where you want to keep your config. For webhook signatures alone, since no secret is ever shared, or unencrypted at rest, I'm not sure there's a scenario where a rotation would be necessary that wouldn't also include all session tokens, API keys, etc...

@EvanMerlock
Copy link
Collaborator Author

For rotation, since the secret is never shared -- and rotating would break everything; is it necessary?

I tend to agree it is unnecessary to be able to individually rotate the single key-ring...

Instead, it may make sense to have a top-level GoAlert option that is "reset ALL keyrings" in case of database + encryption key compromise but where you want to keep your config.

Agreed. Not sure it's a prerequisite of this functionality, it'd be important either way

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants