How it connects

Why Stratorama never connects to your Home Assistant

Last updated: 13 October 2026

Every connection in Stratorama goes one way: out of your home. Nothing calls in. This page follows a tap on the plan through every hop, says what each hop can see, and points at where you can check it yourself.

Your browser

Wherever you are. A sign-in cookie, no Home Assistant token.

Stratorama relay

Our server. Forwards states in memory only.

Home Assistant app

Ours, inside your Home Assistant. Calls out, opens no port.

Home Assistant

Yours, at home. Reached over the Supervisor's local API.

The four hops. Your browser talks to the relay over HTTPS; our app inside your Home Assistant opens one outbound WebSocket to the relay; the app reaches Home Assistant over the Supervisor's local API. The only connection that leaves your Home Assistant is the app's own, and it is outbound. On Home Assistant Container the third box is the same agent running as a Docker container beside Home Assistant, reaching it over its local API: the same hops, and the same one outbound connection.

Why not the usual way

A floor plan on a wall tablet is easy while the tablet shares a network with Home Assistant. It stops being easy the moment you want the same plan from a phone on a train. The usual answers are to expose Home Assistant to the Internet - a port forward or a reverse proxy, a domain, a certificate, and a long-lived access token on every device that connects - or to subscribe to Home Assistant Cloud. Both work, and both are reasonable choices. We wanted a third one for a product that lives on a tablet in a hallway and in the pockets of the people who live there: nothing about your Home Assistant reachable from outside, and no Home Assistant token in any browser.

Hop by hop

Your browser and the relay

Stratorama is a web page served by our relay at stratorama.app. A person signs it in with an httpOnly session cookie (email and password, or Google, GitHub or Discord); a wall tablet signs in with an httpOnly credential cookie of its own, set once by a one-time code typed on the tablet. It reads your plan over HTTPS and listens for state changes on a server-sent events stream. The browser never learns a Home Assistant address, never holds a Home Assistant token, and never names an entity or a service when it acts: it names an element of your plan and what it wants - on, off, 40 % open. The relay does the rest, which is what the next sections are about.

The Home Assistant app and the relay

The app opens one outbound WebSocket to wss://stratorama.app/agent and keeps it open. Nothing listens on your side: it declares homeassistant_api: true and nothing else - no host network, no ingress, no mapped folder, no port. Pairing is an 8-character code that the home's owner generates in Stratorama; it is valid for ten minutes and for one use, and the app exchanges it once for a credential of its own, kept in its /data folder and presented on every reconnection. The relay pings every 30 seconds; if it goes quiet for 90 seconds the app hangs up and dials again by itself. Disconnecting it from Stratorama revokes that credential at once and the line drops within a second; uninstalling the app deletes the folder, credential included.

The app and Home Assistant

On your side, the app speaks to Home Assistant over the Supervisor's local API with the token the Supervisor hands it at start. That token stays inside the app: it is not sent to us, and there is no field anywhere in Stratorama for a Home Assistant token or address, because we never need one.

Home Assistant Container cannot run apps, so there the same agent runs as a Docker container you start beside Home Assistant. With no Supervisor to hand it a token, it uses one you create for it in Home Assistant, and a user without admin rights is enough. That token stays on your network all the same: the agent presents it to Home Assistant and to nothing else, and it is never sent to us.

Nine calls, and a refusal for everything else

The Home Assistant app relays exactly nine calls to Home Assistant and refuses any other, whoever asks:

  • GET /api/states - the entity snapshot, when a plan loads or the device picker opens
  • light.turn_on, light.turn_off
  • switch.turn_on, switch.turn_off
  • cover.open_cover, cover.close_cover, cover.stop_cover, cover.set_cover_position

The list is a closed list rather than a rule about shapes, and it lives in the app, in your home, not on our server: a bug or a breach on our side cannot become a request your Home Assistant app will run. No history, no logbook, no automations, no configuration, no other domain. The file is short enough to read in a minute: ha-allowlist.ts.

In the other direction it forwards Home Assistant's state_changed events, and since version 1.4.0 only those of the entities on your plan - its devices, their readings, your doors' sensors, your device library - which the relay names after every connection and whenever a binding changes; until it has, the app forwards nothing. Every answer to the entity snapshot is cut to what the relay's request names: the plan's picture to what the person or tablet asking may see, the picker's list to names, kinds and units for what is not on your plan, and one value when an editor asks for it. And since 1.3.0, on every path, only lights, switches, covers and sensors ever leave: people and device trackers, cameras and media players never do. An app that has not been updated yet sends more; the relay drops what is not on your plan the moment it arrives, so none of it reaches a browser.

Home Assistant also puts credentials of its own in some states: a camera holds an access_token, and its picture link carries a ?token= that opens its live stream, without signing in, to anyone who can reach your Home Assistant. One can travel into a state that does leave - a template sensor whose value is that link, for instance - so since version 1.3.0 the app removes them, in the forms Home Assistant writes them (an access token, a link's token, a stream's path), from everything it sends, and the relay removes them again from whatever arrives. Stratorama never needed them. The code: ha-domains.ts and ha-redact.ts.

What the relay checks before it forwards

Every command names an element of the plan, not an entity. The relay resolves the entity behind it, checks that the person or wall tablet asking may operate that element - a household member sees and controls only the floors and devices the owner granted - and only then asks the Home Assistant app. States travel through the same filter: the runtime snapshot is narrowed to what the requester may see, and the live stream hands each browser or tablet only the entities on its side of the grant; the rest are dropped as they arrive. One feed is wider on purpose. When someone with edit access opens the device picker, that browser receives the names, kinds and units of your other lights, switches, covers and sensors, with no value, because the picker's job is to show what is not on the plan yet - and one entity's current value when they press Show value. It goes to that browser and is kept nowhere. The devices of your device library not placed on any floor reach the same people, with their names and states, for the same reason; everyone else gets only the names of the devices they can see.

Switching a device we class as consequential - today, electro-valves, because water starts running - leaves an entry saying who, which device and when, readable by the home's owner only and deleted after 90 days. A light or a shutter leaves nothing.

What the relay keeps, and what it never has

Kept, on our server

  • Your account: an email address, a password hash or the identity your sign-in provider gives us, and your language.
  • Your floors, rooms, walls, openings and devices, with the Home Assistant entity id each device is bound to.
  • The on or off, level, colour or position you set from the plan for a device that is not linked to Home Assistant.
  • Household members, wall tablets (each with a name, a fingerprint of its credential and when it was last seen) and their grants.
  • The Home Assistant app's credential, until you disconnect it.
  • Consequential action entries, for 90 days.
  • HTTPS access logs - IP address, path, time, and the headers your browser sends, such as its user-agent, preferred language and referring page, never its cookies - for up to 12 months, as French law allows. The Home Assistant app's connection appears there with your home's public IP, like any other request.
  • Nightly backups of that database, encrypted before they leave the server, with a copy at Scaleway in Paris.

Never on our server

  • The states Home Assistant sends. They cross in memory and are gone: nothing is written to disk, nothing is cached to show later.
  • Your Home Assistant address, tokens or credentials.
  • Your history, logbook, automations, configuration or users.
  • Any entity you did not bind, beyond the moment it crosses the wire. Asking for its value in the device picker leaves only its id, in the access log, as part of a path.

The privacy policy is the complete statement: every processor, every legal basis, every retention period.

When something is down

If your Internet connection drops, Stratorama drops with it, even from the sofa: the browser always goes through the relay, and that is the price of never opening a port. Home Assistant, your automations and your devices carry on as if nothing had happened, and the Home Assistant app reconnects on its own when the line is back. If our relay is down, Stratorama is down too, and nothing pretends otherwise: the relay caches no Home Assistant state, so there is nothing stale it could serve you. The status page shows what we see.

The honest part

The relay is a single point of trust. Whoever controls it can send those nine calls to any paired home, and sees the entity ids and states crossing it - since version 1.3.0 of the app, those of lights, switches, covers and sensors only, even when it asks for the snapshot itself, because the app filters its own answers. From version 1.4.0, which of those it receives is the relay's to say: the app forwards the entities the relay names as being on your plan, so the promise that nothing else crosses is ours, while the four kinds (lights, switches, covers and sensors) have been the app's own rule since 1.3.0. We are that party, and this is the trade we are asking you to make instead of a token on every device or a port on your router. What bounds the damage a compromised relay could do sits on your side, in code you can read: the agent refuses anything outside the nine calls, a pairing is revoked from Stratorama in one click and drops within a second, uninstalling the app (or deleting the Docker container's volume) deletes its credential, and every consequential action is on a record the owner can read. The relay is one server at OVH in Gravelines, France, with its database beside it. And on Home Assistant Container you keep one more secret than on Home Assistant OS: the access token you created for the agent, which sits in your compose file.

Check it yourself

  • The Home Assistant app is open source under the MIT licence: the repository, the allow-list and the manifest with its one permission.
  • Your home leaves with you: Account > Your data > Export as JSON gives you the whole plan as one file, at any time.
  • The plan on the landing page is the real app running on a synthetic house, no account needed.

If a sentence on this page is not backed by the code, write to contact@stratorama.app. We would rather correct the page than defend it.