Home Assistant Command Line Authentication for Authelia
Want to integrate Authelia with Home Assistant? Unfortunately Home Assistant lacks support for SSO, but it does support a rather unique command line authentication mode.
In short: Home Assistant will execute a script, passing in the provided username/password from the client. If the script exits with code 0
then the login is accepted, if not it’s rejected.
Authelia, in turn, has a handy /api/verify
endpoint that can be used by proxies to implement forward authetication with.
Combing these together, we can simply use curl
in a command line authentication script to verify the credentials with Authelia. Additionally, we can pass the X-Original-URL
header to allow Authelia to perform authorization.
There are some drawbacks:
- 2FA is not supported. You’ll need to configure Authelia to use 1FA for your Home Assistant service.
- Since the request comes from the Home Assistant server, you’ll need to ensure that abuse counter-measures don’t block your sever (ex. fail2ban).
How to Use#
- Save the code to a script called
authelia.sh
in the same folder as your Home Assistantconfiguration.yaml
file. - Ensure the script is executable by running
chmod +x authelia.sh
. - In your
configuration.yaml
add:
Then restart Home Assistant and you should be all set!
Code#
#!/bin/bash | |
set -euo pipefail | |
IFS=$'\n\t' | |
## BEGIN CONFIGURATION SECTION ## | |
# The domain/path of your authelia service. For example: | |
# - sso.example.com | |
# - example.com/auth | |
# - example.com:8443 | |
# | |
# Do not include protocol or a trailing slash. Redirects will | |
# _not_ be followed. | |
# For safety we will force the request to be done over https. | |
AUTHELIA_DOMAIN="sso.example.com" | |
# The fully URL for your Home Assistant instance. This will | |
# be provided to Authelia for authoriziation purposes. | |
HOME_ASSISTANT_URL="https://home.example.com" | |
# Usernames should be validated using a regular expression to be of | |
# a known format. Special characters will be escaped anyway, but it is | |
# generally not recommended to allow more than necessary. | |
# This pattern is set by default. In your config file, you can either | |
# overwrite it with a different one or use "unset USERNAME_PATTERN" to | |
# disable validation completely. | |
USERNAME_PATTERN='^[a-z|A-Z|0-9|_|-|.]+$' | |
## END CONFIGURATION SECTION ## | |
# Log messages to stderr. | |
log() { | |
echo "$1" >&2 | |
} | |
err=0 | |
# Check username and password are present and not malformed. | |
if [ -z "$username" ] || [ -z "$password" ]; then | |
log "Need username and password environment variables." | |
err=1 | |
elif [ ! -z "$USERNAME_PATTERN" ]; then | |
username_match=$(echo "$username" | sed -r "s/$USERNAME_PATTERN/x/") | |
if [ "$username_match" != "x" ]; then | |
log "Username '$username' has an invalid format." | |
err=1 | |
fi | |
fi | |
[ $err -ne 0 ] && exit 2 | |
status_code=$(curl --head --silent \ | |
--request GET \ | |
--header "X-Original-URL: https://${HOME_ASSISTANT_URL}" \ | |
--basic --user "${username}:${password}" \ | |
-o /dev/null \ | |
-w '%{http_code}' \ | |
"https://${AUTHELIA_DOMAIN}/api/verify?auth=basic") | |
# Auth success! | |
[ $status_code -eq 200 ] && exit 0 | |
# Auth failed | |
exit 3 |