Skip to Content

Decide who can reach Home Assistant, then give them a clean address

who gets in
HA Tailscale Guide · Part 4

Decide who can reach Home Assistant, then give them a clean address

By now Home Assistant is in your tailnet and you can open it from somewhere else. Those two things are on or off. This article is about the settings in between: narrowing who is allowed through, and replacing the address-and-port you have been typing with a proper HTTPS name that never leaves the tailnet. Neither is hard. Both are easy to get wrong in the direction of too much access.

3 layers
Where an access decision can be made
5 steps
From local HTTP to a private HTTPS name
443
The default port Serve uses, left alone
Three layers

Three layers, and none of them replaces the others

Installing Tailscale is not a reason to assume that everything can now reach everything. When something is blocked — or, more importantly, when something is not blocked and you think it should be — the first useful question is which layer made that decision. There are three, and they are managed in three different places.

In plain terms

Think of an office building. Tailscale membership is the street door: you are either in the building or you are out on the sidewalk. The tailnet policy is the door to a particular floor. Your Home Assistant login is the key to the filing cabinet inside. Getting through the street door tells you nothing about the cabinet, and no amount of network setup will unlock it for you.

That last part is the one people skip. Tailscale manages the network path. Home Assistant should still use personal accounts, strong passwords and appropriate admin rights — Tailscale does not replace the Home Assistant login and was never meant to.

LayerWhat it handlesHow you check it
Tailscale admin consoleAccounts, Machines, routes and policyHome Assistant appears in Machines
The HA Tailscale appRuns Tailscale on the Home Assistant hostStatus healthy, no blocking errors in the log
Home AssistantLogin, dashboard and admin rightsYou log in normally with a personal account

Tell those three apart before you change anything, so that later you do not spend an evening clicking in the wrong place. The app itself lives at Settings → Apps in the Home Assistant menu; if your screen still uses the older name, it will say Add-ons. The interface text and its translations vary by version, so recognize the Tailscale app and its Info, Configuration, Log and Web UI tabs rather than memorizing a menu label.

flowchart TD
  A["A phone on some other network"] --> B{"Is this device signed in
to your tailnet?"} B -->|"no"| X["There is no path at all"] B -->|"yes"| C{"Does the tailnet policy let
this source reach the Home
Assistant machine?"} C -->|"no"| Y["The network path stops here"] C -->|"yes"| D{"Does this person have a
Home Assistant account?"} D -->|"no"| Z["The login page, and it stays there"] D -->|"yes"| E["The dashboard, with whatever rights
that Home Assistant account has"]
Three gates, three ownersTailscale owns the first two gates. Home Assistant owns the third, and it is the only one that knows the difference between an administrator and a family member who just wants the lights.
Least privilege

Least privilege is a list you write before you edit anything

Least privilege means one thing here: give network access to the people and devices that need to use Home Assistant, and to nobody else. Admin rights inside Home Assistant stay where they are, controlled by Home Assistant user accounts.

In plain terms

You ask a neighbor to water the plants while you are away. You hand over the front door key. You do not hand over the whole keyring — the garage, the shed, the filing cabinet, the car. It is not that you distrust them. It is that there is no reason for those keys to leave your hand, and every reason for them not to.

Read before you write. Review the policy that is already in the admin console before you change it. “Allow everything first, tidy it up later” is a bad default even at home — you should be able to say which accounts can reach Home Assistant.

Two syntaxes exist for writing those rules. The Tailscale docs recommend grants as the modern access-control syntax, and ACL is still supported. If you already have working ACL rules, they have not stopped working; if you are writing something new, grants are what the documentation points you at.

The four steps, in order

  1. Step 1

    Take inventory of sources and targets

    On paper, or in a note. Write down who needs to reach Home Assistant, from which device, and which ports or services they actually need. Family members who use the dashboard day to day and the person who administers the tailnet are different roles, even when they are the same person on two different devices.

  2. Step 2

    Read the current rules in Access controls

    Open Access controls in the Tailscale admin console and understand the grants or ACL that are already there. Do not paste in a whole policy you found online. A policy from someone else's network describes someone else's devices.

  3. Step 3

    Grant the minimum that works

    Grant only the necessary sources access to the necessary machines and services, and preserve the meaning of the rules that were already there. The list from step 1 is what tells you where the edges are.

  4. Step 4

    Test with a non-admin account

    Verify Home Assistant from a test device that should have access, and confirm that no account which should not have access quietly picked up a wider scope. An admin account passing the test proves less than you think.

Step 1 sounds like homework you can skip. It is the step that makes the other three short. Written out, an inventory tends to look like this:

You writeMy own laptop — full access, including the admin console. This is the device I do maintenance from.
You writeA family phone — the Home Assistant dashboard only. No admin console, no other machines.
You writeThe old tablet in the kitchen drawer — nobody has used it since spring. It should not be on this list, which means it should not be in Machines either.
flowchart TD
  A["Someone cannot reach
Home Assistant"] --> B{"Should they be
able to?"} B -->|"no"| C["Leave the policy alone.
It is working"] B -->|"yes"| D{"Is their device signed in
to the same tailnet?"} D -->|"no"| E["Fix the device,
not the policy"] D -->|"yes"| F{"Is it the network path or the
Home Assistant login failing?"} F -->|"the HA login"| G["Sort out their Home
Assistant account"] F -->|"the network path"| H["Widen the grant for that one
source and that one target"]
Before you widen anythingMost “I cannot get in” reports are not policy problems. Two of the four endings here are fixed somewhere other than the access controls page.

Start small, then expand

Start with the smallest setup that works and grow it deliberately. If all you want is to see your dashboard while you are away, private access over the tailnet is usually easier to control than a public entry point. If you need to reach a LAN subnet, list one subnet with a clear purpose first rather than advertising every network at once.

What you needWhere to startNot yet
View Home Assistant remotelyPrivate access from a device signed in to the tailnetOpen router ports, and public sharing you do not need
Manage devicesThe Machines list, with personal accountsA shared admin login everyone knows
Reach your home LANA single approved subnet routeAdvertising several subnets before taking inventory
Serve, not Funnel

Serve keeps it inside. Funnel does not.

Serve and Funnel look like two settings on the same switch. They are not the same risk. Tailscale Serve makes a local service available to the devices inside your tailnet. Funnel makes it available to the wider internet. The official docs draw a clear line between them, and this guide deals only with Serve.

In plain terms

Serve is an internal extension number. Anyone already inside the building can dial it; nobody outside can dial it at all, because the number does not exist out there. Funnel prints that same number in the public directory. Same phone, same desk — a completely different set of people who can make it ring.

flowchart LR
  subgraph F["Funnel, which is out of scope here"]
    direction LR
    F1["Any device on the public
internet, with no Tailscale
installed on it"] --> F2["Tailscale relays
it inward"] --> F3["Home Assistant"] end subgraph S["Serve, which is what this article sets up"] direction LR S1["A device signed in
to your tailnet"] --> S2["An HTTPS name that only
exists on the tailnet"] --> S3["Home Assistant"] end
The same service, two audiencesThe difference is entirely on the left. Serve requires the visitor to already be a member of your tailnet; Funnel does not require them to have Tailscale at all.

Both behaviors are reached through one option in the Home Assistant app, share_homeassistant, which is disabled by default. That default is a good one. Leaving it alone is a valid choice, and if the address-and-port you already use is working for you, you can stop reading here and skip to Part 5.

Do not switch it to the public mode until you understand the reverse proxy in front of Home Assistant and Home Assistant's own HTTP settings. Funnel lets internet devices that do not have Tailscale installed reach the service. That is not what this guide sets up, and it is not something to enable by accident while experimenting.
Turning Serve on

Five steps to an HTTPS address that stays private

What you get at the end is a URL you can type on any device in your tailnet, with no port number on the end and no certificate warning. What you change to get there touches three different places: a Home Assistant configuration file, the Tailscale admin console, and the app's own options. Do them in this order.

In plain terms

Step 2 below is the one that looks like magic. Once Serve is in front, every request reaches Home Assistant from the machine itself rather than from the phone that sent it — the way all post in an office arrives from the mailroom, with the mailroom's own address on the envelope. Those two settings tell Home Assistant that the mailroom is trustworthy, so it should read the forwarding label instead of the envelope.

Record the current state first. Before step 1, go to Settings → Apps in the Home Assistant menu, find Tailscale, and note whether it is running. One line in a note is enough. That line is what you compare against if something stops working later, and it is the difference between rolling a change back and guessing at what the change was.
And for now, do not change any advanced options you are not using. share_homeassistant does not sit alone on the Configuration tab. It has neighbors — options this article says nothing about, which are set the way they are for a reason. Change the one the step names, and leave the rest exactly where you found them.
  1. Step 1

    Leave Home Assistant on local HTTP

    The official app docs assume Home Assistant is reachable over HTTP. If you already run another HTTPS reverse proxy in front of it, do not stack the two setups on top of each other — assess your situation against the docs before going further. This step is often nothing at all: a default installation is already where it needs to be.

  2. Step 2

    Set up trusted proxies, then restart Home Assistant

    In configuration.yaml, inside the existing http: section or a new one, set both of the values below. Save the file, then restart Home Assistant.

    use_x_forwarded_for: true
    trusted_proxies: - 127.0.0.1

    The address 127.0.0.1 is the machine talking to itself — it is the same on every computer, so this is not a value you need to look up or change.

  3. Step 3

    Enable HTTPS in the Tailscale admin console

    Go to the DNS settings in the admin console, choose a tailnet name, enable MagicDNS, and then choose Enable HTTPS under HTTPS Certificates. This is the prerequisite for Serve to obtain a certificate — skip it and step 4 has nothing to present to your browser.

  4. Step 4

    Set share_homeassistant to serve, then restart the app

    In the Tailscale app's Configuration tab, set share_homeassistant to serve. Leave share_on_port at its default of 443. Restart the app.

    Do not choose funnel. It is the neighboring value in the same field, which is exactly why it is worth pausing on this step rather than clicking through it.

  5. Step 5

    Open the new URL from another tailnet device

    From a phone or laptop signed in to the same tailnet, open https://<machine>.<tailnet>.ts.net — with no port number on the end, unlike the address you have been using so far. Then log in with your personal Home Assistant account, as usual.

    The two bracketed parts are placeholders. Your own machine name and tailnet name go there; this guide does not print real ones, and neither should you when you ask for help.

flowchart LR
  A["A device signed in
to the tailnet"] -->|"HTTPS on port 443"| B["Serve, running on the
Home Assistant machine"] B -->|"local HTTP,
arriving from 127.0.0.1"| C["Home Assistant, still
on plain HTTP"] C --> D["Your normal Home
Assistant login"]
What the five steps buildServe terminates the HTTPS connection and hands the request onward locally. That local hop is why step 2 exists, and why nothing about Home Assistant's own HTTP setup needs to change.
Change one thing at a time. If step 5 does not work, you want to know which of the four steps before it is responsible. Doing them one at a time, with a restart where the instructions ask for one, is slower for ten minutes and faster for the rest of the evening.
Checking and recording it

The check, the test, and the note you leave behind

Three quick confirmations before you consider this finished. None of them takes more than a minute, and all three are the sort of thing that is obvious now and impossible to reconstruct in six months.

The right Tailscale account

Confirm the account signed in to Tailscale is the one you meant to use. It is easy to authorize a device with whichever account the browser was already holding.

Home Assistant still on personal accounts

Everyone who uses Home Assistant should still have their own account in it. Only the people who need to manage the tailnet should have admin console access.

No strangers in Machines

Open the Machines page in the Tailscale admin console and account for every entry. Unknown devices are the obvious problem; retired ones — the replaced phone, the dead tablet — are the common one.

Complete the Web UI sign-in only on a personal device you trust. Logging in and authorizing the device is not a temporary act. It puts that machine into your tailnet and leaves it there until somebody removes it. So do it on your own phone or your own laptop — not on a shared family computer, not on a borrowed machine, not on a work laptop you do not administer. There is no “just this once” version of authorizing a device.

Cross-check the Home Assistant machine in the admin console

Open the Machines page in the Tailscale admin console and confirm the machine that corresponds to Home Assistant. Finding its name in the list is the easy half. Two other things on that row tell you more:

What to readWhat it tells youWhen it looks wrong
Its last-seen statusWhether the machine is connected right now, or was last connected at some point in the pastA stale last-seen means the machine stopped talking to the tailnet. Read the app log before you change any setting.
Its feature badgesWhat this machine is doing for the tailnet beyond simply being a member of itA badge you were not expecting means something is switched on that you did not switch on. Find out what before you carry on.
Do not copy the names or IPs in the screenshots as your own values. Anything this guide shows you in a screenshot or an example belongs to somebody else's tailnet, and in most of the screenshots the real values are masked out anyway. Read the shape of the screen from them — where the machine name sits, where the status sits — and then use the values your own screen gives you.
What not to publish. Do not post login URLs, auth keys, your tailnet domain, full IP addresses, device serial numbers or raw logs in issues, group chats or screenshots. This applies when you are asking for help, which is exactly when the temptation to paste everything is strongest.

Test it on two networks

One test proves less than two, because a device at home may be reaching Home Assistant over your LAN without Tailscale being involved at all.

  • On your home network: open Home Assistant on the local LAN and confirm that your existing accounts and dashboard were not affected by the changes in this article.
  • On a different network: switch a test phone to mobile data or another secure network, confirm Tailscale is connected, then open Home Assistant once. If you are testing routes, test only targets you are authorized to manage.
  • Record the result: success or failure, the device you used, and the time. That is far easier to work from later than remembering that “it used to work”.
  • Stop at the security boundary: this guide does not cover exit nodes, DNS override or public Funnel setup. Leave them disabled unless you have a specific need for them.

Leave a handover-ready record

The biggest risk with network settings is not that they break. It is that they worked at the time and nobody remembers why. When you finish, write down the date, who did it, the purpose, the state before and after, and the device you verified with — in your password manager or your site maintenance notes.

That record is not a place to store passwords, auth keys or full private subnets. Those belong in a controlled secrets manager. The note holds only the description the next maintainer needs in order to understand the decision. A real one reads like this: “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, add that only a single approved LAN CIDR is advertised and approved in the admin console.

Record thisKeep out of public docsWho needs it next
Purpose of the change, date, verification resultCredentials, auth keys, login URLsThe Home Assistant maintainer
Each machine's purpose and its owner's roleThe full tailnet domain and private IPsThe Tailscale admin
Which subnet, with a clear purpose, was approvedUnredacted CIDRs, scan results, street addressesThe network maintainer

Never write street addresses, customer names, the full Tailscale domain or device identifiers into a public repository. The record is what lets you judge which layer to roll back when a phone is lost, a router is replaced, the app is updated, or admin rights are handed to someone else.

The minimal-change principle: change one thing, test from another network, write down the result. That preserves reversibility far better than flipping routes, policy, DNS and public sharing all in the same sitting.
When something is blocked

Check these first, then the questions people ask

I cannot find Apps in the Settings menu
Confirm whether your Home Assistant install is managed by Supervisor. A Container or Core installation cannot follow the app path this guide uses, because the Apps page it relies on is not there.
Home Assistant is not in the Machines list
Go back to the app's Web UI and complete the login, then read the app log. Reinstalling repeatedly is the common reflex here and it rarely helps — the log usually says what is wrong on the first read.
Machines shows Home Assistant, but Home Assistant will not open
First confirm the client device is signed in to the same tailnet. Then check the Home Assistant login account and the URL you are using. This is the third gate in the first diagram, and it is the one Tailscale has no opinion about.
The route seems to exist but the LAN is still unreachable
Confirm the route has been approved in route settings on the Machines page. Then test with the correct CIDR, against a target you are authorized to reach. Part 5 covers this properly.
Things got uncertain after a change
Go back to the last known-good state. Keep the logs and the change record, then change one thing at a time from there. Uncertainty compounds much faster than settings do.

Questions that come up every time

Do I need to open a port on my router?
The private tailnet flow in this guide does not require you to set up public port forwarding for Home Assistant. Assess that against your own network and security policy rather than treating it as a universal answer.
Does Tailscale replace the Home Assistant login?
No. Tailscale manages the network path. Home Assistant should still use personal accounts, strong passwords and appropriate admin rights.
My screen says Add-on, not App
The Home Assistant interface and its translations vary by version. Recognize the Tailscale app and its Info, Configuration, Log and Web UI tabs, then go by what your screen and the official docs say.
Can I set up an exit node or DNS override while I am in here?
This guide deliberately leaves out those advanced topics. Finish verifying private Home Assistant access and, later, a single subnet route. Then plan those separately, from the official docs.
Where the facts here come from: this article treats the Home Assistant Community App: Tailscale docs and the Tailscale Docs as authoritative. The two pages behind this article in particular are Access controls, grants and ACL and Serve and private tailnet services. Interface text changes with the app and admin console versions — when a name on your screen differs from a name here, believe your screen and the official docs first.
Next

Where to go from here

keep going

Home Assistant is reachable and scoped. Part 5 widens the door.

A subnet router lets the tailnet see the rest of your home network, not just the machine Tailscale is installed on. It also introduces the approval step that stops a route working until an administrator says so — which is a safety check, not a fault.

Open the full guide

Part 4 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

Open Home Assistant from anywhere without opening anything