FEP-d556: Server-Level Actor Discovery Using WebFinger


This is a discussion thread for the proposed FEP-d556: Server-Level Actor Discovery Using WebFinger.
Please use this thread to discuss the proposed FEP and any potential problems
or improvements that can be addressed.


Server-level ActivityPub actors support server-wide functionality rather than representing a user or the software equivalent (sometimes called a bot). This proposal describes how to discover a server-level actor’s URI using WebFinger.

I’m not sure about this FEP for the same reason i’m not sure about the other FEP. I do agree that WebFinger is generally better than NodeInfo for this, although NodeInfo does still have an advantage in that it is a “service-level” spec, just like the “service” actor. So it would make sense to stick information about it under NodeInfo… or perhaps Host Meta? Perhaps both?

Really, the big issue is that we still haven’t defined what this actor is or what it should do. It still feels like putting the cart before the horse. I know it’s usually got something to do with the bootstrapping issue for cases where signed fetches are required (AUTHORIZED_FETCH / secure mode / etc). But the exact purpose should be specified.

With regards to Webfinger being used against the prefix, I think this can generally work, but it has some issues:

  • How do you determine what the prefix is? I know people generally assume it is equivalent to the origin / FQDN, but it might not be. It might include a subpath.
  • Putting aside the exact value of the link relation… is this meant to be a link related to every single actor/user? In which case, it should also be included on your run-of-the-mill resource queries too, right?

Aside from that, I would probably not use the language around “fake Mastodon account identifier”, as it’s a typical acct: URI and there’s nothing particularly “fake” about it.

1 Like

Service [ActivityPubService] is the W3C recommended type for this kind of resource rather than Application [ActivityPubApp].
Activity Streams/Primer/Service type - W3C Wiki

Information presented in Primer is not a W3C recommendation, it is just an opinion of a community member.

See the main page of W3C wiki:

Pages here have no formal status but may have WikiConsensus. Questions & answers here may be misleading, or just plain wrong. Or, they may be useful. You are welcome to add, fix, develop and rearrange topics.

In practice, most Fediverse servers use Application type. Examples:

  • Mastodon: https://mastodon.social/actor
  • Lemmy: https://lemmy.ml/
  • Pleroma: https://blob.cat/internal/fetch
  • Wordpress: https://event-federation.eu/wp-json/activitypub/1.0/application
  • Friendica: https://venera.social/
  • PeerTube: https://tilvids.com/accounts/peertube
  • PixelFed: https://pixelfed.social/i/actor

I’ll tweak the wording a bit. I agree it gives the wrong impression although the opinion in the Primer is from an author of the AP and AS2 Recommendations.

Are you talking about an Actor type rather than a WebFinger rel URI? If so, that’s a different topic. This FEP doesn’t require any specific type for instance-level actors.

However, even for actor types, I’d be interested in a reference to the rationale for using Application over Service for instance-level actors so I can compare it to @eprodrom’s suggested usage of those AS2 types.

regarding this: i think both using as:Application and as:Service as rel values is misguided. it would be better to define an entirely new link relation with the semantics of whatever you want the “instance actor” to be. for example, we could say https://w3id.org/fep/ceee/instanceActor denotes an actor that represents the instance/service/host/origin/prefix/etc for the current resource, and it has xyz purpose. different FEPs can define different semantics, but it ultimately is rooted in whatever the heck that actor is supposed to be, as it relates to the current resource. in the same way that http://webfinger.net/rel/profile-page denotes a relation where the linked resource is the “profile page” of the current resource.

1 Like

I’m talking about the text in “Related Proposals” section.

Service is the W3C recommended type for this kind of resource

It probably refers to the rel URI. If the type of actor doesn’t matter, I think some other relation type should be used, as @trwnh suggested.

It could be put in all three places, but I wouldn’t recommend it. WebFinger also supports service-level metadata and is already required for federation.

I agree and I discuss this issue in the FEP. However, there seems to be more community interest in the discovery topic at the moment than in defining the instance actor itself. I’ve considered writing an informational FEP for it, something like a survey of current practices rather than a specification-like FEP. However, it’s going to require significant time to do the research. These instance-level actors are usually not documented well, so it will require some reverse-engineering to know the instance-level actors’ capabilities in various implementations.

I describe this in the FEP in the Terminology section.

The current “instance prefix” definition does not include a subpath, but I’m open to discussion about it. I thought about including support for it but I don’t know how instance-based same-origin authorization would work with that approach. If you have two URIs: https://server.example/user/foo and https://server.example/admin/bar. Are those the same origin (same instance) or not? I don’t know how an activity receiver is going to know that it must include the first segment of the path in the “instance prefix” to make that determination.

The question isn’t clear to me. This doesn’t replace any existing WebFinger usage for normal actors (versus instance-level actors), if that’s what you’re asking.

The WebFinger as:Service link relation denotes actors (could be more than one with different roles, as discussed in the FEP) that are associated with the WebFinger resource identified by the instance prefix/URI.

I’m not convinced yet that minting a new rel URI is necessary for this case.

This is untrue. It’s true that it’s not a W3C recommendation; that’s a very specific term for documents that go through a pretty rigorous process. But I’m not just a community member and that’s not just my opinion.

I’m the co-author of both Activity Streams 2.0 and ActivityPub. I’m the current editor of both specs.

I create the Primer articles to elaborate on existing specifications when there are questions that come up on the GitHub issues that need further explanation and aren’t covered in the specs well enough. They are made in my role as editor. It is not just my opinion; it’s the best current recommendation for implementers. I publish my opinions elsewhere.

Many of the Primer articles have been edited; it’s a wiki. If you disagree, please change it. Also, you’re welcome to come to the Issue Triage meetings, so you can be there when we discuss the issues.

On this topic: I think it’s fine to use Application for the server actor, especially if you’re representing the role of the server as an HTTP client (for example, for fetching remote data or delivering activities).

But, in general, a server is better described as a Service. So, metadata about the service (like its name, description, etc.) would be better there.

@stevebate I think the content of the server outbox can be about the same as the sharedInbox when you GET it, namely: Announce activities of all the public activities made by users on the server.

1 Like

My objection was about the use of “W3C recommended” phrase, and that has been resolved.

Regarding the Service/Application debate - I don’t have a W3C Wiki account, but I proposed an alternative definition in this GitHub issue: Clarify the definitions of Application and Service types · Issue #563 · w3c/activitystreams · GitHub

In the FEP you suggest using Webfinger properties (while leaving any further details out-of-scope). Based on the example given, I think it would make more sense to swap the usage of properties with the usage of rel. For example, instead of properties.as:relationship = moderation and properties.as:relationship = administration, it makes more sense to use rel = moderation and rel = administration.

I appreciate the feedback.

I’ll add something to the FEP to recommend using instance-level actor role-specific rel URIs defined in future FEPs, if they are available, over the as:Service/as:relationship technique. As you’ve said, these standardized URIs should be described in detail for them to be useful and interoperable. For that reason, I think they need their own FEP (maybe even an FEP per relationship, depending on the complexity).

The bootstrapping issue is definitely one use case! We described this in SocialCG/ActivityPub/Authentication Authorization - W3C Wiki , and it’s illustrated in more detail in Understanding ActivityPub - Part 4: Threads - Sebastian Jambor's blog .

I suspect there are other niche use cases around the edges of the protocol, maybe around Deletes, but I haven’t thought through any in detail yet.

1 Like

Thanks for those links. I’d like to understand this better. Unless I missed it, neither article discussed “instance actor” discovery/identification. Are there extra steps in those documented sequences for querying another service (like WebFinger or NodeInfo) to know if the fetcher is an actor that doesn’t require authorized fetch for its profile (AKA an “instance actor”). Should a fetcher always try to fetch the signature keys first and then use some fallback strategy if the fetch fails?

I’m not sure I understand the intent of the authorized profile fetch (really authorized public key fetch). Mastodon docs for authorized fetch say:

it becomes possible to enforce who can and cannot retrieve even public content from your server, e.g. servers whose domains you have blocked.

I understand the objective with content other than keys. But if a fetcher from a non-blocked domain requests the profile/key, why not return it? If the user’s domain is blocked, wouldn’t the instance actor from that same domain also be blocked?

Is this a workaround for not being able to request the actor’s public keys without fetching the entire actor profile?

The confusion and questions here - and your FEP! - are definitely warranted. :grin:

I’m not aware of any ad hoc standard for instance actor discovery. It’s not strictly necessary for the actor fetch bootstrapping case: the fetcher signs with the instance actor, the receiver fetches the instance actor with a signed GET, the fetcher serves the instance actor without trying to verify that signature, and then the receiver has the instance actor’s public key and can verify its signatures. No one needs to discover a remote instance actor.

I haven’t seen your alternative proposal of “just return the public key” before. It’s interesting! I expect current fediverse servers aren’t ready to handle partial object responses like that in general, but you’re right, it could theoretically work, and wouldn’t require special cased instance actors.


Ok, thanks. That’s the impression I had previously. The Threads-related article spoke of fetching the instance actor without a signature (versus not validating the signature) and that confused me a bit since the code would need to know whether to include the signature or not based on the actor URI.

The publicKey object in the actor profile has an identity (id), It could normally be dereferenced directly, but Mastodon chose to use a fragment-based key id, which is going to return the actor profile when dereferenced using HTTP. Otherwise, the code would be able to dereference the public key information from the key URI included with the signature. The key object has an owner so you can then FYN to the actor profile, if needed. The object isn’t a partial object from JSON-LD perspective. It could remain embedded like it is now and be dereferenced as a standalone object if the key URI supported it.

1 Like

Yup, and literally all other implementations followed suit. More discussion: Guidance on fragments in ids · Issue #367 · w3c/activitypub · GitHub

This is true in theory! …but in practice, very few AP implementations are that generic and modular about composing objects and serving them all separately. In practice, the AP servers I’m familiar with generally treat publicKey as part of an actor, not an independent object.

True. However, it doesn’t seem any more difficult than creating a special fetch proxy actor and delegating to that when fetching profiles. I do realize the ship has sailed to some extent with the Mastodon approach and those that have copied the technique.

Thanks for the GitHub link. I had read that and the Primer associated with the GitHub issue. There are legitimate uses for URI fragments in cases where you never want an object to be dereferenced independently from the containing object (URI-fragment). Given the way authorized fetch usage has evolved (Mastodon still recommends against it), it might be time to rethink the fragment-based key approach as an alternative to the actor proxy technique.

I’m still unclear. If I want to support blocking profile fetches for a specific remote actor (vs a domain, which can be done without the fetch proxy), is the “instance actor” actually a way to bypass that intent?

But, to bring this back on topic, it doesn’t appear that “instance actor” discovery is required for this use case, and if not, it’s not relevant to the FEP-ceee (or FEP-2677).

EDIT: See also, Authorized Fetch and the Instance Actor - ActivityPub - SocialHub

Yes, the “instance actor” is really just a proxy. It grew out of the same-origin assumption of security, i.e., any actor on the host is thought to entail delivery, processing, and potentially visibility on that entire host. It’s the same with sharedInbox as a construct. This is why Mastodon refers to its “instance actor” as a “representative account”. Technically, since the keys are all custodial, an admin can use any actor on any domain they control to sign the fetch. They don’t even have to be on the same host, either – the recent proof-of-concept from Alex Gleason using nginx to proxy additional domains into Rebased and then use them for HTTP Signatures showed that quite clearly: Configuring the Service Actor domain on Rebased ($3634512) · Snippets · Soapbox / Rebased · GitLab

In other words, 1@a could be blocked, but 2@a could sign for it and bypass the actor block, and even if you block domain a, you could use 1@b to sign for it and bypass the domain block. In each case, the actor only really needs a publicKey. Whether it’s a “full” actor or a “stub” actor is irrelevant for the purpose of HTTP Signatures.


True!..which does kind of beg the question, what’s the use case or motivation for discovering an instance actor? We’ve concluded that authorized fetch bootstrapping doesn’t need it, at least not so far. I’m curious what other use(s) you had in mind…?

Great question. I’m still looking for a use case for discovering “an instance actor” (a singleton instance representative, AKA FEP-2677 “Application actor” if it uses the as:Application type). My FEP is focused more on instance-level service actors for tasks like moderation or administration. However, the singleton instance actor is a special, restricted case of what I’m describing.

Relay support is another use case. However, I don’t know yet if that one needs discovery support or not.

I had thought the FEP-2677 use case for fetching public keys (really fetching profiles when authorized fetch behavior is enabled in a remote instance) was a motivating use case, but it doesn’t look that way after our discussion (thanks to you and @trwnh for all the information). According to FEP-2677 more than a few implementations have support for some kind of Application actor. However, it’s not clear if or how discovery is supported for those implementations. I know some use Webfinger (Mastodon) and some use Nodeinfo metadata, but there may be other variants (including not exposing the actor at all for discovery purposes). More research is needed on this topic.

Mastodon uses a discovery technique similar to FEP-ceee (Webfinger-based). Mastodon might have WebFinger support because they support using an account ID as the key ID base and they need to resolve the account ID to an actor URI in that case. AFAICT, the discovery support isn’t to support fetching public keys (restricted profiles).

FEP-2677 also mentions attaching metadata to an instance actor, but I think that would be better suited for NodeInfo metadata (possibly partially standardized with JSON Schema definitions).