Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use access_token instead api_password #15376

Closed
12 of 19 tasks
awarecan opened this issue Jul 9, 2018 · 53 comments
Closed
12 of 19 tasks

Use access_token instead api_password #15376

awarecan opened this issue Jul 9, 2018 · 53 comments
Assignees
Labels

Comments

@awarecan
Copy link
Contributor

awarecan commented Jul 9, 2018

It is an epic includes all files need to remove api_password, change to using access_token.

Separate issue/PR may create for each change.

All tests are not listed here.

@balloob
Copy link
Member

balloob commented Jul 9, 2018

I suggest we drop the API class in Remote and the related methods. Home Assistant is moving away from Rest to WebSocket calls, and we should not maintain these methods. It's also sync instead of async.

@awarecan
Copy link
Contributor Author

awarecan commented Jul 9, 2018

Will that break lots of users?

@awarecan
Copy link
Contributor Author

awarecan commented Jul 9, 2018

We probably need two rounds change. The first round, add access_token, keep api_password, and make sure access_token will be used if auth.active. Make a big announcement, switch auth.active from opt-in to opt-out. Then make the second round, remove api_password.

@fabaff fabaff changed the title EPIC: Use access_token instead api_password Use access_token instead api_password Jul 9, 2018
@gerard33
Copy link
Contributor

I guess Geofency should be added to the list as well.
https://www.home-assistant.io/components/device_tracker.geofency/
components/device_tracker/geofency.py

@awarecan
Copy link
Contributor Author

awarecan commented Jul 15, 2018

We may have to implement accept access token in query string (RFC 6750 2.3) to support web hook usage.

I will suggest to add an optional config in auth components to explicitly enable this support, since it is not recommend validation method

@balloob
Copy link
Member

balloob commented Jul 15, 2018

I don't think that I want to support that. Integrations can allow users to configure a token if they want to do auth via url

@awarecan
Copy link
Contributor Author

awarecan commented Jul 15, 2018

I see.

@gerard33 So the Geofency will need change its view as follow example.

class GeofencyView(HomeAssistantView):
    """View to handle Geofency requests."""

    url = URL
    name = 'api:geofency'
    requires_auth = False

    async def post(self, request):
        if not your_custom_validation(request):
            return web.Response(status=401)

EDIT: So, for any 3rd party want to use HA native auth system, they have to official support OAuth 2 protocol, otherwise, the component need implement itself auth system.

To keep backward compatibility, it can still accept api_password in query url or basic auth header. However, the actually validation logic need be written by individual component, HA will eventually remove current api_password configuration and validation function from http component, do not rely on it.

@balloob
Copy link
Member

balloob commented Jul 15, 2018

When adding something to the url, it should not be a HASS access token, instead the integration should allow the user to specify some sort of auth in the config.

We don't have permissions yet, access tokens are very powerful, never expiring access tokens even more (as that is what a user would want to use). URLs are getting logged in proxies or other systems left and right. There is a very good reason auth should not be send via a url. So if an integration like Geofency wants to use auth in the url, it should define their own string, as that would only grant access to that one endpoint.

@awarecan
Copy link
Contributor Author

Another issue for 3rd party use access token if they don't native support OAuth2 is that they cannot pass IndieAuth, since we need a redirect url match the client id. This will be a deadend.

I will edit my previous comment

@pvizeli
Copy link
Member

pvizeli commented Jul 18, 2018

It's very dificult to use websockets with curl in bash scripts. I like also to minimize the REST API support but complete remove in flavor of websockets are heavy.

A developer can write a short python script but a sysadmin ends with call curl.

There are also other integraton like nodered they run with eventstream and Rest API. I think a rest API and mqtt are a minimun support for IoT device. That will be also used for esphome.

But I also think we should remove the remote class.

@awarecan

This comment has been minimized.

@jedi7
Copy link
Contributor

jedi7 commented Aug 20, 2018

Hi, the warning "Please change to use bearer token access" is comming also from appdaemon calls.
I'm also for to keep the rest api (ex: for simple router scripts to track devices)

Regarding appdaemon, how is auth solved for "system" 3rd party services? Like appdaemon?
Thanks

@balloob
Copy link
Member

balloob commented Aug 20, 2018

Just like all other apps: migrate to the new auth.

@balloob
Copy link
Member

balloob commented Aug 24, 2018

Did a quick grep through the code. These are the components that register HTTP views and probably need to be updated to work with access tokens:

  • alexa (manual setup)
  • binary_sensor/mystrom.py
  • camera/push.py (Replace api_password in Camera.Push #16339)
  • device_tracker/automatic.py
  • device_tracker/geofency.py
  • device_tracker/gpslogger.py
  • device_tracker/locative.py
  • device_tracker/meraki.py
  • device_tracker/owntracks_http.py
  • dialogflow.py
  • dominos.py
  • doorbird.py
  • foursquare.py
  • google_assistant (manual setup)
  • konnected.py
  • mailgun.py
  • prometheus.py
  • rachio.py
  • rss_feed_template.py
  • sensor/torque.py
  • spaceapi.py
  • switch/netio.py
  • twilio.py

Might be less as I have not checked if all these HTTP views require authentication.

@DavidFW1960
Copy link

My Google Assistant (manual setup) used the original gactions works fine still without legacy_api enabled.
I also think you might have missed IFTTT in the list?

@frog32
Copy link
Contributor

frog32 commented Aug 28, 2018

binary_sensor.http is also missing in this list

@awarecan
Copy link
Contributor Author

awarecan commented Aug 29, 2018

IFTTT can be categorized with REST API.

Maybe we shall retire sensor.http and binary_sesnor.http?
EDIT: clearly the doc is outdated, those should be removed from components. They are part of REST API

@dgomes
Copy link
Contributor

dgomes commented Aug 29, 2018

I'm responsible for camera.push

So currently I have:

POST /api/camera_push/camera.<entity_id>

This endpoint must be secured, and I relied so far in the rest API.

Since most calls are handled using curl as external call to a script, it makes no sense to move this to the websocket API.

Should I implement #15376 (comment) proposal ?

@balloob
Copy link
Member

balloob commented Aug 30, 2018

@dgomes yeah. I would suggest something like this:

# configuration.yaml entry
camera:
  - platform: push
    token: sdlkjadslkjadskjlad
    name: MotionEye Outdoor
    buffer: 3
    timeout: 5

And then accept pushes without authentication on the url

POST /api/camera_push/camera.<entity_id>?token=<token>

This is exactly how the Media Player thumbnail endpoint works:

https://github.com/home-assistant/home-assistant/blob/f20a3313b09129b725fec0ac4064bafe940db233/homeassistant/components/media_player/__init__.py#L995-L1014

@dgomes
Copy link
Contributor

dgomes commented Aug 30, 2018

Tks @balloob !

Are we OK replicating this solution in all other components relying on api_password ?

Can't we create a special user with limited access to specific API's? (RBAC -> implement user based ACL's) I think this would also pacify the discussion on the last release blog post.

In the meanwhile I'll prepare this change to the camera.push component.

@balloob
Copy link
Member

balloob commented Aug 31, 2018

we'll get permissions eventually, not today though 😉

Yeah we're ok with replicating this logic. It's not a lot of logic so no need to create an abstraction for it.

@rohankapoorcom
Copy link
Member

Okay, that makes sense. I guess the correct approach for those components then is continuing to use a password from config just not the one from the HTTP component and then disabling auth on the view?

I disagree though regarding responses from webhooks. Some endpoints (Twilio in particular comes to mind) require a webhook to be acknowledged with a certain response (in twilio's case their specific XML format) so that they know you received the data.

@balloob
Copy link
Member

balloob commented Oct 25, 2018

Those components should start using long lived access tokens yes.

@balloob
Copy link
Member

balloob commented Oct 26, 2018

I Apologize, I did more research and saw the PR by @rohankapoorcom and changed my mind. Webhooks should be able to return responses, but we should make sure we only use them for webhooks.

@rohankapoorcom
Copy link
Member

rohankapoorcom commented Jan 16, 2019

I was thinking about moving the Meraki device tracker platform (first to a split component/platform) and then to use the webhook component instead of the current API password approach. Unfortunately I found this in the Meraki docs:

Upon the first connection, the Meraki cloud will perform a single HTTP GET; the server must return the organization-specific validator string as a response, which will verify the organization's identity as the Cisco Meraki customer. The Meraki cloud will then begin performing JSON posts.

Since we don't allow the webhook component to respond to GET requests, what do you recommend for moving this component off of the API password? The simplest approach I can think of is to switch to an unauthenticated webview and perform our own authentication (via a custom API password) for this platform.

@awarecan
Copy link
Contributor Author

After #21884, only api_password left are in either test code or legacy_api_password auth provider or http and websocket_api related codes. This issue can be closed.

@ghost ghost removed the in progress label Mar 11, 2019
@RyuzakiKK
Copy link
Contributor

@awarecan What about components that still requires http.api_password to work, like alexa?
I hope api_password will not get removed until all HA components switched away from it.

@awarecan
Copy link
Contributor Author

I believe I have already checked all usage place, there should be no more dependency on http.api_password.

Could you please point to me where alexa need http.api_password

@RyuzakiKK
Copy link
Contributor

For Alexa the wiki guide says that the api_password is still required as an endpoint https://www.home-assistant.io/components/alexa/#requirements and apparently we can't yet use a long lived access token for example.

@awarecan
Copy link
Contributor Author

You can still use api_password in URL as long as you have legacy_api_password auth provider configured.

BTW, use api_password in alexa endpoint is not a good design, we should change it by verify the Amazon signature.

@balloob
Copy link
Member

balloob commented Mar 13, 2019

It should use a webhook.

@awarecan
Copy link
Contributor Author

Actually, just like google assistant, alexa also can leverage our oauth2 authentication. I can look into it, https://developer.amazon.com/docs/account-linking/account-linking-for-sh-and-other.html

@balloob
Copy link
Member

balloob commented Mar 13, 2019

Oh there you go!

@jerrychong25
Copy link

Based on the long conversation of this issue, it is confirmed that api_password will be dropped completely soon. A migration definitely is unavoidable.

Just curious, what is available method for this migration?

AFAIK, currently only have long live access token with curl command method.

@awarecan
Copy link
Contributor Author

awarecan commented Apr 15, 2019

@RyuzakiKK
Copy link
Contributor

@awarecan any news for the oauth2 authentication in the alexa component?

Sorry for being probably off topic, but as far as I know there isn't an open issue about that.

@awarecan
Copy link
Contributor Author

awarecan commented May 1, 2019

Document has been updated. https://www.home-assistant.io/components/alexa.smart_home/

@filikun
Copy link

filikun commented Oct 26, 2019

Looking at the Meraki integration it seems to still need the api_password? https://www.home-assistant.io/integrations/meraki/

@Josti79
Copy link

Josti79 commented Dec 28, 2019

Looking at the Meraki integration it seems to still need the api_password? https://www.home-assistant.io/integrations/meraki/

Has anyone had any luck to fix the Meraki component?

@123dev
Copy link

123dev commented Jan 7, 2020

Looking at the Meraki integration it seems to still need the api_password? https://www.home-assistant.io/integrations/meraki/

Has anyone had any luck to fix the Meraki component?

And considering that Meraki Location and Scanning settings does not allow to set the HTTPs headers, the integration doesn't work with Long Lived Access Tokens
Setting up nginx reverse proxy to append the required headers based on the URI query api_password value seems to have worked around the issue for now.

@awarecan
Copy link
Contributor Author

awarecan commented Jan 8, 2020

Meraki need to change to use webhook implementation, @filikun @Josti79 @123dev you can look other device tracker platform, such as gpslogger or locative.

Lots of device tracker platform have changed to use webhook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests