The fundamental problem isn’t ActivityPub or WebFinger. The fundamental problem is that an acct: URI is not meant to be resolved. It represents an account on anything with an “account” system. Typically but not always, this is a networked machine made available on some FQDN or hostname and serving as a host for those accounts. Per RFC 7565: The 'acct' URI Scheme
not all service providers offer email services or web interfaces on behalf of user accounts (e.g., a microblogging or instant messaging provider might not offer email services, or an enterprise might not offer HTTP interfaces to information about its employees). Therefore, the participants in the discussion recognized that it would be helpful to define a URI scheme that could be used to generically identify a user’s account at a service provider, irrespective of the particular application protocols used to interact with the account. The result was the ‘acct’ URI scheme defined in this document.
Imagine there’s a Unix system running on a certain hostname. It has a Web server, an XMPP server, an email server, and so on. Each of those accounts exist locally as a Unix account with a username. Now, how do you represent or refer to the Unix account with username a
? Locally, you might do that with acct:a
. In a global network, you have to qualify that with a host-part or domain-part, and it becomes acct:a@trwnh.com
. But this account acct:a@trwnh.com
is not necessarily “the same” as any given Web resource, or any given XMPP resource, or any given SMTP etc etc etc. If it was the same, then you could declare that acct:a@trwnh.com
has one or more aliases
. And by logical extension, you could also declare every single item in the union set of subject
+ aliases
to be related to the current subject
via the self
link relationship. You could also declare the subject
to be a canonical
link relation. So you might end up with something like this, when queried via WebFinger for more information:
GET /.well-known/webfinger?resource=acct:a@trwnh.com HTTP/1.1
Host: trwnh.com
{
"subject": "acct:a@trwnh.com",
"aliases": ["mailto:a@trwnh.com", "xmpp:a@trwnh.com"],
"links": [
{"rel": "self", "href": "mailto:a@trwnh.com"},
{"rel": "self", "href": "xmpp:a@trwnh.com"},
{"rel": "self", "href": "acct:a@trwnh.com"},
{"rel": "canonical", "href": "acct:a@trwnh.com"}
]
}
Now, what’s the problem with the last two links? Well, acct:
doesn’t resolve. You can’t dereference an acct:
URI. RFC 7565 warns about this (emphasis mine): RFC 7565: The 'acct' URI Scheme
the scheme is designed for the purpose of identification instead of interaction (regarding this distinction, see Section 1.2.2 of [RFC3986]) […] It is not assumed that an entity will necessarily be able to interact with a user’s account using any particular application protocol, such as email; to enable such interaction, an entity would need to use the appropriate URI scheme for such a protocol, such as the ‘mailto’ scheme […] Because an ‘acct’ URI enables abstract identification only and not interaction, this specification provides no method for dereferencing an ‘acct’ URI on its own, e.g., as the value of the ‘href’ attribute of an HTML anchor element. For example, there is no behavior specified in this document for an ‘acct’ URI used as follows:
<a href='acct:bob@example.com'>find out more</a>
Any protocol that uses ‘acct’ URIs is responsible for specifying how an ‘acct’ URI is employed in the context of that protocol (in particular, how it is dereferenced or resolved; see [RFC3986]). As a concrete example, an “Account Information” application of the WebFinger protocol [RFC7033] might take an ‘acct’ URI, resolve the host portion to find a WebFinger server, and then pass the ‘acct’ URI as a parameter in a WebFinger HTTP request for metadata
And this is exactly what Mastodon ended up doing: construct an acct:
URI and plug it into WebFinger to get an appropriate link to the resource you’re actually after. Back then, Mastodon used OStatus, which was built on Atom and XML. Convention in an Atom feed was to include a self
link within the response, so that any consumer could get the identifier of the current atom+xml document. In JSON-LD today, you would use the @id
property for the exact same purpose. But Mastodon wanted user@domain handles, so they just lifted the self
link out of the Atom and put it into the WebFinger JRD. Which was not ideal, from a semantic perspective, but it works as long as you declare the appropriate aliases
, and there was a 1:1 mapping between “protocols” (to the extent that “WebFinger resolution of an acct: URI” can be called a “protocol”). Again, A == B, B == A, basic equality.
If you really wanted to simplify the fediverse’s usage of WebFinger, you could just define an extension to WebFinger. Say that the 1:1 mapping is required, and put an Accept
header with the activitystreams media type on your request to the WebFinger endpoint. If the WebFinger server sees that header, it will return an AS2 document instead of a JRD.
So all this is kind of the consequence of using an identifier that wasn’t meant to be interacted with… in a way that interacts with it. Yes, it’s weird. That’s what happens when you use something in a way it wasn’t meant to be used.