indieweb / indieauth

IndieAuth.net website code and IndieAuth Specification
52 stars 7 forks source link

Update client information discovery method #133

Open aaronpk opened 1 month ago

aaronpk commented 1 month ago

The current method of client information discovery (fetching the client_id and parsing the HTML page for microformats) has received a lot of pushback from various people otherwise interested in implementing IndieAuth. This method is also somewhat limited in that it requires defining a Microformats vocabulary for client information, rather than using the existing vocabulary of client information that's defined by RFC 7591 Dynamic Client Registration.

An alternative proposal for client information discovery was proposed in draft-looker-oauth-client-id-scheme, where the AS uses the client ID URL as the base URL and appends a .well-known string in order to find a JSON document with the client metadata. While this approach gets around the HTML/Microformats challenges, it is also not ideal because of the requirement of the .well-known path.

A middle ground (and interestingly, what Solid-OIDC has done), is to instead make the client ID URL be the URL to the metadata document.

So an IndieAuth client such as https://webmention.io would choose a URL to host its client metadata document, for example https://webmention.io/indieauth/client.json. This is the value it would use as the client_id in the OAuth flow.

The AS would see the client_id URL in the authorize request and fetch the URL directly in order to find the client metadata. The metadata values would be the values defined by Dynamic Client Registration, such as redirect_urls, client_name, etc.

martymcguire commented 1 month ago

After some discussion in the #indieweb-dev chat today between aaronpk and myself, some things I'm considering are:

Avoiding a new .well-known feels like a good goal.

Changing the meaning of client_id to be the URL to the metadata document feels reasonable, but I have concerns.

There are also considerations to be made for transition and roll-out.

IndieAuth providers that use client_id per the current spec (or even the previous version, before h(-x)-app microformats were specified) will show users a URL to a JSON document and will most likely make it clickable. I expect that will be a confusing user experience.

(aaronpk mentioned there aren't "that many" IndieAuth providers to update, but I posit that we can't easily know, just as one example, how many people are self-hosting selfauth or how long it will take selfauth to support this client_id change, and how and when users of selfauth would update.)

IndieAuth clients that implement the current spec will lose out on their rich appearance at IndieAuth providers that switch to the new spec. It would be nice to have a migration doc (and maybe a test tool) to help implementers migrate over!

Putting this at the end because I cannot tell if it is constructive, but I noticed that this proposal only mentions .well-known and changing the meaning of client_id. Am I walking into a trap if I ask about adding a link relation from the existing client_id-as-human-readable-page to the client information JSON document?

dshanske commented 1 month ago

There's also the option of the information just being discoverable via the client_url but that means a second fetch.

I think that's what @martymcguire is referring to by the link rel, but confirming.

aaronpk commented 1 month ago

Some quick thoughts on the new proposal:

As far as a migration path goes, that's definitely a bit challenging from the AS perspective. I agree that many AS's will show the full client_id URL and make it clickable, which would not be a good UX if someone clicked it.

Another option for migration is to tie the new client_id behavior to the presence of the (relatively) new indieauth-metadata URL. While it's not perfect, since that has been "out there" for a while, it could at least reduce the chances of the wrong UX. For example:

Adding a link rel from the client home page to the client metadata JSON document doesn't really solve the problem of indieauth server implementers wanting to avoid the HTML parsing step, which is another drawback to the existing spec, and something that I have heard a lot of pushback on from anyone not already 100% bought in to microformats.

dshanske commented 1 month ago

Some quick thoughts on the new proposal:

  • The client_id would be the json document, but the JSON document would contain a client_uri which would be the human-readable home page for the app (this is already defined in the Dynamic Client Registration protocol which defines the vocabulary of this document)
  • If the metadata file is missing or invalid, the AS SHOULD fall back to displaying the domain name of the client_id. (This would provide a reasonable fallback both since it's likely the client developer would have a web page there anyway, but also because the security model of the web is based on domain names so the user would at least see that they are authorizing a client at this domain)

As far as a migration path goes, that's definitely a bit challenging from the AS perspective. I agree that many AS's will show the full client_id URL and make it clickable, which would not be a good UX if someone clicked it.

Another option for migration is to tie the new client_id behavior to the presence of the (relatively) new indieauth-metadata URL. While it's not perfect, since that has been "out there" for a while, it could at least reduce the chances of the wrong UX. For example:

  • Client discovers the user's indieauth server from their profile URL
    • If the client discovers the indieauth-metadata link rel, use the client JSON document as the client ID
    • If the client discovers the authorization_endpoint link rel, use the client home page as before

Adding a link rel from the client home page to the client metadata JSON document doesn't really solve the problem of indieauth server implementers wanting to avoid the HTML parsing step, which is another drawback to the existing spec, and something that I have heard a lot of pushback on from anyone not already 100% bought in to microformats.

Is it microformats if it is a link header and json file? Manifest files do that and do they get complaints?

aaronpk commented 1 month ago

I followed the breadcrumbs from that "Login with Weird" above, and found this discussion on Rauthy:

https://github.com/sebadob/rauthy/discussions/146

That's a good motivator for updating to this JSON document client metadata discovery method.

aaronpk commented 1 month ago

Is it microformats if it is a link header and json file? Manifest files do that and do they get complaints?

The pushback is on parsing HTML. Who are the consumers of manifest files? I suspect that's a very different audience than the consumers of the client metadata we're talking about here.

aaronpk commented 1 month ago

I might just switch this over for a few of my indieauth clients right now. Worst case is someone's IndieAuth server shows them a slightly longer URL than normal, and they see a JSON page if they click it. But other than that everything else about the flow will still work fine, it's not actually a breaking change.

martymcguire commented 1 month ago

Nice! I would likely follow suit if there were, say, a blog post explaining what you changed and why. :}

anderspitman commented 1 month ago

Would this proposal work with clients running on localhost that can't serve the required document? I'm not sure if IndieAuth currently supports that use case anyway.

The current IndieAuth spec says clients SHOULD have a website at the URL in client_id - something intended for a human to read. Will human-readable information be lost with this change?

HTTP content negation could solve this, right? IIRC that's pretty heavily used in the Fediverse to return JSON for machines and HTML for humans.

martymcguire commented 1 month ago

HTTP content negation could solve this, right? IIRC that's pretty heavily used in the Fediverse to return JSON for machines and HTML for humans.

FWIW content negotiation is also often a source of great pain when it comes to development and interop. https://snarfed.org/2023-03-24_49619-2

aaronpk commented 1 month ago

Would this proposal work with clients running on localhost that can't serve the required document? I'm not sure if IndieAuth currently supports that use case anyway.

For clients that are running on localhost (e.g. a mobile app), the assumption is that the mobile app also has a web page about the app which is where the metadata is discovered from.

anderspitman commented 1 month ago

FWIW content negotiation is also often a source of great pain when it comes to development and interop. https://snarfed.org/2023-03-24_49619-2

These are valid concerns. You have to decide if the tradeoffs are worth it. Note that in practice I think a lot of the drawbacks of content negotiation tend to be specific to the data API case (see here). It might not cause as many problems in this situation.

anderspitman commented 1 month ago

For clients that are running on localhost (e.g. a mobile app), the assumption is that the mobile app also has a web page about the app which is where the metadata is discovered from.

That would limit the app to running it's OAuth2 client on a specific port, which might be taken by another app, right?

aaronpk commented 1 month ago

No, there is an exception for exact redirect URI matching for localhost URLs, see:

Alternatively, a mobile app on iOS/Android can use app-claimed HTTPS URLs as the redirect URI, so the localhost issue goes away entirely.

anderspitman commented 1 month ago

I wasn't aware of that; nice!

aaronpk commented 1 month ago

I just implemented this in webmention.io and indielogin.com. Here's the PR that adds support to indielogin.com as a client:

https://github.com/aaronpk/indielogin.com/pull/117/files

aaronpk commented 1 month ago

I updated my IndieAuth server on aaronparecki.com to look for the JSON data as well. It's not open source so I can't link to the changes, but it was super easy.

Since I want to support both for a while, I first try to parse the page as JSON to extract the values. If that fails, I fall back to the existing behavior of parsing the page for Microformats. So it's really not a huge deal to add this new behavior to an IndieAuth server asap.

aaronpk commented 1 month ago

I also started working on a spec that describes this discovery method as an OAuth extension:

https://github.com/aaronpk/draft-parecki-oauth-client-id-metadata-document

https://drafts.aaronpk.com/draft-parecki-oauth-client-id-metadata-document/draft-parecki-oauth-client-id-metadata-document.html

Since this isn't actually anything unique to IndieAuth, other flavors of OAuth might also want to take advantage of this mechanism.

gRegorLove commented 3 weeks ago

I implemented this on https://indiebookclub.biz. Git commit: https://github.com/gRegorLove/indiebookclub/commit/4b685740e9a11ef406fef6cebbed2337dfc11f6f