Repository navigation
Conversation
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. A caller can send that cookie on REST calls through `urlSession:`, but nothing in HAKit's API reaches the WebSocket handshake, so the proxy rejects the socket with 401 and the connection never comes up. `HAConnectionInfo` now takes an optional `cookieStorage`, and both engines present its cookies for the WebSocket URL on the handshake.
There was a problem hiding this comment.
Hi @RReverser
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
RReverser
marked this pull request as ready for review
September 27, 2026 16:44
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies in a store the native `URLSession`s cannot read, and the webhook session disabled cookies entirely. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing WebKit's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native session reads from there. The app group is needed because the extensions and the background webhook session run in their own processes. The copy is additive: a renewed cookie replaces the old one by name and expired cookies drop out on their own, so nothing tracks what the WebView deleted. A cookie the frontend drops early, on logout for instance, therefore stays usable natively until it expires. Two gaps remain. The WebSocket handshake gets its cookies through home-assistant/HAKit#124, and the app will pass the storage to `HAConnectionInfo` once that ships. The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies in a store the native `URLSession`s cannot read, and the webhook session disabled cookies entirely. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing WebKit's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native session reads from there. The app group is needed because the extensions and the background webhook session run in their own processes. The copy is additive: a renewed cookie replaces the old one by name and expired cookies drop out on their own, so nothing tracks what the WebView deleted. A cookie the frontend drops early, on logout for instance, therefore stays usable natively until it expires. Two gaps remain. The WebSocket handshake gets its cookies through home-assistant/HAKit#124 (independent of this change: the app will pass the storage to `HAConnectionInfo` in a follow-up once that ships). The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing WebKit's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (the extensions and the background webhook session run in their own processes) and every native session reads from there. Two gaps remain. The WebSocket handshake gets its cookies through home-assistant/HAKit#124 (independent of this change: the app will pass the storage to `HAConnectionInfo` in a follow-up once that ships). The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing WebKit's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (the extensions and the background webhook session run in their own processes) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake gets its cookies through home-assistant/HAKit#124 (independent of this change: the app will pass the storage to `HAConnectionInfo` in a follow-up once that ships). 2. The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing WebKit's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (the extensions and the background webhook session run in their own processes) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake gets its cookies through home-assistant/HAKit#124 (independent of this change: the app will pass the storage to `HAConnectionInfo` in a follow-up once that ships). 2. The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing WebKit's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (the extensions and the background webhook session run in their own processes) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake gets its cookies through home-assistant/HAKit#124 (independent of this change: the app will pass the storage to `HAConnectionInfo` in a follow-up once that ships). 2. The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing WebKit's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (the extensions and the background webhook session run in their own processes) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake gets its cookies through home-assistant/HAKit#124 (independent of this change: the app will pass the storage to `HAConnectionInfo` in a follow-up once that ships). 2. The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So such a server only worked in the frontend, and sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (the extensions and the background webhook session run in their own processes) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake gets its cookies through home-assistant/HAKit#124 (independent of this change: the app will pass the storage to `HAConnectionInfo` in a follow-up once that ships). 2. The Watch app has its own app-group container, and no cookies reach it. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. The Android app fixed the same problem in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Home Assistant behind an authentication proxy such as Cloudflare Access works in the app's frontend only. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, which was the remaining outlier out of the three supported platforms (web, Android and iOS). Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Home Assistant behind an authentication proxy such as Cloudflare Access works in the app's frontend only. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Behind an authentication proxy such as Cloudflare Access, the app worked in its frontend only. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
2 of 4 tasks
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets and token refresh all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets, token refresh and even onboarding's own code exchange, right after the WebView login that produced the cookie, all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets, token refresh and even onboarding's own code exchange, right after the WebView login that produced the cookie, all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets, token refresh and even onboarding's own code exchange, right after the WebView login that produced the cookie, all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets, the webhook reachability check in Settings, token refresh and even onboarding's own code exchange, right after the WebView login that produced the cookie, all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets, the webhook reachability check in Settings, token refresh and even onboarding's own code exchange, right after the WebView login that produced the cookie, all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native `URLSession`s cannot read them. So the frontend worked and nothing else did: sensors, location, widgets, the webhook reachability check in Settings, token refresh and even onboarding's own code exchange, right after the WebView login that produced the cookie, all got 401. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native session reads from there. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Only the app's frontend worked behind an authentication proxy such as Cloudflare Access. The Android app had the same problem (home-assistant/android#1708) and fixed it in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change fixes it for iOS as well, the last client where such a setup did not work. Such a proxy gates every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So the frontend worked and nothing else did: sensors, location, widgets, Assist voice replies, camera streams, token refresh and the connection diagnostics all got 401, and so did onboarding's own code exchange right after the WebView login that produced the cookie. iOS offers no way to share WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage (`.shared` is per process, and the extensions and the background webhook session are separate ones) and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 27, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 28, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 28, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 28, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 28, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
RReverser
added a commit
to RReverser/hass-ios
that referenced
this pull request
Sep 28, 2026
Without this fix, the iOS app fails to load anything except frontend behind authentication proxies such as Cloudflare Access. Such auth proxies gate every request on the session cookie issued at login. The frontend gets that cookie through the WebView, but WebKit keeps its cookies where native requests cannot read them. So anything besides the frontend - sensors, location, widgets, Assist voice replies, camera streams, token refresh, connection diagnostics and even onboarding's own code exchange - got the 401 unauthorised error. The Android app had the same problem (home-assistant/android#1708) and fixed it couple of years ago in home-assistant/android#1797 by sharing its WebView's cookie store with its HTTP client. This change implements the analogous fix for iOS as well, the last client where such a setup did not work. iOS offers no way to directly share the WebKit's store, so `WebViewCookieMirror` copies it into an app-group cookie storage and every native request presents it, including media that AVFoundation fetches itself. Two gaps remain: 1. The WebSocket handshake still does not receive cookies. A follow-up will fix that once home-assistant/HAKit#124 has landed. 2. The Watch app never receives cookies either, because it has an app-group container of its own. Android has the same gap, since its jar skips Wear OS.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An authentication proxy in front of Home Assistant, such as Cloudflare Access, gates every request on the session cookie it issued at login. A caller can send that cookie on REST calls through
urlSession:, but nothing in HAKit's API reaches the WebSocket handshake, so the proxy rejects the socket with 401 and the connection never comes up.HAConnectionInfonow takes an optionalcookieStorage, and both engines present its cookies for the WebSocket URL on the handshake.