Wednesday, August 1, 2018

OAuth + IOT Part 2: OAuth Flows for Devices

In the last post we covered different flows for OAuth on the web and mobile devices. This post, we will pick up the discussion and cover how OAuth can be used to authenticate external IOT devices.

Though OAuth is complex, it has been well documented for apps where the user can authenticate with a server back-end or directly with the app in a mobile device or browser. While building a smart clock, with a google calendar integration, I found existing OAuth models do not apply well to IOT devices as these devices often lack a browser or method for direct input. I spent some time hacking at different approaches and decided to share my attempts.

This image is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. And is based on the work by Chris Messina.

A Traditional Approach

If you are planning to use a server to make all the requests to the service, you can use the OAuth Authorization Code flow. This flow would follow the same flow from the previous post with a few caveats, as shown in the diagram below. The user would still use a browser or another app to grant access to the client server to interact with the service. However, the user would also need to associate the device with their account on the client server. From then on, whenever the device wants to use the service it would have to communicate through the client server.

This association of the device with the end user on the client server is glossed over in my diagram but it is a sticking point. You must construct a way for the server to uniquely identify each IOT device in a way that a hacker cannot imitate the device and access user data from the service. In my opinion, it is not secure enough to just have a serial code (or other hard-coded value) which is used for the device. If this is done, an attacker could read those values from the device's hardware or guess the values if they are created with a predictable scheme.

My suggestion would be to have the device display a generated code from the server when it connects to the server. The user would then enter the code into another device or browser which would pass it to the server. This way the user knows which device they are giving server access to. Following that step, the device can generate a random password which would be stored in memory or within a secure persistent storage partition. This password would be used for identifying the device to the server.

External Device OAuth Flow with Trusted Backend
made by Fuad Balashov, Distributed under the CC 4 License
A server based approach is one of the most standard ones I identified and I encourage you to consider it. This approach is especially helpful if you plan to do processing of the data from the service or share data across multiple devices. In my case, I did not want to introduce a new layer which needs to be maintained so I decided to look for solutions which would not require a server.

Direct Input

Once you no longer consider having a client server between the device and service, you need to find a way to authenticate your device (eg, make it the client). If your device has an input method (keyboard or touchscreen) and a browser, then a user can directly authenticate the device with the authorization service. The limitation of this approach is many devices abstain from these to lower production costs and provide a more robust product. If you are wondering what the flow looks like, it is identical to the Mobile OAuth flow from the last post.

Leaky Tokens

One approach I tried and would NOT recommend is to have the user authenticate on their phone, and then send the tokens from the phone to the device over Bluetooth (or any secure, encrypted communication method). This approach seemed fine to me as the user maintains control of the token and is the one passing it to another device. On top of that, the service should give them a way to invalidate the access and refresh tokens if they no longer want the device to access the service.

However, this approach will draw a lot of criticism and scrutiny. By having the phone app pass tokens to the device, I introduced a new interface which could be exploited to steal the tokens. Moreover, sharing the tokens intended for the phone app sounds very much like an exploit of the service's trust in your application, whether or not that implies an actual security problem.
Leaky OAuth Flow for External Devices
made by Fuad Balashov, Distributed under the CC 4 License

IOT First Flow

Ideally, there would be an OAuth flow which grants credentials to an external device without compromising security. After banging my head against the keyboard I found Google offers exactly such a flow.

In this flow, the user must first tell the device to start the flow with the service's authentication server (eg, by pressing a button on the device). The auth server will return a code and a login url for the device to display. The user will navigate to the given login url, enter the code, and provide the credentials to their account. If authentication is successful then the device can ping the auth server to get an access token.

If your device has no display, it will have to use another secure communication path to transmit the code and url to the user (like Bluetooth low energy).

Image from Google's Identity Platform Docs

At first, I thought this was a self rolled solution by Google, but after searching for "OAuth 2.0 Limited-Input Device" I discovered Facebook, and Salesforce both support the same flow. Moreover, the flow is captured in an ieft draft originally from 2015. However, it seems few services support this flow and even Google only supports a limited set of apis. Hopefully, other services are thinking of this use case and planning to add support for IOT devices to access their apis.

Final Thoughts

If your IOT device will need to exchange data with an external service, you will have to think about authentication. Tools are slowly developing and growing to meet this need, and I hope this read is informative to anyone looking for a solution. If you have some approaches you have tried, or thoughts on the ones I listed, I would love to hear them. And if you are writing a service you envision could be integrated with IOT devices, I encourage you to implement a secure authentication flow for that use case.


Post a Comment