openhab-cloud icon indicating copy to clipboard operation
openhab-cloud copied to clipboard

Webhook with HMAC X-signature validation (no basic authentication)

Open jsjames opened this issue 6 months ago • 5 comments

There are many instances where apis are moving to support HMAC X-Signature verification and discontinue support of basic authentication in their webhook (eg. Rachio API -(https://rachio.readme.io/reference/webhooks#webhook-authentication)). Are there any ideas/suggestions on how to support this type of webhook with openHAB cloud? The only other alternative I see would require users to open up ports on their machines.

jsjames avatar Jun 11 '25 15:06 jsjames

So, I understand the issue, my hesitation here is that we have a binding that requires all of its communication to proxy through the cloud service. Right now we do support standard Oauth requests for 3rd party integrations, which is what Alex and Google both use for voice requests, but this would require a whole new type of a non-standard registration to tie the Signature in the header to a openHAB (so some type of registration endpoint would be needed that openHAB calls with the API key, which returns a webhook URL to use) . Again, not ideal, but if its the only option i'm open to discussing.

digitaldan avatar Jun 11 '25 15:06 digitaldan

Has this been brought up before for any other services?

In looking at other services, it seems different apis implement different hash algos and different header fields. Just thinking of a more general way to implement ... Would the cloud service actually need the API key/etc.? For instance, if the URL was http://home.myopenhab.org/<%OPENHAB-UID%>/rachio/webhook/, then the cloud service would know where to forward the packet and the local openhab instance would then be responsible for validating the signature? This might have a security hole I'm not thinking of though.

jsjames avatar Jun 11 '25 16:06 jsjames

This might have a security hole I'm not thinking of though.

Correct, we do not want to expose the UID of the openHAB. We also need to be able to only allow authorized requests, so openHAB cloud would need to verify that it comes from rachio and not someone else before proxying. (edit, i guess the binding could do this, but i hate opening an unauthorized endpoint that sends data back to openhab, we don't do this anywhere else)

Has this been brought up before for any other services?

Other then voice services, not really, and honestly the upcoming Matter binding may make those voice services obsolete in a year or two as it replaces it with faster local control ( its already replaced the Alexa skill for me).

We used to support IFTTT, but their polling architecture was quite heavy weight, and we eventually disabled it.

digitaldan avatar Jun 11 '25 17:06 digitaldan

We could hash the openHAB UID to address the first concern, but if we need the cloud service to verify the request before sending to the local openHAB - this will require some type of registration with the API key per your original suggestion - I was just hoping there would be an "easy" implementation.

I am surprised more webhook services don't require this though - from what I have inferred in reading on the web, this is fairly common. I don't think we should do something special for the rachio binding but would prefer a more generic approach.

To make something somewhat generic, we could have a registration call with the following parameters:

  • Header field which contains the signature - in Rachio's api this would be "x-signature"
  • Hashing algo - in Rachio's case, this would be "HMAC-SHA256"
  • and an API Key used as the private key

The registration could return a unique base URL or a key to include as a parameter in the url.

In the meantime, Rachio has not removed basic authentication in their legacy API for their controller - so this isn't a rush. At some point it would be good to support their new API which is required to support their newer devices (smart hose valves, lighting, ...).

jsjames avatar Jun 12 '25 14:06 jsjames

am surprised more webhook services don't require this though

Agreed, I think its very common in many places in SaaS, but not so much in consumer IoT (at least consumer cloud IoT), which is why i think it has not been an real issue so far.

What i was thinking, if we really need to do this, is something like this:

We would have a general Webhook registration API. Your openHAB would call /api/registerWebhook along with some local API path (or something) to proxy to , this would return a webhook URL (so https://home.myopenhab.org/api/webhook/{random uuid}) as well as some type of TTL for when it expires. The openHAB would just need to call refresh on this before the TTL expire to keep it active (maybe every hour). This webhook would pass all headers, HTTP methods, etc, back as is to openHAB, so would not be aware of the actual implementation of whats being proxied.

This is after 5 mins of thinking about it, so i have not really sat down and thought it out, or how other bindings would interact with the cloud binding, thats not been done before.

My intention with the cloud service is to keep it as minimal as possible, running a general proxy service is not ideal, i'm always on the lookout for alternatives that keep as much of this local to openHAB as possible.

digitaldan avatar Jun 12 '25 15:06 digitaldan