w3c-fedid / FedCM

A privacy preserving identity exchange Web API
https://w3c-fedid.github.io/FedCM/
Other
369 stars 72 forks source link

Use of .well-known folder location #160

Closed dj2 closed 4 months ago

dj2 commented 2 years ago

FedCM API currently uses the .well-known/fedcm folder in order to find the endpoint configuration. The .well-known folder is specified as only existing in the root folder (e.g. https://idp.example.com/.well-known/fedcm).

The question has come up, is that acceptable for IDPs?

  1. Do IDPs have multiple IDPs on the same root with different paths? (e.g corp.example.com/idp1, corp.example.com/idp2)
  2. Is it reasonable to assume that an IDP can put a .well-known/fedcm folder in the root of their domain?
timcappalli commented 2 years ago

Putting .well-known deeper in the path is quite common for multi-tenancy. For example, we use:

https://login.microsoftonline.com/microsoft.com/v2.0/.well-known/openid-configuration https://login.microsoftonline.com/capptoso.com/v2.0/.well-known/openid-configuration

https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig

Using path components enables supporting multiple issuers per host. This is required in some multi-tenant hosting configurations. This use of .well-known is for supporting multiple issuers per host; unlike its use in RFC 5785 [RFC5785], it does not provide general information about the host.

dj2 commented 2 years ago

Oh, interesting. We've been looking around for docs and everything we found pointed to it being at the root. So, having prior art for this is good to know.

samuelgoto commented 2 years ago

Oh, that is indeed good to know. @timcappalli do you know if that's a valid construction for .well-known? When we first read the spec, it seemed like an invalid use. Any chance you'd know?

timcappalli commented 2 years ago

In my experience, protocols that leverage well-known define the behavior in the protocol spec.

Some examples:

bc-pi commented 2 years ago

I'm pretty sure that an author of RFCs 8615 & 5785 would say that it is not a valid construction for .well-known. Push-back from the IESG on the subject was how https://datatracker.ietf.org/doc/html/rfc8414 ended up with a different construction for OAuth than OIDC, which is unfortunate. Though I don't think it's used much in practice. I'm not trying to say it has to be one way or the other. But there are some folks out there that would argue that per-directory well-known locations are bad.

domenic commented 2 years ago

I would definitely recommend picking a less-misleading prefix; well-known URLs are a specific thing, origin-wide, and reusing their prefix for something that doesn't work like that would be really confusing for web developers. It's a shame some other API has done that, but we should not follow their bad example.

Of course it'd be ideal if you could have one IDP per origin. But if that's not an acceptable constraint, then that basically means well-known is not appropriate. Probably then instead of supplying origins and appending /.well-known/fedcm, you should just have people supply URLs of config files.

bmayd commented 2 years ago

I agree with using something other than well-known; as the RFC 8615 introduction indicates: “...for data or services related to the origin overall...”, the intent is for it to be used for origin-general metadata and applying it to what’s described in this use-case seems to go against that intent. Seems like there should be something FedCM specific, perhaps referred to in a well-known resource to make it discoverable.

samuelgoto commented 2 years ago

I would definitely recommend picking a less-misleading prefix; well-known URLs are a specific thing, origin-wide, and reusing their prefix for something that doesn't work like that would be really confusing for web developers. It's a shame some other API has done that, but we should not follow their bad example.

So it seems that our use of .well-known isn't exactly what it was intended for.

Seems like there should be something FedCM specific,

+1, that seems like a good starting point.

I'll start by using something specific, like, fedcm.json (as opposed to .well-known/fedcm) and see how far that takes me.

Updating the spec here.

samuelgoto commented 2 years ago

I'm going to tentatively resolve this issue here with the following PR that has been merged:

https://github.com/fedidcg/FedCM/pull/175

Feel free re-open if you disagree with the resolution (and/or have a better suggestion/recommendation).

Thanks all!

dickhardt commented 2 years ago

Having been involved in the early days of .well-known, it was intended as a discovery path for IdPs -- so it is confusing why it was concluded it was misleading.

As an IdP -- yet another metadata directory / file in a different place is a security headache and something that can easily be gotten wrong. @samuelgoto

cbiesinger commented 2 years ago

I missed that comment -- @dickhardt , the reason to switch away from well-known is that some IdPs need to put their manifest into a subfolder. And well-known in a subfolder does not make sense.

However, you should feel free to still put your file into well-known for your IDP, you just have to specify "https://foo.com/.well-known/" as the provider.

dickhardt commented 2 years ago

@cbiesinger assuming by provider, you also mean the iss claim in an ID Token, specifying anything other than https://foo.com is impractical. Existing code does discovery using the .well-known standard, and existing ID Tokens will already have https://foo.com as the IdP issuer.

Microsoft already puts .well-known into a subfolder -- their IdP has a subdirectory as the iss claim -- so I'm confused why using .well-known does not work when it is working fine for discovery for OIDC

cbiesinger commented 2 years ago

I did not mean anything in the ID token, I meant the FedCM API call, ie. navigator.credentials.get({provider: "https://foo.com/.well-known/"})

well-known is specified to be in the root (https://www.rfc-editor.org/rfc/rfc8615.html#section-3), so we did not want to perpetuate misuse like Microsoft's here.

Adding @domenic in case he has anything to add.

dickhardt commented 2 years ago

For RPs, the provider and the issuer are equivalent. I would find using navigator.credentials.get({provider: "https://foo.com/.well-known/"}) confusing myself.

While I agree that Microsoft's use is a misuse -- they industry has accepted it for OP discovery.

All the other IdPs have a 'normal' .well-known discovery. Is there another IdP that requires resolution to a directory rather than a hostname?

Also, @cbiesinger can we re-open this issue?

samuelgoto commented 2 years ago

For RPs, the provider and the issuer are equivalent. I would find using navigator.credentials.get({provider: "https://foo.com/.well-known/"}) confusing myself.

This isn't how we are expecting it to work. You'd call:

navigator.credentials.get(federated: {providers: [{url: "https://foo.com/subfolder"}]})

Which the browser would fetch two files:

You don't need to use a subfolder, and we can probably make the API simpler/cleaner when you don't and use only your .well-known configuration file.

dickhardt commented 2 years ago

Above @cbiesinger is suggesting that I would need to have the provider URI include the .well-known path if I wanted to put my FedCM files there.

However, you should feel free to still put your file into well-known for your IDP, you just have to specify "https://foo.com/.well-known/" as the provider.

From a SecOps point of view, I want to minimize how many places I have critical metadata. Having it all in .well-known is great.

So to clarify, an RP can just call navigator.credentials.get(federated: {providers: [{url: "https://foo.com"}]})

And I can have my metadata at https://foo.com/.well-known/fedcm

Correct?

I see that you are still including the .json extension -- I'll open a new issue for this topic w3c-fedid/FedCM#276

cbiesinger commented 4 months ago

We have converged on requiring a well-known file in the root of the eTLD+1 for privacy reasons. We are discussing allowing specifying this via DNS instead (#580) but we can't relax the requirement to specify this once per eTLD+1.