w3c / wot-profile

Web of Things (WoT) Profile
http://w3c.github.io/wot-profile/
Other
16 stars 8 forks source link

OAuth2 and SSE Notifications #397

Open farshidtz opened 3 years ago

farshidtz commented 3 years ago

Server-Sent Events (SSE) was selected as the protocol to implement a secure notification mechanism; see w3c/wot-discovery#42.

The SSE connections can remain open for a long time. How is this going to work with OAuth2?

A security token (JWT) can be passed as a bearer Authorization header:

  1. Access token with a short and recommended lifespan (5 min):
    • The client must reconnect every 5 minutes
    • Not ideal as it wastes a lot of resources and puts pressure especially on IoT devices
  2. Access token with medium lifespan (few hours):
    • Server1 disconnects the client when it expires
    • Reasonably good option for WiFi connected devices
  3. Access token with a long lifespan (>1 day):
    • Server validates the token internally, but this leaves the client connected until token expiry time is reached.
    • Does not allow early access revocation initiated by auth-server
    • Good for situations where revocation earlier than the token lifespan is not necessary.
  4. Same as above, but with OAuth 2.0 Token Introspection
    • The server checks the token with auth-server periodically and disconnects the client if access is revoked.
    • Very secure
    • Most resource-friendly approach for the clients
    • Depending on the introspection interval, it could put high pressure on server and auth-server.
    • It requires some extra implementation on the server-side.
  5. Refresh token instead of access token: passed to the server and used to request new access tokens on the server-side without interacting with the client.

In all of the above, the client (libraries) should understand the disconnection reason and reconnect with a fresh token only if relevant. Simply ignoring the reason and reconnecting with a fresh token every time may cause endless loops and put huge pressure on auth-server, server, and client if the there is another error.

Any other suggestions?

1 server refers to the directory service.

mmccool commented 3 years ago

We probably need to discuss this in wot-security-best-practices. I have created an issue there to cross-reference this one: https://github.com/w3c/wot-security-best-practices/issues/24

mmccool commented 3 years ago

Suggested resolution: Add a reference to the wot-security-best-practices document

mmccool commented 2 years ago

So... what IS the best practice here? I did some brief digging but did not find anything authoritative.

mmccool commented 2 years ago

Discussion (discovery call 2022.9.5): Farshid looked at this, no good solution. OAuth2 not designed to work with SSE. Best we could do is add informative text, which we can do post-CR. Mark as Resolve by PR.

mmccool commented 1 year ago

Re-reading Farshid's comments, it seems there are 5 options, one of which we should discourage, but others with performance/implementation tradeoffs, and some specific things we should recommend or discourage. At this point we really can't change the discovery doc, but I think we can write this up in the S&P Guidelines doc. We could also probably start with the text from Farshid's comment above - https://github.com/w3c/wot-profile/issues/397

mmccool commented 1 year ago

discussed in Discovery call 2022.09.26:

mmccool commented 1 year ago

Let's keep this issue about security, and raise another issue to discuss whether we should make SSE informative: https://github.com/w3c/wot-discovery/issues/417

mmccool commented 1 year ago

Security TF discussed, felt this was not a discovery topic per se, since it applies to regular Things as well. Probably should be covered elsewhere, perhaps in an SSE Profile, where it makes sense to recommend "best practices".

Rather than closing this issue though I think it should be "moved", e.g. to Profiles.

benfrancis commented 1 year ago

Security TF discussed, felt this was not a discovery topic per se, since it applies to regular Things as well. Probably should be covered elsewhere, perhaps in an SSE Profile, where it makes sense to recommend "best practices". Rather than closing this issue though I think it should be "moved", e.g. to Profiles.

I agree that what (if anything) to mandate or recommend about token expiry and renewal is an important topic in general (see also #347), and SSE is indeed an interesting special case due to the extended duration of open connections and limitations of the client-side API in browsers.

However, note that recommending or mandating best practices in a profile will not also solve this problem for Directory implementations, which may not necessarily conform to a profile. I'm not sure if the Directory Service API is even compatible with the existing profiles (the Directory Service API is very much like a profile for Directories itself, which isn't necessarily consistent with the constraints in the WoT Profiles specification).

So yes, this may be something that can be addressed in profiles for Things in general, but in order to solve this problem for Directories we'd need to either:

Also note that if these really are just recommended "best practices" which apply to all Things (as opposed to mandatory constraints needed to guarantee interoperability between Things/Consumers conforming to a profile), I would suggest they would be better defined in the Thing Description specification, or Security Best Practices document.


For the record, WebThings Gateway currently includes JWTs in a query string for SSE (and WebSocket) connections, since that's basically the only option for the native EventSource (and WebSocket) APIs in web browsers (it's theoretically possible to use cookies, but only via a caching mechanism which is not useful in practice). The tokens also do not currently have an expiry date which is obviously not ideal, so I would like to properly implement token expiry and renewal as part of OAuth2 for the gateway's REST API. I don't really know how to solve that for SSE and WebSockets without making it impossible to implement using the standardised browser APIs.