The Hayward Omnilogic cloud server is in the process of being upgraded to utilize unique API keys for each home automation platform. The key is to be kept confidential. Is there an existing method to encrypt this information such that it is not discernable in the open source code?
There was some work on a PR to implement secrets handling in OH but it stalled and I’ve not seen any updates to it for some time. I do know that similar add-ons that require some authorization we leave it up to the users to go and obtain their own API keys (e.g. Nest, Residio, OpenWeatherMap, etc.). I don’t know if that’s feasible here though.
Honestly, I don’t understand why they would do this except to exclude open-source software. The API key should identify the user, not the software. Also, even if this secrets stuff was implemented, wouldn’t it be trivial to just decompile the JAR and get the API key that way?
If the API key is stored in the binding, that would be trivial, yes. Unless some form of obfuscation can be used (e.g., splitting the key in several parts and scrambling them across the code). But there still needs to be an algorithm that can piece them together, which can be analyzed, so it’s just a hurdle. And apart from that, maintainability gets worse, since issuing a new key will require an update to the binding. The same is of course true for all integrations with the API (including commercial for that matter).
From what I remember about the secrets handling, the discussion derailed into a debate about whether secrets should be encrypted in memory, and the feasibility/impossibilty of implementing that.
It doesn’t matter if it’s stored in the binding or another part of OH. It’s a “logical dilemma”, you can come up with all the complicated schemes in the world to hide it, but you must provide a way to unpack everything, or it won’t work.
Obfuscation isn’t really security, but it’s still used quite a bit because there are no better options. But, compared to proprietary solutions, OH has some extra “challenges”: Java is exceptionally easy to decompile, and people might not even need to decompile it to read it - they might find it in the bytecode. More crucially, you can’t hide your “deobfuscation”, because it’s all open source. So, nobody will have to figure out how to put it back together, then can just read the source code and get the exact recipe.
I haven’t studied all the arguments that have been made here, and might not know all the details, but I’d say that I can’t see a problem with having the secrets encrypted in memory. However, it won’t really help either, because you have to store the encryption key somewhere to decrypt it, and that encryption key is as available to “everybody else” as it is to OH.
In the end, I believe that all attempts to hide a key from the computer it’s running on (and those controlling it) is futile unless you use some kind of hardware device. And that isn’t feasible for something like this.
But, if “services” continue to make such requirements and people still want to use them, I guess some solution should be found. Since it’s impossible to do this “safely”, I would rather focus on what is needed to satisfy their requirements, so that the services can be used, and just ignore the fact that the key can easily be extracted.
Which means that any other software could “impersonate” OH, but if that’s what it takes to use the “service”, in the end that’s only an issue for the service provider, at least in theory. What they want to achieve doing things like this is probably to be able to ban or throttle specific software, based on “load” on their service, and potentially to charge for the use.
A “rouge software” using OHs “secret” key could thus potentially cause trouble also for OH users.
I wouldn’t say that necessarily. There are probably enough users out there running on a machine with a TPM and for those users secrets could be put into it. But that definitely would split the user base to those who have a TPM and those who do not and most users do not (AFAIK there’s no TPM on an RPi). There are at least two FOSS Java TPM libraries I’m aware of.
I’m saddened that this “encrypted in RAM” issue derailed the work because just making it encrypted on disk would be a huge improvement. Many bindings have secret keys, usernames and passwords, API keys, and other secret stuff in plain text in the Thing configs. This is a case where a something is better than nothing at all.
But that doesn’t help OP really. If individual users can’t obtain their own keys, it might simply be the case that this is not a feasible integration for an opensource project like OH. However, do not necessarily be put off by the wording in the API docs and agreements and such. Almost all of these APIs use terms and verbiage that make it seem like you’d be establishing a key for all of openHAB. But it’s perfectly possible for individuals to register for their own API key too. And in that case you can provide instructions for how to register for the key in the docs and just let the user enter their API key in the Bridge Thing’s config. No need to store a secret in github at all. That’s why bindings like Nest have so many steps to set them up.
The implementation for the “secret” handling in the yaml enhancement was simply so I could separate the secrets in a separate file, which can then be added to .gitignore, and it was originally just meant to be used within the yaml configuration file, just like how it’s done in esphome. But in the end I removed it because of the bigger scale secret management idea.
Any TPM use would have to be optional, there would have to be a “non-TPM” solution to achieve the same. Then users could choose what concerns are more important to them.
I always disable the TPM on devices that have it. The reason is simple: I have absolutely no desire for my data to die with some piece of hardware. I don’t want to lose data just because a motherboard dies, and as long as the TPM is enabled, I never know what software might consider that a good idea. Needless to say, I despise Microsoft for their actions with Windows 11.
But, I still can’t see how TPM could be used for protecting an API key that OH would have to make a part of the distributed installation files. Thus, not viable here.
I wonder if there are any TPM/PKCS#11 libraries for Java that can use a TPM if there is one, and otherwise use a (obviously less secure) “virtual” software-based one, where the encryption key is stored in some other way. A file with strict permissions would protect it from some attacks at least.
But as you say, a lot of APIs (e.g., most that use OAuth2) require you to register an “application” to get an API key. But that can often be done by anyone, not seldom using the regular user credentials. The Spotify binding is another example that require this. @matchews can you give some more details on how it’s supposed to work in this case?