owncloud / ocis

:atom_symbol: ownCloud Infinite Scale Stack
https://doc.owncloud.com/ocis/next/
Apache License 2.0
1.42k stars 183 forks source link

federated spaces #10065

Open butonic opened 2 months ago

butonic commented 2 months ago

The ownCloud clients have learned the indirection of discovering spaces at the /me/drives endpoint. As it turns out , we can use this mechanism to discover spaces on remote instances.

For now this is a braindump of what I wrote down the last time I thought about this. Eventually, I drift into the Backend For Frontend pattern for oidc web clients because it would make accessing remote instances a lot safer. So here goes...

Currently, the graph of an oCIS instance only lists the spaces of that instance. Following the actively managed space registry ADR we can extend this to spaces on other instances.

While the API currently has a webdav property it lacks a property for the /drives/id endpoint on a remote instance.

When we add that the clients can discover spaces on remote instances. This becomes a federated graph when remote /drives/id endpoints can authenticate users from other IdPs. This federated authentication is covered by openid connect.

Which IdPs should an instance trust? Every IdP that contains a user that was sent an invite. An invite contains an email and when creating the invite the instance can do an OpenID Connect discovery for that email. If there is an idp we add it to the list of trusted IdPs. If not we use the IdP for guest accounts.

In a similar fashion we can discover the oCIS instance that hosts the web ui. We need to add CORS headers so it can make requests to our graph endpoint.

We could host the web ui globally at eg htt s://web.owncloud.com

When it is opened you first enter your email. That will trigger an OpenID Connect discovery and a LibreGraph discovery. Web will authenticate with the idp and fetch the user and drives list from the LibreGraph endpoint.

oCIS as a RP would need to find out which IdPs to use to verify the access token based on the access token, but access tokens might be opaque. Web would have to send the idp as well. AFAICT there is RFC 8693 OAuth 2.0 Token Exchange that could be used by ocis server side to exchange the id token for an access token to impersonate the user / act on behalf of it. The id token could act as a session? Hm. It does look like there is a spec for this, but I don't understand it, yet.

The RP has to authenticate to exchange the id token... How would it get the credentials? Using the dynamic client registration? So not only web, but also ocis server would have to register with the idp? What about the clients?

Interesting read with recommendations for oidc RP: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps-18

Hm the BFF - Backend For Fronted pattern is the most secure, but requires all web request sto go through a server. But it takes web out of the client s we have to register at the idp.

It would turn out web app into a client that can maintain secrets. The backend would store them.

It could even decide how to implement the API between the browser app and the backend. oCIS itself would only expose LibreGraph. (And later maybe CS3). It could also use the same LibreGraph API but with cookies which the backend replaces with an access token. The backend would be a proxy for the Frontend. Backend For Fronted.

https://auth0.com/blog/the-backend-for-frontend-pattern-bff/

Example implementation https://github.com/michaelvl/oidc-oauth2-bff

Hmmm this would also get rid of the cors headers problem, because the web backend does not need to respect them.

We can talk to any ocis instance without them having to tweak any cors headers. We do not need to madd a list of all IdPs the web ui should be allowed to access.

https://handouts.secappdev.org/handouts/2022/philippederyck_securingoauthspa.pdf

And a nice page with sequence diagrams ffor BFF and other patterns: https://docs.abblix.com/docs/openid-connect-flows-explained-simply-from-implicit-flows-to-authorization-code-flows-with-pkce-and-bff

rhafer commented 2 months ago

I know this is just a braindump. But since your posting it in a public issue, I assume you're interested in feedback. So let me try :smiley:

The ownCloud clients have learned the indirection of discovering spaces at the /me/drives endpoint. As it turns out , we can use this mechanism to discover spaces on remote instances.

For now this is a braindump of what I wrote down the last time I thought about this. Eventually, I drift into the Backend For Frontend pattern for oidc web clients because it would make accessing remote instances a lot safer. So here goes...

Currently, the graph of an oCIS instance only lists the spaces of that instance. Following the actively managed space registry ADR we can extend this to spaces on other instances.

Which ADR are you referring to here? Is that already existing? Or is that still tdb?

While the API currently has a webdav property it lacks a property for the /drives/id endpoint on a remote instance.

  • [ ] do we need to prefix the space ID? With an instance id?

Why?

When we add that the clients can discover spaces on remote instances.

What is "that" referring to? The new property referencing a remote /drives/id endpoint, or the space id with and instance id prefix?

This becomes a federated graph when remote /drives/id endpoints can authenticate users from other IdPs. This federated authentication is covered by openid connect.

I guess here you're referring to https://openid.net/specs/openid-federation-1_0.html? (which is still a draft)

Which IdPs should an instance trust? Every IdP that contains a user that was sent an invite. An invite contains an email and when creating the invite the instance can do an OpenID Connect discovery for that email. If there is an idp we add it to the list of trusted IdPs. If not we use the IdP for guest accounts.

I guess I am misunderstanding something here, but why should we automatically trust IDPs based on the fact that we could discover it via a single users email address? Maybe we just want to trust that single user and not anybody else that is able to sign in via the discovered IDP?

In a similar fashion we can discover the oCIS instance that hosts the web ui. We need to add CORS headers so it can make requests to our graph endpoint.

We could host the web ui globally at eg htt s://web.owncloud.com

When it is opened you first enter your email. That will trigger an OpenID Connect discovery and a LibreGraph discovery. Web will authenticate with the idp and fetch the user and drives list from the LibreGraph endpoint.

What are you referring with "LibreGraph discovery" ?

* [x]  Do we need to register web with the idp? How does dynamic registration work? -> https://openid.net/specs/openid-connect-registration-1_0.html fits the bill. It explicitly mentions web apps.

* [ ]  which IdPs actually support it?

  * keycloak, okta, ping, maybe other big ones
  * neither authelia, nor authentic support it

Again, What is "it" referring to. oidc federation or dynamic client registration?

oCIS as a RP would need to find out which IdPs to use to verify the access token based on the access token, but access tokens might be opaque.

I must admit that from here on, you completely lost me. I have a really hard time imagining how all the different pieces you're mentioning are tieing together. (And I have the slight feeling I am not the only one :smiley: )

Web would have to send the idp as well. AFAICT there is RFC 8693 OAuth 2.0 Token Exchange that could be used by ocis server side to exchange the id token for an access token to impersonate the user / act on behalf of it. The id token could act as a session? Hm. It does look like there is a spec for this, but I don't understand it, yet.

The RP has to authenticate to exchange the id token... How would it get the credentials? Using the dynamic client registration? So not only web, but also ocis server would have to register with the idp? What about the clients?

[ .. ]

hodyroff commented 2 months ago

This brings everything on the OIDC level ... doesn't work without it, right? OCM Federation 2.0 then depends on it.

Is this in any way related to the solid protocol? You it be related/using it? Answer: Graph is different from Solid - there could be a proxy/translator with little effort for the missing 5% from graph to solid. OIDC is also used in solid.

For the future we could have syncing between the federated servers with a trashbin, so in case the other side goes away we still have the data available for future usage if required.