Best way to distribute access for product and access token expiration times

We are building a IoT product and we want the first run to use the spark. Accordingly we need a way for clients to get their device ID and access tokens. Our users don’t want to register with an email address and password. This is to much PII and work (and we agree with them!).
I’m hoping for feedback on our current strategy and a reply to a critical question which right now Spark.IO can’t handle!

  1. We register all cores to ourselves and flash them at the factory. We generate an access token for ourselves. This ensures we have control over the cores and can flash them with updates as needed. We then place them in “wifi search” mode before shipping.
    ---- Devices arrives at user -----
  2. Wifi is handled by integrating the SmartConfig library into our own app.
  3. DeviceID and AccessToken… each device has a QR code with the device ID, and then separately distribute the access_token as another QR. User keeps access_token in a safe place. They will then scan both of these into their app to get setup.
  4. Use app and enjoy.

Is this the optimal way to handle this? The major blocker we have right now is that access_tokens expire really often. We want the users token to expire in 20-30 years. They shouldn’t ever need to talk to us. If they need to, for whatever reason, we can invalidate their token and generate a new one, but this is the exception!

When can we expect updates on the access token and auth front? We can’t ship unless we can control the tokens.

2 Likes

This question was just brought to my attention @OrangeOctober—we’ll be implementing a full OAuth 2 solution soon. I’ll add a longer response here later today.

1 Like

Just FYI, I’m working on a long, detailed response here. It’s in progress. Cheers!

Very much looking forward to it @zachary! Thanks for your consideration in helping to take this from a “single unit hacker” project to something which could ship 10-1000’s of units.

You are welcome. Sorry for the delay. We are very busy over at Spark HQ! The quick version goes like this:

  • The scenario you describe would allow any user of your product to control all your products, even flashing new firmware to them. Don’t do it!
  • We use OAuth 2.0.
  • We currently only support resource owner password grant.
  • We will have a full OAuth implementation soon, probably in September.
  • Auth code grant + refresh tokens is The Right Way™ to do things like this.
  • But that requires users to create an account with Spark—not as convenient as we would all like for the ideal box opening experience.
  • So I’m designing a custom extension grant type, which is hard. :wink:

More to come soon.

Cheers!

1 Like

As Spark.io is evolving quickly, in case this post is found in the future, everything in this post is related to the Spark.io ecosystem as of August 14th 2014.

@zachary thanks for the reply. I failed to recognize that, currently, one access token provides access to every device registered to an account. I was under the, incorrect, impression that access tokens were paired against devices. What this means is that in order to achieve the “box opening experience” I described above while maintaining security, we would need to create a separate spark account for every device we sell. Not impossible, but it seems like a rube-goldberg solution.

I’ve just read through the OAuth 2.0 RFC (6749) and I don’t see why creating a new extension grant type is required. I think within the scope of the “box opening experience” problem, it’s unrelated to the grant type used.
OAuth 2.0 already has the required components to make this system work. The spec says that authorization tokens can carry with them a scope. In this way tokens can carry both the scope of a specific device ID, as well as the scope of whether or not they are allowed to update the given device with new firmware or just make requests against the existing firmware.
[Sidebar: I would also like to see the Spark.io accounts support 2-factor authentication as passwords stink for really important stuff]

Using OAuth 2.0 then, I would suggest the following architecture and control flow for a very simple improved version, which I think should be a lot less work than a new OAuth grant type.


Initial Step:
User (USR) claims spark device ID from Spark (SPK), becomes owner.

Access Generation Step:
USR------> SPK,
Request new access token
where the request includes:

  1. USR login
  2. USR password
  3. USR 2-factor
  4. device ID: if null, => global scope token requested
  5. access_level: a simple first proposal is, ENUM {all, noFlash}, where noFlash restricts the user from the “PUT /v1/devices/{DEVICE_ID}” endpoint and allows all others

Response SPK ------> USR provides an access and a refresh token with the requested scope.

Request Step:
All requests to https://api.spark.io/v1/devices/0123456789abcdef01234567 are checked against the token for both device scope and access scope before being granted.

We could then distribute these auth+refresh tokens as printed items with our devices, and our Android app could handle the “token refresh” cycle when needed. How to handle the new auth+refresh tokens after a refresh is the only part of this flow that is still a bit thorny because it would mean the printed tokens we ship with the device are now invalid. I could see prompting users that their tokens have changed and that they need to email/store the new tokens and throw away the old ones. If that is all done on device, (easy on Android using Intents) then they still wouldn’t need to register any PII with us. This accomplishes our goals of 1. not having users register with us, and 2. not requiring us to build and maintain an authentication intermediary web-service. This scheme assumes that we must have tokens expire and we therefore need refresh tokens.

Changing subjects a bit, I see a larger vision (which may be what you are getting at) where the authorization step could be delegated to a third party (e.g. me). This way, I can control and create the authorization logic however I want. This would allow authorization scopes as finely grained as desired and potentially allow me to include things like time-of-day, gps location, and the moon cycle in determining when users can access a given device. A very neat and exciting thought experiment indeed! If this approach was required it would carry the downside of requiring everyone a lot of work (implementing and maintaining the auth server). Something we, in our specific case, would love to avoid.
For this reason, would you consider making a smaller step, something more in the direction of what was suggested above?

The IoT is already a lot of fun, I’m glad to be a part of it. Cheers.

1 Like