Authentication flow for IoT devices/wearables

I feel that the concept of solid pods would solve many of the privacy issues around IoT devices/wearables. I have a concept in mind to have e.g. a fitness tracker which publishes it’s data into a private file of my personal pod. However, so far, the only way I’m able to connect outside of a browser, is using solid-node-client, and only the flow for ESS-Style Pods. However, this is not a good fit for my use case for a number of reasons:

  • It only works for one specific style of pod provider. If we were to build a product on this concept, it would need to work with all pod providers.
  • For some reason, this flow only works for one session - if I try running it again with the same token, it does not work (may be a bug?)
  • Even if it worked, I believe these tokens are only valid for a short period, and the user would need to frequently re-authorize their device, which is onerous for this use case.

Is this sort of thing entirely outside the scope of Solid? Is there another authorization method I’ve overlooked which would be a better fit to this?

1 Like

It’s definitely not outside the scope of Solid. If you’re fine with using Node, I believe solid-client-authn-node can satisfy your use case, the documentation for which you can find at Authenticate — Inrupt JavaScript Client Libraries.

As for your second and third bullet, pay extra attention to the section Handling Refresh Token Rotation.

@Sheap - you are mistaken about solid-node-client and NSS - it does work with both NSS and ESS. (though depending on your version you may need to apply a patch as mentioned below)(

The landscape for Solid login has changed every couple of months for two years. We are finally at a stage where most of the spec related to it is complete and the servers have mostly (though not completely or consistently) implemented the spec.

Solid-Node-Client does work with both NSS and ESS but since they are both changing, there are gaps as the library plays catch up.

There is currently a bug in some versions of solid-node-client (it depends when you used npm to install it). A downstream package that causes solid-node-client to not work on NSS. I have submitted patches to the downstream libraries and solid-node-client should work again with NSS as soon as the patches are accepted by the downstream authors. There is a simple fix in the mean time - see Could i login solid pod automatically without opening the solid login page? - #5 by jeffz for the details.

ESS recently completely changed their login flow which is what causes the dropping of the session after one login. I am investigating a fix for that and should have one soonish.

@Vincent - can solid-client-authn-node login to NSS with a username password? Can it log in to NSS with a token? Can you point me to documentation if either is possible?

If @vincent’s answer to those questions is yes, then the only reason to use solid-node-client over solid-client-authn-node is that solid-node-client leverages solid-rest to provide Solid access to a non-pod local file system via file:/// URIs and provides a plugin architecture for access to other storage systems. If Vincent’s answer is yes and you have no need of the local or plugin features, then solid-client-authn-node may be your best option.

1 Like

Node is not a solution for my idea in the long term. I was simply using it to test if I could have a machine maintain long-term access to a pod without needing a user to actively open a browser (a single browser session during initialization would be acceptable). In the long term, if the spec is stable, I would have to reimpliment the auth flow from solid-client-authn-node or solid-node-client into something which can run on embedded devices (i.e. c, micropython, rust). But that’s not something I’m willing to do if the spec is going to change under my feet.

I’ve spent some significant time trying to wrap my head around the various auth flows, but so far I don’t have a good grasp of it. It sounds like I will need to do some more reading. If you could point me at what you think is an appropriate flow, I would really appreciate it.

Ideally, I could simply store my identity provider, username, and password on a device, which could use these to authenticate and access my pod on its own with no browser involved. (as is claimed is possible for NSS-style pods. Is this part of the standard now? will this soon be possible with ESS pods and any theoretical future servers?)

Alternatively, what could be possible, is using a mobile device to retrieve an OIDC token once, and then transfer that token to the device, which could then use it to access the pod. However, as I understand it, the OIDC token - even if refreshed correctly - is only valid for 3 days. Meaning this would have to be repeated frequently. This would be a deal-breaker for many of the ideas I have in mind.

NSS supports browserless login by sending the username and password directly. That is not secure and is, I believe now not supported in the spec. Solid-node-client supports this kind of login because it is great for automated operation and testing. In the long run, and for things requiring strong security, it is probably best to avoid the direct browserless login to NSS.

The Solid specs related to OIDC are, by my understanding, very close to complete. Inrupt has said that making the token last more than three days may be on the long range roadmap but you’d have to talk to them about when and if that will happen.

No, the way it works is that it generates a link that the user has to visit - in the case of an IoT device you’d probably share this through e.g. a QR code or a companion app. That link is to the user’s Solid Identity Provider, where they enter their username and password. Once they confirm that the device is allowed access, it will be notified and can complete the sign in flow.

After that flow above is complete, the device will have a refresh token. You can then pass that to solid-client-authn-node, which can use it to make authenticated requests. The Solid Identity Provider may occasionally provide you with a new refresh token, which solid-client-authn-node throws an event for so you can replace the old refresh token with the new one. (Inrupt’s Enterprise Solid Server does this on every request, I believe, but other servers might keep them around for longer.)

I’m not up-to-date on whether Node Solid Server supports that full flow, but I think it does.

@Vincent have you actually logged in to NSS using the flow you describe? I have not been able to and if you have, I would definitely appreciate a code snippet or documentation.

The standard, not-Solid-specific OIDC spec is here, and the way Solid extends that is here (primarily DPoP, if I recall correctly). I think, but am not sure, that the Authorization Code Flow is the part of the OIDC spec that’s tailored to IoT. Edit: Actually, I think it’s the Device Flow for the OAuth 2.0 spec, which OIDC is based on. Edit 2: actually, I don’t think that’s it either. I just don’t know, sorry.

As far as I’m aware the whole point of the spec is to allow the user to grant access to their Solid Pod without having to share their credentials with anyone, so I’m fairly certain that this will never be part of t he standard.

I don’t think the standard prescribes any particular lifetime. The “3 days” number doesn’t ring any particular bells for me at least. (But I should emphasise: I’m not too closely involved with the auth work.)

I did not, hence “I’m not up-to-date on whether Node Solid Server supports that full flow” :slight_smile: Unfortunately most of the auth stuff is a bit over my head still, but hopefully at some point in the future I’ll have a better grip of it and be able to answer such questions with more certainty.

@Vincent - yep, I guess I could have deduced that. :-). I think @zwifi is in a better position to answer the question of whether solid-client-authn-node can login to NSS than either your or I.

I tried to get my head around this.
As far as I can tell the device workflow is not currently supported by the solid oidc spec.
Authorizing a browserless device or input constrained device requires going through the authorisation in a separate browser and the device polling the server for a token as a result.

From a security perspective, the token then provides long term access to the scope unless revoked. Such devices are usually assumed not to be secure, and the server is meant to mitigate the attack surface accordingly.
With Solid this seems a bit tricky, but the discussion about the handling of bots in the old webid-oidc spec seems relevant (brainstorm) does ‘bots have webids’ remove the need for 'client credentials flow'? · Issue #30 · solid/webid-oidc-spec · GitHub
If there is a sufficiently easy way of getting the necessary token onto a device than the device can be issued its own webid and access control limited accordingly.

In absence of any official support for device authorisation flows, if one assumes that the token can indeed be easily compromised, then another solution is simply to enable append-only public access to a non-discoverable Uri, e.g within a private folder. If the Uri is compromised, corrupt data could be added, and a new one would need to be minted. A URI is likely easier to compromise than a token, but you’d still need to be able to observe the traffic in order to do so?

Edit: there is an issue already open for the device authorisation flow: OAuth 2.0 Device Authorization Grant · Issue #74 · solid/authentication-panel · GitHub

1 Like

Update from my side:

  • I believe the oidc token flow could work for my use case. Specifically by using a browser enabled device to retrieve the token in the first place, then transferring that token to the other device. I believe I read somewhere that the 3 day limit mentioned here was under review, and might be extended, which would be a prerequisite for it to work in the real world.
  • I’m looking into reverse engineering the relevant parts of the node app into something which could run embedded. This is however slow work, as I have a lot of projects in parallel, and this one is unfortunately relatively low on my list of priorities.

I will keep this thread up to date with what I find as I find it. And if I get something working successfully, I’ll publish a guide somewhere to help anybody else who tries going down a similar path.

1 Like

You can now run @inrupt/generate-oidc-token on the command-line, have it redirect you to a browser, login, and have it spit back a JWT to your comman-line. You can then save and use that JWT to login with either solid-node-client or @inrupt/solid-client-authn-node in a bot or command-line. You can get these tokens from either ESS or NSS servers and use them on ESS/NSS/CSS for resources that give access to the WebID you log in as. If you use solid-node-client with NSS, you can also get the token by sending username/pass rather than generating a JWT.

My current info on expiration is that ESS uses a rotatating token and you must currently get a new one every 30 minutes. They have an eventual verified credentials solution but out-of-browser use is not high priority and I would not expect a longer ESS token anytime soon. However, NSS expiration is still about three weeks so you can give your NSS WebID access to your ESS/CSS resources and thereafter login to NSS and access anywhere.

2 Likes

@Sheap I realize this posted is a little date, but I just joined the forum and have been exploring projects in IoT/Wearables and Digital Twins for patients. I’d love to learn more about your latest efforts.

You may also look at the possibility offered by CSS GitHub - RubenVerborgh/solid-hue: Philips Hue module for the Community Solid Server

1 Like

You may be interested to know that the authentication panel is looking at use cases outside of the typical Web application, where a browser and redirects are involved. It is a conversation currently happening, and everybody is welcome to join: GitHub - solid/authentication-panel: GitHub repository for the Solid Authentication Panel. As we progress along, I’ll try to communicate advances here.

1 Like