Thursday 14 November 2013

Using OAuth 2.0 with MQTT

I've been thinking about security and privacy for IoT. I would argue that as the IoT grows we are going to need to think about federated and user-directed authorization. In other words, if my device is publishing data, I ought to be able to decide who can use that data. And my identity ought to be something based on my own identity provider.

The latest working draft of the MQTT spec explicitly calls out that one might use OAuth tokens as identifiers in the CONNECT, so I have tried this out using OAuth 2.0 bearer tokens.

In order to do it, I used Mosquitto and mosquitto_pyauth, which is a handy plugin that let's you write your authentication/authorization login in python. As the OAuth provider I used the WSO2 Identity Server.

The plan I had on starting was:
  • Use a web app to go through the bootstrap process to get the bearer token. Encode an OAuth scope that indicates what permissions the token will have:
    • e.g. rw{/topic/#} would allow the client to publish and subscribe to anything in /topic/#
  • Encode the bearer token as the password, with a standard username such as "OAuth Bearer"
  • During the connect validate the token is ok
  • During any pub/sub validate the requested resource against the scope. 
Here is a sequence diagram:


The good news - it works. In order to help, I created a shim in the ESB that offers a nice RESTful OAuth Token Introspection service, and I call that from my Python authentication and authorization logic.

I had to do a few hacks to get it to work.
1) I wanted to use a JSON array to capture the scopes that are allowed. It turns out that there was a problem, so I had to encode the JSON as a Base 64 string. This is just a bug in the OAuth provider I think.
2) I couldn't encode the token as the password, because of the way Mosquitto and mosquitto_pyauth call my code. I ended up passing the token as the username instead. I need to look at the mosquitto auth plugin interface more deeply to see if this is something I can fix or I need help from Mosquitto for.
3) mosquitto_pyauth assumes that if you have a username you must have a password, so I had to pass bogus passwords as well as the token. This is a minor issue.

Overall it works pretty nicely, but there are some wider issues I've come up with that I'll capture in another write-up. I'm pretty pleased as I think this could be used effectively to help control access to MQTT topics in a very cool kind of way. Thanks to Roger Light for Mosquitto and Martin Bachry for mosquitto_pyauth. And of course to the WSO2 Identity Server team for creating a nice easy to use OAuth2 provider, especially Prabath for answering the questions I had.

Here is the pyauth plugin I wrote. Apologies for poor coding, etc - my only excuses are (1) its a prototype and (2) I'm a CTO... do you expect nice code?!
Loading ....

No comments:

Post a Comment