An example single sign on SSO with Authelia and Home Assistant

Please refer to the previous article to understand what is SSO and how to install and set up Authelia.

What is HomeAssistant ?

Home Assistant

Home assistant is an open source home automation server that's probably the best of crowd.

Home assistant (HA) is probably the most professional software you could run to manage all the gizmo in your home. It's may not be the easiest to set up (please refer to this page for this) because of the huge possibility it can run, but once it's set up, it's rock solid. It'll recognize and detect all your IoT stuff from China, Uncle Sam and elsewhere and add it with few clicks.

Typically, once you've installed HA, when you're adding something to your home, you'll check if the gizmo is compatible with HA before buying and most of them are!

However, there are few area where HA isn't very user friendly. Single sign on is typically a feature that HA developers refused to implement since it adds a lot of additional work to all their interfaces (mobile, web, etc...). So by default, HA provides a login page that you must validate to access it.

In this article, we'll set up a SSO solution with Authelia to avoid seeing this login page. This will work for the web interface, but since the mobile interface can not deal with Authelia, we'll also provide a fallback for the mobile interface so it runs unmodified. It's very likely that the SSO solution is less useful on mobile, since you're more likely to use the dedicated Home Assistant application anyway.

Setting up Home Assistant

I would recommend you follow the installation steps from here

Home assistant runs inside its own containers and replies on its own subdomain, let's call it ha.myhome.com

If you've installed HA in OS/Supervised mode instead of Docker's container mode, you'll have to adjust the steps below by replacing entering the container by SSH'ing to the server.

HA is handling its own (internal) update mechanism so it's quite safer and easier to run in a docker's container, unlike Authelia which doesn't deal with update and is much easier to install and update from your distribution.

I'm focusing on using SSO for the application once it's correctly installed on your server.

Thus, once you are satisfied with the application, you'll need to change few configuration keys in order to make it work with SSO.

NGINX configuration

We are using NGINX here for proxifying a HTTPS connection to HA's docker instance.

In order to do so, you must have set the right DNS entry in your domain's DNS zone (something like ha.myhome.com. A yourServerIP).

Step 1. HAM or setting up a fallback path

While you're at it, duplicate this DNS entry to add a new subdomain that mobile application will use (something like ham.myhome.com. A yourServerIP, notice the additional m for mobile in the subdomain name) In your NGINX configuration, the ham.myhome.com site configuration will looks a bit like this:

server {
    server_name  ham.myhome.com;

    # Home assistant
    location /
    {
        proxy_pass http://homeassistantserverip:8123;
        proxy_set_header   Host             $host;
        proxy_set_header   Upgrade          $http_upgrade;
        proxy_set_header   Connection       $connection_upgrade;
        proxy_http_version 1.1;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_buffering    off;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/ham.myhome.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/ham.myhome.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = ham.myhome.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen       80;
    server_name  ham.myhome.com;
    return 404; # managed by Certbot
}

You'll also need to enable the site, by linking it via:

$ sudo ln -sf /etc/nginx/sites-available/ham.myhome.com /etc/nginx/sites-enabled/ham.myhome.com

As usual with HTTPS, you might need to use certbot to fetch a valid SSL certificate, via sudo certbot run -d ham.myhome.com --nginx.

Restart nginx (sudo systemctl restart nginx) and check you can access your HA installation by browsing to https://ham.myhome.com. If you are greeted by HA login page, congratulations, you can continue this tutorial. Else, please recheck any steps above until you figure out what went wrong.

This ham domain is the domain that'll be used by the mobile applications. It's not behind SSO Authelia server. It's 100% genuine HA authentication process.

Step 2. Changing HA to allow remote authentication

As usual with SSO (see previous article for explanation), the SSO server acts as a proxy. If a valid session exists, it signals to the protected application that no authentication is required. Else, it redirects by itself to its own login page to create the session.

HA doesn't really deal with external authentication by itself and it's probably a bit too complex to modify and maintain the authentication code to validate external authentication.

Hopefully, half of the work is already done by using an Authentication provider. You'll need to install this one.

The process is a bit convoluted, since it requires setting up the HACS integration first in HA. Don't worry, here's the process:

  1. Determine what HA installation you've done (I recommend using containers, so this tutorial is based on this installation type)
  2. Open a terminal on the computer running HA and type docker exec -it homeassistant bash. Depending on your distribution, you might need to prefix the previous command by sudo
  3. The prompt should have changed. Type wget -O - https://get.hacs.xyz | bash - to install HACS on your HA installation
  4. Then follow the instructions on this page to install the integration in HA. An integration, in HA speak, is a software that's hooking into HA's system.
  5. Restart HA (click Settings and the hamburger menu on the top right and then Restart Home Assistant)
  6. Once HACS is installed and working (you should have a new icon on the left column) like this: HACS
  7. Click on it and on Integrations. Then click on the top right hamburger menu and select Custom Repository.
  8. A dialog will pop up asking for a repository URL. Enter https://github.com/BeryJu/hass-auth-header and select Integration in the category field then click Add.
  9. This should have added the Header Authentication in the list above. Since a large number of integration is listed, you can search for Header in the search field and click Header Authentication card that shows up.
  10. Once its active, restart HA (see above). Until it's restarted, the configuration won't accept the new authentication directive.
  11. Once HA has restarted, open your configuration.yml (either by using the Home assistant's File Editor, either by entering the container and edition the /config/configuration.yml directly) and change the section that reads:
http:
    use_x_forwarded_for: true
    trusted_proxies:
        - 1.2.3.4/32 # This needs to be set to the IP of your reverse proxy
logger:
    default: info

to

http:
    use_x_forwarded_for: true
    trusted_proxies:
        - 1.2.3.4/32 # This needs to be set to the IP of your reverse proxy
auth_header:
    # Optionally set this if you're not using authentik proxy or oauth2_proxy
    username_header: Remote-User
    # Optionally enable debug mode to see the headers Home-Assistant gets
    # debug: false
# Optionally, if something is not working right, add this block below to get more information
logger:
    default: info
    logs:
        custom_components.auth_header: debug

Change the IP address to fit your setup, the IP address should be the IP address of the NGINX server, and save the file.

Then, click on the Development tools on the left bar and click Verify the configuration. It should return a green check. If it doesn't re-edit your configuration to fix the reported error. Once it's valid, restart HA once again.

Step 3. Update the NGINX configuration to proxy authentication

Then you'll need to update your site configuration for ha.myhome.com. Basically, it means adding 2 lines in the file, so it looks like this:

server {
    server_name  ha.myhome.com;

    # Add this line
    include snippets/authelia.conf;

    # Home assistant
    location /
    {
        proxy_pass http://homeassistantserverip:8123;
        proxy_set_header   Host             $host;
        proxy_set_header   Upgrade          $http_upgrade;
        proxy_set_header   Connection       $connection_upgrade;
        proxy_http_version 1.1;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_buffering    off;

        # And this line
        include snippets/auth.conf;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/ha.myhome.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/ha.myhome.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = ha.myhome.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen       80;
    server_name  ha.myhome.com;
    return 404; # managed by Certbot
}

Restart NGINX via sudo systemctl restart nginx, clear your browser cache and cookie (but don't connect to https://ha.myhome.com yet)

Step 4. Update Authelia configuration to accept Home assistant's domain and forward the required headers

In your Authelia configuration file (likely /etc/authelia/configuration.yml) make sure you've listed ha.myhome.com in your access_control/rules/domain list. It should look like this (this is only an extract of the whole configuration):

access_control:     
  default_policy: deny    
  rules:
    - domain:
        - 'auth.myhome.com'
      policy: bypass
    - domain:
        - 'myapp.myhome.com'
        - 'ha.myhome.com'
      policy: one_factor  

Make sure your HA's user account has the same name as Authelia's username.

Restart Authelia with sudo systemctl restart authelia if you have made any change to the configuration file

Finally, browse to https://ha.myhome.com and you'd be greeted with Authelia login page, not Home assistant page. In the login process, the login page should never appear completely (only the HA's icon).

Congratulations, you did it!

Final remarks

When/If using the mobile application, use ham.myhome.com instead of ha.myhome.com for your server's URL. That way, the usual HA's login is used.

You can still browse to ha.myhome.com on your mobile's web browser to benefit from SSO. But the mobile application is using a Webview with limited support for this redirection dance and cookie session sharing, so it doesn't work.

Previous Post