HASS-WH-Triggers is a Flask webapp that allows you to store predefined triggers, which can be used to fire Webhook trigger based automations in Home Assistant.
Authentication is required to access the list of triggers. Logging in requires a registered username, password and one of the following:
- A device to perform FIDO2 / WebAuthn authentication. This could be a Security Key by e.g. Yubico (or other FIDO2 device vendors), Android 7+, Windows Hello or Apple’s Touch ID on Mac OS (only when using Google Chrome or Safari 14). iOs devices with version 13+ support hardware tokens, and iOs 14+ supports Touch ID or Face ID (depending on your device) in Safari. More information on WebAuthn can be found here. You can test if your device is WebAuthn compatible at this site: https://webauthn.io/.
- An enrolled TOTP token (the ones used with Google Authenticator (Android, iOs))
- A One-Time-Password sent to the user by the admin
The purpose of this tool is to provide external access to specific Home Assistant automations without exposing Home Assistant itself / granting full access to users with less privileges. Currently Home Assistant has no concept of role based access from start to end. So whoever can login into Home Assistant can pretty much control everythig. By limiting the users access to a set of specific automations, you can provide restricted control for 3rd parties.
Example: You have an automated door lock and want to grant access to your home to a sibling. You however don't want them to control anything else. Hence you (currently) can't solve this problem by adding a dedicated user in Home Assistant. There are solutions to this problem with a varying degree of usability, effort to set up, and most importantly: security.
This webapp solves the problem by only providing predefined triggers (buttons) for webhook-based automations in a simple user interface. So in the example from above your sibling would only see the button Unlock door, but besides that have no other control over your environment.
The following steps have been taken to make this tool fairly safe to use:
- A valid username and password are required
- 2-Factor authentication is a strict requirement
- Registering a new user requires a manually created registration token
- Clients failing to authenticate / register will be banned after a configurable amount of failed attempts for a configurable amount of time
- No API-level access to Home Assistant is required (only the public, but secret, webhooks are called)
- Triggers can optionally be protected by their individual password / PIN
Home Assistant provides Webhook triggers to execute automations. These triggers can be fired from the internet without any authentication. By using a cryptic webbhook id it is pretty unlikely an attacker is able to execute the automation by guessing the webhook id.
This tool leverages those triggers to execute automations remotely (it can run on any server in the web that supports Flask apps). Within a trigger you specify the used webhook URI, JSON-data that should be included as a payload, optionally the name of the user that fires the trigger, and also optionally a password that is required to fire the selected trigger. The latter serves to configure multiple triggers, but only allowing certain triggers to be fired if the secret is known to the user.
Because of the nature of webhook triggers your Home Assistant installation has to be exposed to the internet. Or at least the webhook part of it. You can configure to disable certificate checks when calling the webhooks if you are using self-signed certificates for Home Assistant. FIDO2 / WebAuthn (the token-part of the built-in security) does not work without certificates. So however you deploy the app, make sure it can be accessed using an encrypted connection.
Head over to the wiki for information on how to install and operate this tool.
This app is in an early stage and should only be used with great caution. I am not responsible for any damage that might result out of using my work. Use at your own risk! I also have to mention, that this is my first Flask app. So I might be doing some pretty stupid stuff. Feel free to review my code and suggest improvements.