Data Sharing in the IoT Bill Doerrfeld August 25, 2015 We consistently put our personal data at risk. API security concerns sky rocket as the user’s desire to pass access to others steadily increases. With the rise of Internet of Things (IoT) devices, the ability to share the use of physical connected devices makes access management an increasing concern. Whether sharing a collaborative document or car location, users routinely pass data and access to family members, friends, coworkers, clients, or fellow app users — most often using APIs. But how can these data exchanges be accomplished in a secure and efficient way using existing standards? In a session with Nordic APIs, Jacob Ideskog demonstrates how this is possible using OAuth enabled with OpenID Connect. In this piece we’ll examine how to implement secure data sharing for a new bike lock IoT device — a real world example of introducing a best practice approach to identity management in the IoT realm. A New Economy Based on Shared, Delegated Ownership In addition to dramatically altering the way enterprise business is done, APIs are fueling a major consumer shift. With the dawn of smartphone ubiquity, sensors, and IoT devices, new subscription services and businesses have quickly emerged around the concept of sharing access to personal property. Homeowners are becoming part time business owners with Airbnb, citizens with a car and free time are making extra income driving with Uber or Lyft. Apps enable users to share their office or work space, or use communal cars with Car2Go or ZipCar. Put simply, the Anything-as-a-Service (XaaS) model is the wave of the future. Sharing ownership comes with inherent risks. Risks on the side of the party using the property, and risks within the data exchange process. So how does an app avoid security risks to ensure ownership is delegated correctly? What specific technologies and workflows offer the best route to access management? Skylock – Example IoT Device Take Skylock, a crowdfunded initiative to develop a solar powered connected smart bike lock. It’s loaded with features — a built in anti-theft feature, accelerometer to analyze movement, and automatic safety response alerts. Skylock also allows keyless entry, and has an ability to share access remotely with friends using the Skylock app. The Skylock lock and app likely utilize many first or third party APIs to power location, mapping, safety response, and more. But out of all the software powering the scenarios presented in their promo video, the most complex part of a system like this may be the sharing of access that occurs between users. Related: Take a Deep Dive into OAuth and OpenID Connect How This Works In a scenario like this one, the user typically authorizes the app to access the API. We’ll call the guy Adam, and his girlfriend Bianca. Let’s say Adam wants to share access so that Bianca’s app can access Adam’s account via the API. In this case, sharing is delegating use. Can’t OAuth be used for that? Not exactly. OAuth is really about the User delegating access from the User to the Application, i.e. user-to-app delegation. Typically, in OAuth the app requests access to an API and the user grants that access. OAuth then gives the app a token. Rather, this new situation is more complicated. Since Adam wants to allow Bianca to access his account, delegating user responsibility to Bianca, we are dealing with user-user delegation. There are two ways to do this. Either you set up a database or table around the API for Bianca to gain access to in order to retrieve data, or, the system grants Bianca an access token that belongs to someone else, i.e. Adam, granting Bianca equivalent powers. Related: How to Control User Identity Within Microservices Option #1: Access Tables In the first approach, we use the API to retrieve data from an access table. The flow is as follows: Bianca’s app contacts the OAuth server. The OAuth server challenges Bianca to enter her credentials (username/password). The OAuth server accepts, and issues her own account’s access token. Bianca uses this token to send a request to the API. At this point, she must somehow instruct the API that she intends to perform on other resources — she must distinguish between users to access Adam’s account. (This step is unfortunate as it requires tangling identity management within the API itself). The API talks to the database to verify that the access is real, and validates access. The API then responds with Adam’s data to the app. Looking at it, this is architecturally the simplest flow, but however, implementation is the hardest. This is especially difficult when building microservices that plugin to many APIs. We may be building many small APIs that need to implement and contact services to repeatedly allow data access. These microservices may be doing many separate things. Their communication protocols may not be similar, and on top of that, if you have user info tangled into that data, you’re going to have to program a lot — a lot to leave up to developers to handle. Option #2: Delegated Tokens: OpenID Connect OpenID Connect is a companion protocol to OAuth. Enabling an OAuth server with OpenID Connect adds an identity layer on top. Now our API not only knows what access is being given, but it knows who is accessing that data. This is processed using the OpenID Connect Userinfo endpoint, a simple endpoint that can be called using a GET verb with an authorization token. The Userinfo endpoint responds with a JSON document, containing basic user information such as name, phone, email, etc. With a user token you can retrieve Userinfo to access user information — a pretty simple process. We can take this response, and change the meaning by adding access tokens in this response. This is how we list the delegations. We’ll use the Userinfo endpoint to reissue tokens, or downgrade tokens. In the case of our bike lock, Bianca receives an access token for the Resources Owner, Adam, containing meaningful data and scopes to specify who the authenticator is — in our case, Bianca. The new flow is like this: The app requests access from the OpenID Connect enabled OAuth server. The server challenges Bianca to enter her credentials (username/password). Bianca receives her own access token. Bianca then calls the Userinfo endpoint with her access token. The OpenID Connect enabled server takes this access token. The server responds with a second token (Adam’s access token). This came from JSON document. BIanca now has 2 tokens. When Bianca needs to operate on Adams data she uses the token she got from the UserInfo endpoint. If she needs to do stuff on her on account, she uses the initial access token she got. The API will at all times receive one token, and can look at it to see which user it should operate on. An example Userinfo JSON response may look like: { "sub": 'bianca", "name": "Bianca Doe", ... "example:delegations" : { "adam" : { "access_token" : "te2eg9a-2daca99-ad9caf-nacnkh3h", "expires_in" : 300, "scope" : ["stuf", "otherstuff"] } } } Sharing Access Between Microservices As we learned in How to Control User Identity Within Microservices, handling user data within microservices is a very similar process. We send in an access token, and it terminates that token. If we want to access someone else’s account, we simply use a different token. To regulate this process we can place a gateway at this intersection. It doesn’t really matter — regular or delegated access tokens are acted upon in the same way. Our normal access case won’t have to be altered — meaning that modifying the backend is not necessary. Ideskog admits a possible drawback is that if an app must maintain a multitude of tokens. When delegating tons of tokens with many people involved in a single flow, you may run into system bloat. For more, watch Jacob Ideskog present on this topic at a Nordic APIs event Review: Thanks to smart approaches to delegating access, Adam can remotely share his bike lock with Bianca in a secure and confident manner. These methodologies also transfer into identity management within web apps, APIs, or IoT situations in which users must grant functionality to other users. As a review, to accomplish this there are two alternatives: Access Table Lookup Approach: Identity is built into the API, and a database is stored access lookup is stored. Easy to implement form an ADMIN perspective Every API needs to know about delegation Every API needs to resolve access rights With microservices this becomes a LOT heavier. Delegated Tokens Approach: Identity is removed form API, thrown into OpenID Connect server and OAuth server. Easy to implement on the API side APIs work the same for regular access and delegated access App must maintain multiple tokens It’s important to remember that OAuth is user-to-app delegation, not user-to-user delegation. However, if we throw on OpenId Connect and use the Userinfo endpoint, we can add user-to-user delegation and be complete with quality access sharing standards. Disclosures: Skylock is just used as an illustrative example, and we have no affiliation with the company and don’t know if they used this specific technique in their system. Graphics owned by Twobo Technologies. Jacob Ideskog is an Identity Specialist with Twobo Technologies, a sponsor of Nordic APIs The latest API insights straight to your inbox