mTLS Certificates for Companion App Mutual Auth
Issue client certificates per installation so the Companion App's native sessions (location + sensors, live entity states, Watch/CarPlay, Assist, token refresh) connect directly to Home Assistant without an auth proxy in the path.
Summary
Today, remote access to a customer’s Home Assistant installation is fronted by an auth proxy (Pangolin) that challenges requests with a shared password before they reach Home Assistant. An auth proxy can protect the browser UI and nothing else: every native feature of the Companion App that relies on a persistent, device-bound session breaks behind it, including Location + sensors, live entity states, Watch/CarPlay, Assist, and token refresh.
Today this is exposed to the customer as a choice between two password modes (see Choose Your Protection Mode ):
- Password, web and mobile app excludes the app’s paths from the proxy, so every native feature works, at the cost of leaving the whole Home Assistant API reachable at the remote access URL, guarded only by Home Assistant’s own access tokens and, on the webhook path, a secret per-device URL.
- Password, web only keeps everything behind the proxy, at the cost of the app’s background features: location tracking, sensor updates, live entity states, and Watch/CarPlay.
Neither mode is what the customer actually wants, which is both.
mTLS is the supported alternative. With mutual TLS, the Companion App presents a client certificate that is threaded through every native session, so the device authenticates at the TLS layer with its own per-installation identity — no proxy impersonating the app, no credentials injected mid-stream.
Why the Auth Proxy Falls Short
- The proxy gates requests behind a browser-style password challenge. Anything that needs a long-lived, device-bound session (WebSockets, sensor streams, token refresh) never gets past the challenge, because a native session has no browser to answer it.
- Companion App features tied to the device identity (Location + sensors, Watch/CarPlay integrations, Assist voice, live entity state streams) have no way to establish themselves through the proxy.
- The only available workaround is a path exclusion per broken feature, which trades the proxy’s protection for a wider exposed surface rather than authenticating the device. Making that trade a customer-facing setting makes it visible; it does not make it go away.
mTLS collapses the choice: instead of trading app features against an exposed API surface, the client certificate is the identity, validated by the transport layer on every connection and session. Native features keep working and nothing is left open.
How It Works
- Selora operates a certificate authority (CA) that signs client certificates scoped to a customer’s installation.
- When the Companion App is paired with an installation, the app registers the device and is issued a client certificate (with private key), stored in the device’s secure storage.
- For every remote connection, the app presents the client certificate over the existing secure remote-access channel.
- The edge of the customer’s installation validates the certificate against the Selora CA and maps it to the customer’s account and permissions.
- All native sessions — location + sensors, live entity states, Watch/CarPlay, Assist, token refresh — run with the certificate threaded through, so sessions stay live and the device stays authenticated.
- Certificates have a lifecycle: renewal, rotation, and revocation on device change, app uninstall, or support action.
Components
- Client certificate issuance (Selora CA) — signing per installation/device, with a scoped identity and defined validity.
- Companion App integration — certificate provisioning during pairing, secure storage, presenting the certificate on connections, and handling renewal and revocation.
- Remote-access edge termination — mTLS verification and client-certificate → customer mapping, with the auth proxy out of the native path.
- Certificate lifecycle management — issuance, renewal, rotation, revocation (device change, uninstall, support actions).
- Transition / fallback — the browser UI continues to be protected by the existing auth proxy; mTLS is additive, not a replacement for the browser path.
What Belongs in the Roadmap
- Define the certificate model: what a client certificate identifies (installation, device, app), its permission scope, and its lifetime.
- Design the issuance and provisioning flow into Companion App onboarding/pairing.
- Implement mTLS verification on the remote-access channel and map client certificates to Selora accounts and permissions.
- Verify the previously-broken Companion App features over mTLS: Location + sensors, live entity states, Watch/CarPlay, Assist, token refresh.
- Certificate lifecycle: rotation, renewal, and revocation workflows with defined cut-over windows.
- Plan the transition: what stays on the Pangolin proxy (browser UI), what moves to mTLS, and the rollout order per customer.
Out of Scope
- Removing the auth proxy for the browser UI — the proxy continues to protect the browser experience.
- Local (same-network) connections — those are already direct and authenticated.
- Authentication for third-party integrations or other client apps (separate roadmap items if needed).
Success Criteria
- A paired Companion App can obtain a client certificate and open a direct mTLS session to the customer’s Home Assistant installation.
- All affected Companion App features work over mTLS without the proxy in the path: Location + sensors, live entity states, Watch/CarPlay, Assist, token refresh.
- Revoking a certificate stops access within a defined window; certificate rotation works without the customer re-pairing.
- The browser UI continues to work exactly as before via the existing proxy, during and after the rollout.
- Customers no longer have to choose between Companion App features and a fully closed surface: the Password, web and mobile app exclusions are no longer needed.
References
Related Epics
Last modified August 28, 2026: Add Bluesound and NAD device catalog (6a9f8ee)