kratos icon indicating copy to clipboard operation
kratos copied to clipboard

Support multi-domain environments

Open aeneasr opened this issue 4 years ago • 15 comments

Is your feature request related to a problem? Please describe.

It is currently not possible to set up ORY Kratos' Login Session Cookie in such a way that it is valid for multiple domains at once (e.g. foo.com, bar.com). The user will have to log in on both domains individually.

Describe the solution you'd like

There should be a way to get this working.

Additional context

This works as demonstrated for google.com and youtube.com where sessions are synchronized. They apparenlty use HTTP redirects to get it working with query parameters that include the session.

aeneasr avatar Aug 24 '20 08:08 aeneasr

So the end goal would be SSO? Isn’t Hydra the tool for that? I think Google and YouTube also use OIDC.

Raou1d avatar Feb 03 '21 23:02 Raou1d

No they do not! Yes SSO is the end goal. Hydra is for federation

aeneasr avatar Feb 04 '21 07:02 aeneasr

Could this be achieved by sending a Set-Cookie header to the callback url, allowing the OAuth consumer to create a cookie for the origin domain?

dan2kx avatar Sep 17 '21 16:09 dan2kx

What is the complexity of this? Does it require an architecture change?

daattaa avatar Nov 08 '21 21:11 daattaa

Yes this is quite complex! It would first require a design document that explains a secure flow for setting cookies across multiple domains. Probably looking at how google does it for youtube?

aeneasr avatar Nov 09 '21 07:11 aeneasr

@aeneasr Just a random crazy idea: is it worth to consider Trust Tokens as an alternative to a chain of redirects or it's too optimistic taking into account those are not wide-spread?

Serhii-the-Dev avatar Nov 09 '21 20:11 Serhii-the-Dev

What are trust tokens? 😅

aeneasr avatar Nov 09 '21 21:11 aeneasr

Ah you mean https://web.dev/trust-tokens/?

aeneasr avatar Nov 09 '21 22:11 aeneasr

@aeneasr yes, but nevermind, it was a stupid idea...I did a small research and AFAIK now the Trust Tokens are designated for identification and not authentication.

Serhii-the-Dev avatar Nov 13 '21 19:11 Serhii-the-Dev

I think this will be very hard to pull off because many approaches to this are also used by ads industry for tracking users and browsers are actively trying to protect users. Safari is a prime example of this.

mitar avatar Dec 08 '21 18:12 mitar

I am probably repeating the additional context from the OP in so many more words, but wanted to share my thoughts incase they are useful.

I am vaguely familiar with an older strategy where foo.com redirects browser to a page on bar.com that sets the same cookie data just on its domain. The cookie data is passed in the sub-path or request parameters in some way:

  • If cookie material is safe enough, foo.com can send it via request parameter to a page on bar.com. That page validates the request parameter looks like normal cookie data's format, then returns instruction to browser to set cookie data to those request parameter's contents when responding with the bar.com page.

  • If cookie material isn't public, shared data store is an option. foo.com stores it under a key/id in a place where both foo.com and bar.com backends can reach, then foo.com transmits that key/id in request parameters like above. This time bar.com does some validation that the request parameter looks like a valid key/id, then looks up cookie data to set from shared store and return instruction to browser to set it.

  • If cookie material isn't public, and shared data store is not an option, server->server is an option. foo.com backend first makes a call to bar.com telling it an id to store cookie material under somewhere it can (short term in-memory works) and waits for bar.com to respond before foo.com then redirects browser to bar.com with that same id given out of band. Now bar.com validates that it looks like a valid key/id, then looks up cookie data to set from its store (which was pre-populated out of band) and returns instruction to browser to set it.

For setting on login or something for future use, consider bar.com cookie setting redirect could redirect back to foo.com when done.

Similarly, if there are more than 2 domains involved, bar.com page could continue the same pattern to baz..com which could continue the same pattern yet again to fum.com.

User experience is not that great, but it does work.

https://jisajournal.springeropen.com/articles/10.1186/1869-0238-4-13#Sec2 describes the first way in more detail:

Many variants of the same folk protocol exist where one or more Web sites use another site as a cookie manager (CM): to set a cookie the Web sites redirect the browser to the manager passing the necessary data as a request parameter; the manager sets the cookie when redirecting back to the requesting page. (At this point the browser associates the cookie with the cookie manager’s host or domain.) To receive a cookie, they do a redirect to the CM who receives the cookie from the browser and performs another redirect (back) passing the data, also as a request parameter. While this is a working solution, it requires multiple redirects (two per request) increasing communication overhead and design complexity. [...]

And then the third in more as well:

Callaghan et al. proposed a proxy-based solution that allows non-cooperating Web servers to communicate using standard HTTP cookies [16]. A forwarding proxy is configured to treat a group of Web sites as one; it captures cookies from passing HTTP traffic and makes them available to communicating browsers and servers by inserting Cookie and Set-Cookie HTTP headers as needed. In a more complex configuration, Callaghan et al. set up a “cookie manager” URL that the proxy itself responds to. Cross-site cookies are associated in the browser with that URL. When a browser sends a request to a participating server, the proxy initiates a cookie transfer from the “cookie manager” (CM) as follows:

  1. Redirect to the CM keeping the target URL as a request parameter.

  2. Intercept the request as the CM, receive all cookies, and redirect to the target URL encoding the cookies as request parameters.

  3. Intercept the request again, convert the request parameters into cookies using the Set-Cookie header, and redirect to the target URL again.

After this the cookies will be associated with the target host as well as the CM itself. The drawback of this solution (in addition to multiple redirects) is that it tightly couples components in the user’s domain (the forwarding proxy) and the application’s domain (the Web servers). Such coupling may be achieved and maintained in a controlled environment, for example, within an enterprise, but cannot be easily replicated in other settings. Callaghan et al.’s approach was driven by constraints imposed by the same origin policy. [...]

r4j4h avatar Dec 21 '21 03:12 r4j4h

Thank you! This is indeed very helpful!

A major challenge with this model is that we need to ensure that the cookie is bound to the same client. A simple example may be as follows:

  1. Eve (evil) signs in to foo.com and receives the redirect to bar.com but does not execute it (because of potential token replay defense)
  2. Eve (evil) sends link bar.com?cookie=abcd to Alice (good)
  3. Alice (good) clicks link or executes it (e.g. email with an image)
  4. Alice is now signed in as Eve even though she is not Eve

Depending on your threat model this might sound like not a problem (why would eve try to sign in alice). However, it is an attack surface in certain scenarios that needs to be considered.

In order to ensure this methodology is secure, we need to follow some of OAuth2's playbook:

  1. Ensure replay is not possible
  2. Ensure intended audience matches
  3. Ensure TTL is short and long enough

Maybe it would even make sense to embed a kind-of-hidden (aka no user interaction required) OAuth2 dance to support this use case?

aeneasr avatar Jan 02 '22 09:01 aeneasr

We were thinking about building our own "hidden OAuth2 dance"... We've come to the conclusion that we don't know enough about security to do so safely. However if Ory builds this into Kratos natively, we would use it.

What do you think of the approach of using Kratos for our main domain, and then using Hydra to delegate OAuth2 access for other "whitelabeled" domains running the same product? This would come with overhead on building our API implementation (having to support both Hydra and Kratos auth flows, depending on the user's domain), but we believe it would be possible. Can you think of any security downside?

sebmellen avatar Mar 23 '22 21:03 sebmellen

It's incredible work you guys are doing here. Internally supported multi-domain cookies would save a lot of people from hacks that aim to achieve what google does in their dance.

I think I read somewhere that they use 0px images to invoke the other domains, ergo set the cookies. Never got to verify that piece of info though. Keep up the good work.

dystopiandev avatar May 19 '22 19:05 dystopiandev

Hey @dystopiandev, I know this is an old issue, but just wanted to share this as it might be helpful for OP.

The 1px gif was as far as I remember was (or probably still is) used by Stack Exchange so they can log you into all of their domains, you can read more here: https://meta.stackexchange.com/a/309823. The problem with this is that most browsers don't allow 3rd-party cookies anymore (for privacy reasons), so Google achieves it differently.

If you log in anywhere to your Google account (e.g. I did it from the main page), you're sent to accounts.google.com where the login form is. Then - after successful authentication -, you're also sent to YouTube with a simple 302 redirect, like this: image The URL has a few request parameters, one of them seems to be a token so YouTube can check with the IdP (Google) if it can create a session for you. The redirect is required as the only way to set a cookie for a different domain is if the browser has a page on that domain open. Then you're redirected to the original page you initiated the login from, obviously you can't really see this (except in the network tab) as it happens very quickly.

So I think what OP asks can be implemented this way.

Rodolffo avatar Aug 22 '22 11:08 Rodolffo

Just wanted to let you know that Ory Kratos now has a native integration with Ory Hydra (works out of the box on https://console.ory.sh) which basically allows multi-domain environments by using SSO with OpenID Connect.

This doesn't really solve the issue here. We will introduce multi-cname support in the cloud system which uses some wrappers to make it work with cloudflare.

In the end, I'm not sure if it really makes sense to support the use case Google has laid out. This works well with one or two sites, but does not scale to 10 or 15 sites as you would be stuck in redirects for a while as a user.

aeneasr avatar Oct 28 '22 16:10 aeneasr

Having given this more thought we are convinced that for multi-domain and multi-brand environments, OIDC is the way to go to ensure smooth SSO. All other approaches are not really scalable due to e.g. number of redirects as well as other issues (cross-site logout for example). Therefore we’re closing this as resolved :)

aeneasr avatar Nov 01 '22 12:11 aeneasr

Just wanted to let you know that Ory Kratos now has a native integration with Ory Hydra (works out of the box on https://console.ory.sh) which basically allows multi-domain environments by using SSO with OpenID Connect.

Hey @aeneasr, congrats to the 2.0 hydra release! Is there any documentation on how to configure hydra to use kratos as identity provider?

davidspiess avatar Nov 04 '22 19:11 davidspiess

Thanks

lapnd avatar Jun 20 '23 13:06 lapnd

Having given this more thought we are convinced that for multi-domain and multi-brand environments, OIDC is the way to go to ensure smooth SSO. All other approaches are not really scalable due to e.g. number of redirects as well as other issues (cross-site logout for example). Therefore we’re closing this as resolved :)

Can multi domain cookies be implemented? For example, if Kratos runs on both api.a.com and api.b.com, I would like to configure the cookie domain name as a.com when logging in through api.a.com, and b.com when logging in through api.b.com.

rdp-studio avatar Jul 10 '23 14:07 rdp-studio

Having given this more thought we are convinced that for multi-domain and multi-brand environments, OIDC is the way to go to ensure smooth SSO. All other approaches are not really scalable due to e.g. number of redirects as well as other issues (cross-site logout for example). Therefore we’re closing this as resolved :)

Can multi domain cookies be implemented? For example, if Kratos runs on both api.a.com and api.b.com, I would like to configure the cookie domain name as a.com when logging in through api.a.com, and b.com when logging in through api.b.com.

If you need to share accounts between those two domains, the easiest way IMHO would be to have 2 Kratos instances running for each domain separately pointed to a single database.

Serhii-the-Dev avatar Jul 10 '23 15:07 Serhii-the-Dev

Having given this more thought we are convinced that for multi-domain and multi-brand environments, OIDC is the way to go to ensure smooth SSO. All other approaches are not really scalable due to e.g. number of redirects as well as other issues (cross-site logout for example). Therefore we’re closing this as resolved :)

Can multi domain cookies be implemented? For example, if Kratos runs on both api.a.com and api.b.com, I would like to configure the cookie domain name as a.com when logging in through api.a.com, and b.com when logging in through api.b.com.

If you need to share accounts between those two domains, the easiest way IMHO would be to have 2 Kratos instances running for each domain separately pointed to a single database.

Thank you, I will give it a try. I also want to manually implement the initial idea of this issue, 302 redirect to configure cookies.

rdp-studio avatar Jul 10 '23 18:07 rdp-studio

@rdp-studio it doesn't seems to me you need a redirect, your case is covered in the Multi-domain cookies documentation. All you need to do is to configure Kratos instance hosted on api.a.com to set session cookie to a.com, and the same thing for the b.com accordingly. I had a similar approach for a multi-tenant application, however in our environment all the cookies are set for api.tenant.com as Kratos seats behind a reverse proxy on the API domain, while a web server is hosted on tenant.com. We are also using Oathkeeper to authorize requests to the API basing on the session cookie mutating the credentials into JWTs which are consumed by those API services.

Serhii-the-Dev avatar Jul 12 '23 13:07 Serhii-the-Dev

Yes, I do, but I want to be able to share sessions (that is, SSO) across multiple domains at the same time, so I proposed in my previous message to set up cookies via redirect (and I've implemented it, It works well).

---Original--- From: "Serhii @.> Date: Wed, Jul 12, 2023 21:00 PM To: @.>; Cc: @.@.>; Subject: Re: [ory/kratos] Support multi-domain environments (#662)

@rdp-studio it doesn't seems to me you need a redirect, your case is covered in the Multi-domain cookies documentation. All you need to do is to configure Kratos instance hosted on api.a.com to set session cookie to a.com, and the same thing for the b.com accordingly.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

rdp-studio avatar Jul 12 '23 13:07 rdp-studio

so I proposed in my previous message to set up cookies via redirect (and I've implemented it, It works well).

@rdp-studio this is neat, could you share your implementation? This solves a lot of pain.

mohamed--abdel-maksoud avatar Oct 31 '23 18:10 mohamed--abdel-maksoud