home-assistant / architecture

Repo to discuss Home Assistant architecture
317 stars 99 forks source link

App Credential Management #139

Closed balloob closed 1 year ago

balloob commented 5 years ago

Note, this issue is not about storing user credentials (we use config entries for this).

This issue is about the app credentials that are used to get credentials for a user. The credentials that identify Home Assistant to an external service. Examples of such credentials are OAuth2 client_id and client_secret. For other apps it could be an app_key.

Right now we've not been allowing app credentials to be entered from config flows. The reason for this is that it's not a user facing credential.

Our current approach is to require integrations to be configured using YAML, and then the config flow behaves normally, ie:

nest:
  client_id: XXX
  client_secret: XXX

In the future I want to provide a Home Assistant set of credentials that we either embed for users or allow users to access. I have a working prototype for Nest in this branch from last summer. This will require a cloud account (but no subscription), because client secret cannot be shared as that would compromise it and open it up for abuse.

However, until this future vision is implemented (so many things to build), I wonder if we should add a UI where people can provide app credentials?

bachya commented 5 years ago

However, until this future vision is implemented (so many things to build), I wonder if we should add a UI where people can provide app credentials?

I think so. The separation makes sense, but without this UI, the UX of having to edit configuration.yaml and create a config entry is slightly friction-y.

frenck commented 5 years ago

Right now we've not been allowing app credentials to be entered from config flows. The reason for this is that it's not a user-facing credential.

That is like the cannabis policy in the Netherlands... you are allowed to sell it, but not to supply it? So supplies (app id&secret) will go via the backdoor (YAML).

Whatever the future might hold, having a user to do both manual configurations for the app and next doing an entry via the config flow, defeats the whole purpose of the config flow IMHO.

From a future standpoint:

In the future I want to provide a Home Assistant set of credentials that we either embed for users or allow users to access.

While cool, easy and super user-friendly, I definitely would reframe from this; When "our" app gets revoked/blocked, "we" will be the one to be blamed.

Secondly, some apps have limits on the use (e.g., rate limiting), which would be hard to provide and still would rely on the user setup.

From a config entry perspective, this could be a 2 step flow:

Any further entries would skip the first step. It could still use YAML (in case the component wants to) and step 1 could be provided by the Cloud in the future as well.

Maybe I'm missing a point here...?

elupus commented 5 years ago

I don't really see the distinction between app credential and user credential. In my example you log in, create a app credential on the vendors home page. This is then linked to your account. It's fully equal in sense to a user password. It's just linked to one application that you as a user might use.

If user passwords are allowed from config flow, why not application passwords?

That said, a secure storage feature of config flow would be good, using the python keyring package for example.

elupus commented 5 years ago

To add, client_id is is created per useraccount too. So it can't be shared.

balloob commented 5 years ago

client_id is not created per user account, a client ID is something used on a per app basis to allow multiple users to authorize.

We should not conflate concerns. There are user concerns, there are app concerns.

Think about where we want to be as a platform. If we install this for our parents, I want them to get a message that they can't set it up right now and contact their administrator instead of being asked for a client ID/secret.

Config flows are for users, it should never require a user to have to go into the developer portal/create a developer account etc.

elupus commented 5 years ago

In my example, nibeuplink, since this is a self-hosted instance of an app. I get generated client_id for my use (nibeuplink) a. These are linked to my user account. In essence same thing as app password when you have mfa on mail and other things. The password is very much linked to you as a user. It's just a way to delegate certain permissions (on my user) to an application.

balloob commented 5 years ago

Such services should adopt Indie Auth. We did with Home Assistant and it's awesome.

https://aaronparecki.com/2018/07/07/7/oauth-for-the-open-web https://indieauth.spec.indieweb.org/

elupus commented 5 years ago

Not really an option to force organizations to adapt to homeassistant :). But it's no major issue to keep it in config files.

balloob commented 5 years ago

It's not our spec, so organizations wouldn't adapt to us. But if a product is locally installed and client IDs are mainly one off, adopting Indie Auth makes sense.

elupus commented 5 years ago

Well home assistant is the client/product, and it is usually locally installed (apart from hassio). Another client in this case is ifttt.com, which obviously is not locally installed (they have a global non user specific client_id i think).

I just realized, the client_id I create might actually be global. You still have to log in when you request token. So token could still be user specific. Will have to verify this. I suppose this is what you solve with hassio. A public redirect url, a place to store the client_secret.

frenck commented 1 year ago

This architecture issue is old, stale, and possibly obsolete. Things changed a lot over the years. Additionally, we have been moving to discussions for these architectural discussions.

For that reason, I'm going to close this issue.

../Frenck