FEP-d8c2: OAuth 2.0 Profile for the ActivityPub API

I also have never been able to figure out what problem this FEP is supposed to solve. But if I assume that it does solve a problem, then I agree that defining a rigid subset of OAuth2 as a special case for activitypub is misguided.

And then if we assume that at some point C2S APIs implementing any sort of claim-encoding bearer token auth scheme became readily available, the set of claims proposed here doesn’t seem at all adequate. It’s hard to imagine wanting less than to be able to authorize specific activities.

Unfortunately, I don’t have enough time at the moment to familiarize myself with it. But I am absolutely in favor of using a standard server such as https://www.keycloak.org/ for authentication. So anything that conforms to the oauth2 specification and is feasible with keycloack should be ok!

It is NOT ok if an activityPub server takes over parts of the authentication or if auth requests should/must be routed via the activityPub server.

1 Like

Yes, this would be an additional “SHOULD” requirement.

I think Aaron is actually talking about a subset of OAuth 2.0 specifically for ActivityPub, which in standards parlance is a “profile” of OAuth 2.0. Unrelated to actor profiles in ActivityPub.

ActivityPub (Jan 2018) predates RFC 8414 (Jun 2018) by 6 months. It was not “re-implementing part of another existing standard”.

This FEP is an OAuth 2.0 profile for the ActivityPub API. It uses ActivityPub-centric discovery and identification in order to be more useful for ActivityPub developers.

I’m happy to include additional scopes. I’ll try to add read:* scopes for the standard properties of actors (inbox, outbox, followers, following, …) and write:* scopes for the standard activity types defined in ActivityPub. I’ll add a read:all and write:all for the broader scope.

Finally, I’m happy to add a discovery process via RFC 8414, and a client registration mechanism via RFC 7591.

@jenniferplusplus the point is that you can write a client for one server implementing the ActivityPub API, and run it against another server implementing the ActivityPub API, and it just works. OAuth 2.0 has a pretty broad set of possible parameters, so the goal is to sufficiently constrain the parameters such that a client doesn’t need server-specific authentication code.

Whilst RFC 8414 was published by the IETF as a proposed standard in June 2018, the specification of it was in progress for a while before that, with work starting in 2015 on it, with several draft versions: RFC 8414 - OAuth 2.0 Authorization Server Metadata

So the properties were representing something well outside of the scope of ActivityPub, orthogonal to other standards processes.

But looking at these properties today, RFC 8414 would be the more preferable way, given that the properties alone do not allow you to complete authorization / authentication, given the other information that is required in order to complete an OAuth 2.0 flow successfully.

As we’re limiting this proposal to C2S APIs, which it sounds like that’s all this is to cover, then I think we should choose scopes that are much more specific to that purpose, as “read” or “write” is too general, and could mean anything from an OAuth 2.0 Authorization server.

Perhaps a specific prefix to the scopes is required? e.g., activitypub:c2s:read:actor, activitypub:c2s:read:activities, etc.

The other point I’d like to raise here is “how does this proposed standard profile conflict with other OAuth 2.0 usages within the fediverse?”

At present, it’d be difficult I think for Mastodon and Pixelfed to support this FEP, given they use standard OAuth Server libraries (doorkeeper gem and laravel passport respectively), and also the scopes and permissions may conflict.

1 Like

The social web working group started in July 2014.

I am sorry that you’re not happy with the decisions we made when we created ActivityPub, but they were made long ago. This FEP cannot change them.

Can you live with a compromise that recommends both the RFC 8414 discovery process and the ActivityPub properties? Clients and servers can support one or the other or both.

I like the idea of prefixed scopes. I’d say “activitypub:” is fine here. That should probably prevent any conflict.

I started tracking issues from this conversation in codeberg under the “FEP-d8c2” label.

I am sorry that you’re not happy with the decisions we made when we created ActivityPub, but they were made long ago. This FEP cannot change them.

Saying that the decisions we made 10 years ago are set in stone and unchangeable is a bit silly, especially when there is strong evidence and desire by people actually building stuff on these specs to do something different now.

I’m actually surprised to see that ActivityPub defined the two OAuth endpoints in the actor object in the first place. I would argue that was an error on our part since we made the explicit decision to leave authentication/authorization out of scope of the draft.

If I follow the breadcrumb trails, the “Authentication and Authorization” section links to a wiki page here: ActivityPub/Primer/Authentication Authorization - W3C Wiki which says:

To discover the correct endpoint for authorization, clients should use OAuth-Server-Metadata on the host part from the actor’s ID URI.

That sentence was in the original version of that page from 2017, before the final publication of ActivityPub: ActivityPub/Primer/Authentication Authorization - W3C Wiki

So even the ActivityPub spec when it was published had two contradicting ways to find the OAuth server, one of which ignored the “follow your nose” method entirely.

This is all just to say that I think it’s best to ignore the oauthAuthorizationEndpoint and oauthTokenEndpoint properties in the actor profile and do something that makes more sense now.


I don’t like how this allows the application object to be either Application or Service.

As I was told, when designing the vocabulary, the intention was that an Application is a client (an app, a website, etc) and a Service is a server (a bot, a bridge, etc).

I came up with a similar idea for Smithereen, except I’m going to require the type to be specifically Application, and what you get access to would not be C2S ActivityPub, but rather a custom REST API.

This distinction between types is important because of the UX. You would display a Service as a user profile, with posts and followers and the follow button, because it’s like a user but automated. You would display an Application as something resembling an app store listing with name, description, developer contact and maybe a download link. No posts, no following it, no nothing. On the technical side of things, these objects would also go into different database tables.

In a peer to peer network like ActivityPub, every server is also a client, so it is not a useful distinction. For instance actors almost everyone uses the Application type (see here).

However, I agree that following an application actor makes little sense. If it can be followed, Service is probably more appropriate (I proposed a similar rule in Clarify the definitions of Application and Service types · Issue #563 · w3c/activitystreams · GitHub)

I think this might be conflating ActivityPub S2S and C2S? What you said is true for S2S where everything would be a Service. However, the Application vs Service distinction still applies in a C2S context.

So here’s a new IETF I-D almost removes the need for this FEP, which is, myself and @aaronpk have started defining a specification for the OAuth WG that allows the client_id in OAuth 2 to be a URI to a document which describes the client (following current standards around dynamic client registration and various security concerns): OAuth Client ID Metadata Document

It is a draft, we are working on it, so language may change and there’s issues we probably need to address, but this solves needing dynamic client registration for federated systems, without conflating ActivityPub Actors and OAuth Clients / Applications.

The other thing in this is that the Client Identifier Metadata Document can include additional properties outside of those used for dynamic client registration / client metadata, which allows extensibility by others if they so desire (e.g., adding @context to a json-ld context like Solid might require)


Huh? In the sense of underlying protocols like HTTP and TLS and TCP yes of course, but server-to-server interactions are very distinct from client-to-server interactions. You can’t just lump them together like that.