Cloudflare Access and the Android App

For my externally accessible services, I use Cloudflare Access and Nginx. Cloudflare Access basically adds an additional authorization layer before any requests make it to Nginx. In my case, I use Google verification.

More info here: LINK

Problem is, the Home Assistant app doesn’t like this since it won’t show the Cloudflare Access login page in the login process. Coudflare does have the ability to use a service token to get around the login page, however. Info HERE.

Anyone know of a way to make this work in the Android app?

Thanks.

3 Likes

I am also facing the same issue.

When I open the Homeassistant app on my phone it automatically opens the Chrome app and allows me to authenticate against Cloudflare Access then correctly redirects me to my Homeassistant within the browser window though, if I open the app again the cycle will repeat.

Has anyone figured out how to make this work?

I was told in another thread or GitHub maybe a long time ago that there are no plans to add support for any kind of authorization tokens in the app that would make this work. I’ve moved to just using NabuCasa.

Disable access, login on home assistant and enable access again. Works on iOS app

2 Likes

What do you mean by “disable access”? Sorry, didn’t get it.

Disable “Cloudflare Access”, so you can setup your app. Once the app works, enable “Cloudflare Access” again.

Seems not work on Android. Currently my HA instance is accessible on public internet without any additional authorization layer then the HA internal (with two factor).

The companion app is already setup, but once I’ve enabled the application on Cloudflare Zero Trust, the app is not working anymore (HA could not be reached) followed by the authentication loop in Chrome.

Even if you got this working you would have to carve out a bypass exception for the entire HA API. It’s not possible to get HA entirely behind access because the app has to be able to talk to the API without requiring any user interaction to do things like report zone/location changes, changes in phone settings, etc.

If cloudflares auth token had expired (which is does once every 30 days if you give it max lifetime) then these API calls would simply fail. An API call cannot require user interaction so an auth screen is failure.

I tried to set this up at once point but gave up. I kept running into challenges and realized I was going to have to carve out this gaping exception so it made it kind of pointless. Since the API can do everything the UI can do and more after all.

With GitHub Access method in Cloudflare, it works, but only when setting up the companion app first time.
The problem is that, after a month, you have to delete all app data and reconfigure angain the app so in the initial setting up process you are showed the login page.

Other solution I have tried is a bypass policy with warp 1.1.1.1 and zero trust teams, so devices connected via zero trust 1.1.1.1 team can access directly without any login in GitHub or Google.
Problem with this solution is that 1.1.1.1 does not work perfectly, and my mobile phone lost internet connection some times, and I had to turn off and on 1.1.1.1

Anyway, the first solution suggests that the companion app has the ability to show the login cloudflare page, as it does at the initial set up process.
It would be great if they enable it always, or in some configuration option.
Other solution would be the possibility of making a backup of the companion app configuration, so when once a month we have to delete app data, we could restore previous configuration easily.

I think I “solved” this issue locally, however it required code change in android companion app. It looks that:
io.homeassistant.companion.android.webview.WebViewActivity
uses TLSWebViewClient as webViewClient. This TLSWebViewClient is preconfigured there and there are overrides for several standard methods from WebViewClient. Method “shouldOverrideUrlLoading” is root cause of our problem here.
It implements following condition:

} else if (!webView.url.toString().contains(it.toString())) {
                                Log.d(TAG, "Launching browser")
                                val browserIntent = Intent(Intent.ACTION_VIEW, it)
                                startActivity(browserIntent)
                                return true;
                            }

When CF authorization happens, this condition is matched and web browser is oppened.
If this condition is commented webbrowser is not started and we can successfully accomplish CF authentication.

Well done on finding this!

Also battling with this… Taken me a while to get my head around all the networking… Running CloudFlared in Docker and everything is now working except for this issue. If I use ha in browser that works just not in companion app. Any chance of this fix making its way into an app update anytime soon?

1 Like

I have noticed something else here, when the app launches the browser and it gets stuck in its endless “unable to connect” loop… The URL is:
https://ha.xxx.xxx/lovelace?external_auth=1
If you delete the external_auth=1 then obviously it loads with no issue… Not sure if this is at all useful but hoping for a fix…

Well the CloudFlared add on seems to work but it’s the same I guess as having no access control from CloudFlare side… Not ideal but still better than port forwarding an unencrypted connection

I can confirm the behavior and I’m also interested to get a working solution.

Authorization just works on the first companion (Android) setup but after the authorization expires you won’t be able to authorize again. The only workaround is to delete the app data.

Another solution would be use service tokens.:
Link

I would prefer the service token but both solutions should work in my opinion.

Another workaround is the WARP App.:
Link
(I hope it is ok to Link external, maybe someone is interested in the workaround…)

1 Like