Open Home Assistant from anywhere without opening anything
Home Assistant has joined your tailnet. That is not yet a web address you can type on your phone from a train. This article turns it into one — a private HTTPS URL that only devices logged in to the same tailnet can open — and then covers the other half of daily use: treating every phone and laptop in that tailnet as an asset you name, audit and switch off when it leaves.
A habit worth building before a URL worth typing
The workflow this guide asks you to adopt is two moves, always in the same order. On the phone or laptop you are holding, open Tailscale and confirm it is logged in to the right tailnet. Only then open Home Assistant.
That order keeps the point of failure obvious. If Tailscale says it is connected and Home Assistant still will not open, the problem is your Home Assistant account or the address you typed. If Tailscale is not connected, nothing below that matters yet. Reverse the order and every fault looks alike from the outside.
Tailscale builds the road to your house. Home Assistant's login is still the key to the front door. Someone who gets onto the road has not got into the house — and when you cannot get in yourself, it helps to know straight away whether you are stuck on the road or standing at the door with the wrong key.
The benefit of the private route is that a client cannot use it by accident. Every phone or laptop has to become a tailnet device first, deliberately, signed in as a person you recognize. Compare that to the shape of a public entry point:
flowchart LR
subgraph Q["What this guide leaves out"]
direction LR
F["Anyone on the internet"] --> G["A forwarded port
on your router"]
G --> H["Home Assistant login
the only thing left"]
end
subgraph P["What this guide does"]
direction LR
A["Your phone on mobile data"] --> B["Tailscale app, logged in
to your tailnet"]
B --> C["Encrypted link
between two machines"]
C --> D["Home Assistant host
running the Tailscale app"]
D --> E["Home Assistant login
your own account"]
end
Now the edges of this article, so you know what it is not. It does not set up a public reverse proxy or router port forwarding. It does not turn on Funnel, the setting that would make a service reachable from the public internet. Exit nodes and DNS override are out of scope as well — leave all of them off unless you have a specific reason.
Three places to click, and what each one owns
Almost every confused half hour in this topic comes from clicking in the right-looking place at the wrong layer. There are three of them, so learn what each one owns before you need it.
A tailnet is your private Tailscale network. A machine is one device that has joined it. The Home Assistant Tailscale app is the Tailscale service that Supervisor manages, which you open and configure from the Apps page inside Home Assistant.
| Layer | What it handles | How you verify it |
|---|---|---|
| Tailscale admin console | Accounts, Machines, routes and policy | Home Assistant appears in Machines |
| HA Tailscale app | Runs Tailscale on the Home Assistant host | Status healthy, no blocking errors in the log |
| Home Assistant | Login, dashboard and admin rights | You log in normally with a personal account |
Read the right-hand column downward as a checklist. Together, those three lines are what “it works” actually means.
Settings → Apps or the older Settings → Add-ons. The translations vary too. Recognize the Tailscale entry and its Info, Configuration, Log and Web UI tabs, then go by what your screen and the official docs say rather than by the wording printed here.Before you change anything, record where you are starting from. Open Settings → Apps, find Tailscale, note whether it is running, and leave alone every advanced option you are not currently using. That is thirty seconds of work and it is what lets you roll back later.
Joining the tailnet is not yet a browser entry point
This catches people out, so it is worth saying plainly: getting Home Assistant into your Machines list does not give you an address to type. Turning that into something a browser can open is a separate, four-part job.
The tool for it is Serve, the Tailscale feature that publishes a service to your tailnet over HTTPS and to nowhere else. In the Home Assistant Tailscale app it is one Configuration value: share_homeassistant, set to serve.
Serve and Funnel are the same door with two different signs on it. Serve says residents only — the people already inside your tailnet. Funnel takes the sign down and puts the door on a public street. This guide uses Serve, and never the other one.
serve to funnel. Funnel changes how far the service can be reached. It is a public entry point setting, and it is deliberately outside the scope of this guide.The four parts have to be done in order, because each one is a prerequisite for the next.
flowchart TD A["Home Assistant is a machine
in your tailnet"] --> B["1 · Trusted proxies
set in configuration.yaml"] B --> C["2 · Tailnet name chosen,
MagicDNS on, HTTPS on"] C --> D["3 · share_homeassistant set to serve
then restart the app"] D --> E["4 · Open the HTTPS URL
from another tailnet device"] E --> F["Log in with your own
Home Assistant account"]
-
Step 1
Set trusted proxies in Home Assistant
Following the app docs, open
configuration.yamland, in itshttp:section, add these two settings:use_x_forwarded_for: truetrusted_proxies:then- 127.0.0.1beneath itIf an
http:section already exists, merge these keys into it. Do not create a second one — a duplicated top-level key is a configuration error, not an override.What the pair does is narrow: it tells Home Assistant that a forwarder on the local address
127.0.0.1is allowed to say where a request really came from. Serve is that local forwarder. Without this, the hand-off is not trusted and the page does not load. -
Step 2
Turn on MagicDNS and HTTPS for the tailnet
Go to the DNS settings in the Tailscale admin console. Confirm that a tailnet name has been chosen, enable MagicDNS, and enable HTTPS under HTTPS Certificates.
Your tailnet name is yours alone. This guide deliberately prints no example one, so there is nothing here for you to copy by mistake — read your own value off your own admin console.
-
Step 3
Set share_homeassistant to serve, then restart
In the Tailscale app's Configuration tab, save
share_homeassistant: serveand restart the app. Leave Home Assistant itself serving plain local HTTP for now; that part does not change.Once it comes back, get your URL from the app's status or from the docs. It has this shape:
https://<machine>.<tailnet>.ts.netDo not append your old Home Assistant port number to it. The whole point of this step is that Serve is answering on the standard HTTPS port instead.
-
Step 4
Open it from another tailnet device
Take a phone or laptop that is logged in to the same tailnet, open that HTTPS URL, and sign in with your personal Home Assistant account.
Note the time and which device you used. That single line makes a future problem far easier to place than remembering that it worked once.
The Machines page is an asset list, not a status screen
Once remote access works, the second half of daily use begins: knowing what is on your tailnet. The Machines page in the Tailscale admin console is where Home Assistant, phones, laptops and long-forgotten devices all appear together. It is an inventory you maintain, not a dashboard you glance at.
Three details are worth checking for each machine: its name, its last-seen status, and its feature badges. And one rule about names — a name should make the purpose obvious and give nothing else away.
ha-livingroom — anyone maintaining this can tell what it is at a glance.ha-home — purpose only. Short, and it survives a house move.Checking those details is a step of its own, and it is the same step at the end of every article in this series. Open the Machines page in the Tailscale admin console and confirm the machine that corresponds to Home Assistant, its last-seen status and its feature badges. Three things, one page, less than a minute.
| What to look at | What it tells you | Why it is worth the look |
|---|---|---|
| The machine that corresponds to Home Assistant | That the entry in this list really is your Home Assistant host, and not another device you named similarly | Everything else on this page is about the wrong machine if this is wrong |
| Its last-seen status | Whether the console has heard from that machine recently, or is showing you a stale entry | A machine that has not been seen for a while explains a failed connection before you go hunting in Home Assistant |
| Its feature badges | Which Tailscale features the console is showing as active for that machine | This is where a setting you turned on earlier either shows up or quietly does not |
The maintenance itself is a monthly job that takes a few minutes.
-
Step 1
Open Machines with an admin account
Log in to the Tailscale admin console with a Tailscale admin account and go to Machines. Work down the list and identify each entry by its purpose — Home Assistant, which phone, whose laptop.
-
Step 2
Rename anything you had to think about
If identifying an entry took you more than a second, rename it now, using the purpose-only style above. You are not naming it for today; you are naming it for whoever reads this list after you.
-
Step 3
Deal with devices that are no longer in use
When a device is replaced or lost, or a person leaves, disable or remove the matching entry from the Machines list. Do not settle for deleting the Tailscale app from the phone.
-
Step 4
Check key expiry
Following the app docs, check key expiry from the machine's own menu. The official app docs specifically remind you to keep an eye on this. If your maintenance policy allows changing it, let an admin make that call, and record the reason and the date.
Deleting the app from a phone is the leaving employee dropping their pass in a drawer. The pass still opens the door. Removing the machine from the list is you, at the front desk, switching that pass off. Only one of those two actually changes who can get in.
The same judgment, as a decision you can run in seconds whenever a device changes hands:
flowchart TD A["Something changed
about a device"] --> B{"Is it still in use
by the same person?"} B -->|"yes"| C{"Does its name say
what it is for?"} C -->|"yes"| D["Leave it. Check key expiry
and move on"] C -->|"no"| E["Rename to a purpose-only name"] E --> D B -->|"replaced, lost,
or the person left"| F["Disable or remove it
in the Machines list"] F --> G["Record the date,
who did it and why"]
Two access decisions sit alongside this one, and both follow least privilege. Only the people who need to reach Home Assistant should have a path to it. Only the people who need to manage the tailnet should have admin console access. Those are separate grants, and it is normal for the second list to be much shorter than the first.
Two networks, and a note your successor can read
Testing from the sofa proves nothing about remote access. The acceptance test has three parts and is worth doing properly once.
- On your home network. Open Home Assistant over your local LAN and confirm the existing accounts and dashboard were not affected by anything you changed today.
- On a different network. Switch the test phone to mobile data, or another network you trust. Confirm Tailscale is connected, then open Home Assistant once. If your setup involves routes, test only against targets you are authorized to manage.
- Record the result. Success or failure, which device, what time.
Run the security check in the same sitting. Confirm the account logged in to Tailscale is the right one. Confirm Home Assistant is still managed with separate personal accounts rather than a shared admin login. Confirm the Machines list holds no unknown or retired devices.
Then the part everyone skips. The biggest risk with network settings is not a wrong setting — it is a right setting that nobody remembers making.
It is the pencil note inside the fuse box lid. Nothing in it is secret. It just means the next person to open the box is reading rather than guessing, and that the person is often you, eight months later.
Write the date, who did it, the purpose, the state before and after, and the device you verified with. Keep it in your password manager or your site maintenance notes. The record holds the description a maintainer needs to understand the decision — not the secrets themselves, which belong in a controlled secrets manager.
The source guide gives a worked example of the right level of detail: “2026-08-19, the administrator confirmed the Home Assistant machine is still in the designated tailnet; private access tested successfully from a managed laptop on a non-home network.” For a subnet router you would add that only a single approved LAN CIDR is advertised, approved in the admin console. Never write street addresses, customer names, the full Tailscale domain or device identifiers into a public repository.
| Record this | Keep out of public docs | Who needs it next |
|---|---|---|
| Purpose of the change, date, verification result | Credentials, auth keys, login URLs | HA maintainer |
| Each machine's purpose and its owner's role | The full tailnet domain and private IPs | Tailscale admin |
| Which subnet with a clear purpose was approved | Unredacted CIDRs, scan results, street addresses | Network maintainer |
Underneath all of it is one habit: change one thing at a time, test from another network when you are done, then write down the result. That preserves your ability to roll back far better than flipping routes, policy, DNS and public sharing all in one evening and hoping.
Which layer is actually broken
The three layers pay off here. Each common failure lives in exactly one of them, provided you check in order rather than at random.
flowchart TD
A["Something is wrong"] --> B{"Can you find Apps
in Home Assistant?"}
B -->|"no"| C["Check whether your install
is managed by Supervisor"]
B -->|"yes"| D{"Does Home Assistant
appear in Machines?"}
D -->|"no"| E["Finish the login in the app's Web UI,
then read the app log"]
D -->|"yes"| F{"Is the client logged in
to the same tailnet?"}
F -->|"no"| G["Connect the client first.
Nothing below this is the problem yet"]
F -->|"yes"| H["Check the Home Assistant
account and the URL you typed"]
I cannot find Apps in Settings at all
Home Assistant is not in the Machines list
Machines shows Home Assistant, but Home Assistant will not open
A route seems to exist but the LAN is still unreachable
Things got uncertain after a change
Do I need to open a router port?
Does Tailscale replace the Home Assistant login?
Can I set up an exit node or DNS override while I am here?
The two documents this article defers to
Two sources are authoritative here, and it is worth knowing which is which. The Home Assistant Community App: Tailscale docs describe the app itself — its options, its Web UI, share_homeassistant, advertise_routes and userspace networking. Tailscale Docs describe the service the app connects to: the admin console, Machines, routes, access controls and Serve.
Interface text changes with the app and admin console versions. When a name on your screen differs from a name printed here, go by your screen and the official docs first.
- App options, Web UI, share_homeassistant, advertise_routes and userspace networking
- Tailscale: Serve and private tailnet services — the feature behind this article's private HTTPS URL
- Tailscale: Access controls, grants and ACL — how least privilege gets written down
- Tailscale: set up a subnet router and approve routes — the route approval Part 5 covers
Where to go from here
Access works. Now decide who gets it.
Part 4 takes the least-privilege idea from this article and makes it explicit: access controls that say who can reach what, and a closer look at Serve as an HTTPS entry point that stays inside your tailnet.
Open the full guidePart 3 of the Home Assistant Tailscale Remote Access Guide series on the Apporo blog.
Adapted from the Home Assistant Tailscale Remote Access Guide, produced by WoowTech and released under CC BY 4.0. This adaptation is published by Apporo under the same licence.
Light · Air · Water · Control · apporo