With the web hook, how should my app verify the event is genuine?

Hello. I’ve just started reading through the docs on the API. I have a simple web app I wrote in Python to log my expenses. I now want to integrate with Monzo to make addition of expenses automated.

With the web hooks, I see that my user (me) has to authenticate with the Monzo API using OAuth, add the web hook via the Monzo API, and then Monzo will start sending events. But how does my API, which receives the Monzo event, know that the event is genuine? Seeing as the authentication is only to access the Monzo API, but no mention of authentication for Monzo to access my web hook.

1 Like

You can’t.
But you can use the web hook to trigger your code to fetch the transaction from the API (and know that that response is trustable).

1 Like

You could use the Host header that is sent with each HTTP request. Haven’t used the API before, but just calling the endpoint from curl returns ‘api.monzo.com’. You can check this by inspecting the HTTP headers you get when you recieve the request.

sudocode:

if(host !== "api.monzo.com") {return false} {return true}

It’s worth mentioning that without any sort of authentication it’s very difficult to ensure the validity of an HTTP request since all of the headers/data can be manipulated. This is a whole other topic but I think this should get you started.

Could I check by the IP? If Monza publish their IPs. Or by the name on the SSL certificate?

You could use the IP but it will be brittle (i.e. break when Monzo’s IP changes). You can’t use their SSL cert as when their delivering the web hook their machines are the client in the HTTP connection not the server.

Sounds like an obvious use case for TLS mutual authentication, if monzo were to choose to enable their client to respond to these requests

Or just do what practically everyone else does and sign the payload in some way - Mailgun’s looks simple enough for both ends to implement for example.

1 Like