Cannot get credentials for non-HA Thread networks that are not marked as the 'preferred' network in user's iCloud Keychain
Home Assistant Core Version 2025.9.4
Describe the bug
When the user taps send credentials to Home Assistant on the Thread configuration page, the app calls retrieveAllCredentials(), which makes two calls to the ThreadNetwork library:
- Gets the credentials for the user's preferred Thread network by calling (THClient).preferredCredentials().
- Gets credentials for all other Thread networks by calling (THClient).allCredentials().
Unfortunately, this does not retrieve all credentials as the name suggests. While one would think that calling allCredentials() would return all credentials, the documentation for the method says:
When calling this method, you receive credentials for your team ID only.
In other words, it's only getting credentials for Thread networks that were originally created and stored by the app (or by any other app by the same developer). If the user has a Thread network outside of Home Assistant that they'd like the credentials for, and that network is not marked as the preferred Thread network in their iCloud keychain, Home Assistant iOS will not be able to get those credentials.
Suggested Solutions
Change (THClient).allCredentials() to (THClient).allActiveCredentials(). This bumps the minimum iOS version for functions used in that file from 15.0 to 16.4. I'm not sure if that's a problem or not. I believe the credentials returned by allActiveCredentials() will include the credentials for the preferred network, so the call to preferredCredentials() becomes redundant and should be removed to avoid prompting the user for access to thread credentials twice in a row.
Additionally, you could allow users to get credentials on a network-by-network basis using (THClient).credentials(forBorderAgentID) or (THClient).credentials(forExtendedPANID).
I was able to validate the issue and test my theory on the root cause by signing up for an Apple Developer account and building / running a modified version of the app that would request credentials specifically for the PAN ID of the Thread network I was missing credentials for:
+ let bytes: [UInt8] = [0xf3, 0x48, 0xb6, 0x10, 0xed, 0x8b, 0x45, 0x0c]
+ let panID: Data = Data(bytes)
+
// Thre preferred credential call is necessary as it triggers a permission dialog
- let preferredCredential = try await client.preferredCredentials()
+ let preferredCredential = try await client.credentials(forExtendedPANID: panID)
To Reproduce
- Store Thread network credentials using an app that isn't Home Assistant for iOS. Make sure that network is not marked as preferred.
- Open Home Assistant iOS, go to the Settings -> Companion App -> Debug -> Thread, and allow it to retrieve thread network credentials.
- The credentials created in step 1 will not be included in the output.
Expected behavior
Tapping on send credentials to Home Assistant sends all credentials to Home Assistant.
Screenshots
Here is a screenshot of my Thread configuration page, showing two Thread networks:
- MyHome1307316849 is the network of an old Apple Home device that I upgraded away from and no longer own. Unbeknownst to me, It happens to be set as my 'preferred' Thread network in my iCloud Keychain. After searching extensively and even resetting my Apple Home, this unused network remains my preferred Thread network.
- MyHome672859431 is the name of the actual running network, the one I'm trying to get credentials for.
Reading your report, it looks like a bug that should be reported to Apple no?
Have you validated this as well?
Change (THClient).allCredentials() to (THClient).allActiveCredentials()
@bgoncal My understanding based on reading the documentation is that allCredentials() is working as intended by Apple. It is definitely poorly named though.
No I have not tested allActiveCredentials() but I can do so if you'd like.
It would help me a lot if you could validate so, thanks in advance.
But something that I disagree with you (if I understood correctly) is that, the current implementation CAN fetch the credentials from apple home thread network (from your homepods etc), what I am not certain is regarding third parties, like Aqara, that I think doesnt work on the current implementation.