Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth and/or OIDC profile work for Mastodon and/or for AP more generally? #38

Open
bumblefudge opened this issue Dec 5, 2023 · 11 comments

Comments

@bumblefudge
Copy link

bumblefudge commented Dec 5, 2023

No idea if this should be a CG Note or a WG item mentioned in a charter or yadda yadda but regardless of how it gets published, it sounds like it's blocking other work for there not to have even a draft! that there isn't more feedback or PRs on evan's excellent FEP from September!

This was discussed on the Solid/SocialCG joint meeting, and Solid folks invited review here:
solid/solid-oidc#208

The IndieWeb folks were also interested in profiling IndieAuth and its extension TicketAuth:
#35

NB @ThisIsMissEm and @aaronpk and @srosset81

@ThisIsMissEm
Copy link

It's important to note that almost all fediverse software so far has just implemented (parts of) OAuth 2.0, not OIDC, though Mastodon for instance does allow "login via OIDC provider". Basically fediverse software tends to be both the Authenticating Party / Authorization Server and Rely Party in this way.

That is, they're securing access to their APIs using OAuth 2.0 (though there's some interest in moving to OIDC but that's a major breaking change due to having to use JWTs and expiring access tokens)

I've been trying to encourage the adoption of https://datatracker.ietf.org/doc/html/rfc8414

All client's to Mastodon and similar fediverse software are using dynamic client registration, and this is where something like Solid-OIDC's public client identifier documents or OpenID Connect Federation could be incredibly beneficial

@dshanske
Copy link

dshanske commented Dec 5, 2023

Someone like @aaronpk might be able to offer a better explanation than I as the spec editor and someone with more experience in these areas, but speaking as someone who implemented IndieAuth, had never implemented anything OAuth 2.0 prior to that, and has been involved with IndieAuth's evolution since the original W3C recommendation(which caused me to read a lot of OAuth extension documents), it always seems to me that IndieAuth smooths out a lot of rough edges and is a simple solution that can be supported with only minor changes to OAuth libraries.

It eliminates dynamic client registration and switches to only public clients identified by a URL. Again, makes my life easier.

@ThisIsMissEm You note that you want to encourage adopton of RFC8414, the latest living standard for IndieAuth supports it, it just offers an alternate discovery mechanism.

@aaronpk
Copy link
Member

aaronpk commented Dec 5, 2023

OpenID Connect Federation is solving a completely different problem and would not be a good solution here. There are some other similar efforts in the IETF OAuth group to solve this problem of not needing pre-registered clients. Both for things similar to Mastodon's clients (think email and calendar clients), as well as the more bleeding edge communities around Verifiable Credentials and Wallets. As @dshanske mentioned, IndieAuth has also established this pattern for about 10 years now of using a URL as a client identifier to avoid the need for dynamic client registration. In any case I would strongly recommend Mastodon/AP do not define something new here and draw from as much prior art as possible.

@bumblefudge
Copy link
Author

bumblefudge commented Dec 9, 2023

OpenID Connect Federation is solving a completely different problem and would not be a good solution here.

I suddenly realized I'm unclear on what the targeted use-case(s) is/are here. Are we [only] solving for "user of mastodon instance 1 wants to sign into mastodon/AP instance 2 to leave a comment"? Does it matter if servers 1 and 2 are federated or known to one another at the time? Are there other user stories the Profile (or a separate Profile) would want to support, like a "Fediverse" server being able to authenticate a bridge.gy instance or an unconventional AP Actor or any other kind of thing? Are there clients not identifiable by a URL that some might want to support?

(In any case it seems avoiding Dynamic Client Registration is a self-evident design goal, but other details and pros/cons might best be assessed against targeted use-cases!)

@gobengo
Copy link

gobengo commented Dec 9, 2023

  • @evanp's FEP-d8c2 here is relevant and, upon skim, generally aligned with the way I'd expect someone to try 'oauth 2.0' against the oauth... affordances in the AP spec. https://codeberg.org/fediverse/fep/src/branch/main/fep/d8c2/fep-d8c2.md#fep-d8c2-oauth-2-0-profile-for-the-activitypub-api

  • in SocialWG in 2015/2016, I was implementing an OpenID Connect provider (using pyoidc) at the time (to power accounts.livefyre.com), and I was quite happy with it at the time for providing a much more specificly implementable set of behaviors than the 'oauth 2.0' framework, while still being an implementation of that framework, and iirc I suggested at the time maybe we should encourage OIDC for Dynamic Client Registration, etc.
    I believe there was a lack of consensus in the group both whether to make normative language around auth as well as, if we could agree on that, what would make sense to recommend. On top of that, to go to WG, i recall that quite a few normative references had to change to informative because, for example, there weren't necessarily good 'final' TR/RFCs of some of this stuff for the ActivityPub TR to rely on. i.e. we needed to go make auth standards that would be official enough to be referred to from W3C TRs (or FEPs) in the future.

  • +1 OIDC Dynamic Client Registration and e.g. I also like how it specifies encoding the OAuth 2.0 Authorization Request in JSON (because the application/x-www-form-urlencoded encoding is less expressive and tedious to translate between as your auth{n,z} requests get more complex)

  • In general I'd like for there to be well defined profiles for going through this process and just using a cryptographic public key as the oauth client id. 'Client Registration' for a noncryptographic client id shouldn't be required for everyone. Not everyone needs a database of metadata about clients, and in fact it is an operational expense and data liability that many would probably rather not take on. (I would rather not)

    • I would also like to put on people's radars OAuth 3 GNAP which encourages cryptographic authentication for clients as well. I encourage anyone to sketch a GNAP profile for ActivityPub. But I also think it's important to have OAuth2-related profiles that build upon the already-in-TR oauth vocabulary items defined by AP. Since this issue is mostly about OIDC/OAuth2, i encourage GNAPPy discussion elsewhere to not derail the thread.
  • I also strongly recommend folks become familiar with 'Self-Issued OpenID Connect Providers' aka SIOP, which is one of the things about OIDC I liked so much from 2015-2016, but felt abandoned for awhile until getting more adoption recently e.g. by the European Union

    • https://openid.net/specs/openid-connect-core-1_0.html#SelfIssued
    • imho more ActivityPub apps, whether they are clients or the web-ui served by 'instances', should have affordances for an end-user bringing their own authentication process to the instance, instead of assuming that your 'identity server' and your 'activitypub server' are always (or even should be) operated by the same folks. My preference is to have a social web where I bring my own identifier to any number of ActivityPub Clients and Servers (which do not try to be my identifier-provider as well), and thus I have both 'single sign on' and 'portable identity' and whatnot by virtue of my ActivityPub Actor Identifier not being controlled by the provider of my inbox/outbox servers (and I can switch/compose providers whenever I want sans lock in).
  • Actor Identifier Resolver, Authorization Server, ActivityPub Inbox Server, and ActivityPub Outbox Server, should all be able to be provided by different domains and service providers, and I should be able to bring my own identifier to all of them, whether that identifier is rooted in my own domain name (e.g. https://bengo.is/actor.json), from which you can find an Actor and related oauthAuthorizationEndpoint, but also could be rooted in my own cryptographic identity (e.g. did:key:z6MkfbsERaJ7rtJQWMWtYMxNED56bhQMgrNu8CRdUjB5LfRp or perhaps a dweb: URL). One of the benefits of the latter over the former is that claims by that identity may be verifiable even if you are lacking connectivity to resolve a domain name via DNS or ability to connect to any IP addresses you find via DNS, and it removes the Actor Identifier Service and the Authorization Service as semitrusted intermediaries that could act maliciously without accountability (e.g. not allow certain folks to resolve your identifier to an Actor Object without you knowing)

@nightpool
Copy link

nightpool commented Dec 10, 2023 via email

@bumblefudge
Copy link
Author

bumblefudge commented Dec 12, 2023

In case Codeberg goes down again, here is Evan's FEP on valid client_id values and how to interpret them:

Client identifier: ActivityPub provides a rich vocabulary for describing objects in the social space. Each object in the ActivityPub world has a unique https: URI, which must be dereferenceable to a JSON-LD document describing the object. / This allows a distributed description of ActivityPub API clients that doesn't require out-of-band registration. / Objects dereferenced at the [https: URI value if one is provided as client identifier??] SHOULD be of type Application or Service. They MUST have an id property with the same value as the client_id parameter. They MUST have a redirectURI property with the redirect URI for the client (see Context document below). / Clients SHOULD provide metadata to help users make authorization decisions, including:

  • nameMap or name: The name of the client software.
  • icon: An Image object with the icon for the client software.
  • summaryMap or summary: A description of the application or service.
  • attributedTo: The name, id, icon and summary properties of the actor responsible for the client software.

Src: https://codeberg.org/fediverse/fep/src/branch/main/fep/d8c2/fep-d8c2.md#client-identifier

I think Ben's comments about composability of layers (i.e., moving away from the "custodial" assumption of each inbox/outbox server also being a keyserver and also being an IdP for all authZ purposes) is an important medium-term goal to keep in view, particularly if we want to support many form-factors (bridges to other p2p networks, 1-user-servers, publishing systems that just host micro-AP services "as a comments section/social overlay", etc).

I'm guessing some of these latter use-cases might well be served by a "just hang a shingle" approach (each client required to maintain a little metadata) but I'm not sure why it's either/or... aren't they orthogonal, @nightpool ? Just as, in the wake of a CVE, you might want to filter your own logs for a given client version or build, wouldn't you also want, in the wake of a defederation or moderation crisis, to filter the same logs for a specific IdP? I'm probably missing something, but for lack of the kind of user-story docs I'd usually consult to figure this stuff out, I'm hassling experts 😅

@gobengo
Copy link

gobengo commented Dec 12, 2023

Thinking more about my experience as a Mastodon server admin, I think I'm a
much bigger fan of the "public client URI" (including Application actor,
which iirc FEP d8c2 mentions...? Codeberg is down right now, so I can't
easily reference it) flow that IndieAuth pioneered, compared to an oidc
dynamic client registration approach (which is pretty similar to what
Mastodon currently uses)

I agree a public client URI is a good client id. A way of doing that while also using a cryptographic commitment in the URI is to use a did:key URI, or another did: URI that can be resolved to a did document (a description of how to verify claims authored by the subject of the identifier) without using the network (e.g. did:jwk).

that IndieAuth pioneered

Compared to the https URLs that IndieAuth requires, other kinds of URIs can be strictly more useful in certain contexts, e.g. because they dont' require the network to resolve and because they don't reveal more information about the requester than is necessary to authorize the request. (https://en.wikipedia.org/wiki/Privacy_by_design)

It's just much easier to tie a client to a
"real-world" identity that way, which is important for security and trust
purposes.

There is a tension between what's best for the 'security and trust' of the server operator and the 'security and trust' for the client operator and/or end-user. Yes, operating a server is easier if you can surveil the "real-world" identity of every single request. But we shouldn't bake that as a requirement into the protocol IMHO, we should have affordances for authorizing requests that can be selected on a case-by-case basis, espeically when they have (potentially physical) operational security implementations for end-users. End-users are in the best position to decide whether to reveal their real-world identity, not server operators or protocol designers.

Server operators should be able to make decisions about what authorization proofs they accept, but end-users should be able to freely move between operators that can differentiate themselves based on the auth proofs they accept.
Only accepting proofs from client IDs that start with 'https:' may be cheaper to operate, but it also might limit the addressable audience of your service.

The approach of using a cryptographic commitment as a client identifier predates IndieAuth and is how OAuth 1.0 worked. https://oauth.net/core/1.0/#anchor9 (and, as I mentioned, how what some have called 'OAuth 3', GNAP, works).

I'm not saying using an HTTPS URL is bad, but I do think constraining the allowed URI schemes for a Client ID to http-only is not a good idea for a general purpose solution. (especially because DIDs are really useful for identifiers and designed for this type of thing, which is why they are being adopted by things like EBSI.eu or in education by imsglobal.org.

I do think the HTTP-URL-only requirement in IndieAuth is conveniently useful for any company that already has Authorization-as-a-service products that speak HTTP. I can understand why representatives of such companies would benefit from the requirement, but I think we also owe it to end-users to provide other affordances as well.

@bumblefudge
Copy link
Author

It's also worth noting that A profile doesn't need to be THE profile-- it might help to scope this more conservatively as a "best current practice" kind of exercise (it's non-normative after all! could even be a FEP instead of a CG Note!). A more conservative profile could be optimized for, e.g., mastodon- and mastodon-like servers that are heavily federated and have more DDoS/bandwidth concerns, another could be optimized for more inclusive/wider federation (with e.g. dynamic registration and non-HTTP clientIds may be necessary to support federation with more kinds of servers)... as long as a plurality of profiles and a lifecycle is a design goal of the profiling process, they can be more opinionated or optimized, right? they're "just" profiles?

@ThisIsMissEm
Copy link

Lots of interesting and very similar ideas exist in Bluesky's / ATProto's OAuth proposal: https://github.com/bluesky-social/proposals/blob/main/0004-oauth/README.md

@ThisIsMissEm
Copy link

Okay, some updates, since I'm updating ALL THE ISSUES atm (if you're involved in Mastodon, you'll know what I mean probably).

Since this issue was created, I have started working on an IETF I-D with @aaronpk to solve the many to many client to authorization server problem that is present within federated and decentralised social media. It's called Client ID Metadata Documents.

It has been adopted by:

We may write up a OAuth Profile for Mastodon (it can't hurt to fully document it), however, I believe the focus should instead be on the following:

  • defining an OAuth Profile that uses modern OAuth/OIDC standards and Client ID Metadata Documents for ActivityPub C2S (this primarily resolves around using the OAuth Authorization Server Metadata to discover supported scopes and configuration, and declaring a set of scopes for ActivityPub C2S, all prefixed with activitypub: as to not conflict with existing OAuth / OIDC implementations across the fediverse).
  • defining a generic client API for the current uses cases where C2S is not appropriate (e.g., things like feeds, collection filtering, search, media uploads, discovery features, etc), I imagine this to be something like a ActivityPub Client API.

I do NOT think the Mastodon API should be the defacto API of the Fediverse.

We SHOULD rely on modern OAuth / OIDC standards when designing the OAuth Profile for ActivityPub C2S / Client API. That means things like RFC 8414, etc, instead of doing things in our own unique way (see w3c/activitypub#427 ), and additionally design with OAuth 2.1 and OAuth 2.0 Security Best Current Practices in mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants