FEP-2c59: Discovery of a Webfinger address from an ActivityPub actor

How will this be related to or reconciled with name and preferredUsername as currently implemented by Mastodon-like servers? It feels like embedding presentation-related preferences into the aliases collection ordering will lead to confusion. It also doesn’t fully specify the presentation considerations, such as how the preferred alias (possibly something other than an acct: URI), will be transformed for presentation and display purposes.

Mastodon doesn’t generally follow this policy. For example, in displayed posts, I am often referred to @steve rather than by my domain-qualified Mastodon account “handle”.

+1 for a more generic property. Maybe sameAs or a similar name would make a difference between it and alsoKnownAs a bit more clear.

I have a use case in FEP-ef61 where a yet-to-be-decided property needs to specify identifiers that resolve to the same object. I think this is sufficiently close to the Webfinger use case, especially considering @trwnh’s idea to skip JRD.

The reasons I like using XRD aliases are

  1. The semantics are reasonably well understood already, because everyone already implements WebFinger
  2. Someone else (the XRD WG) already documented them
  3. This allows you to skip WF in the ActivityPub id to acct: handle direction. If you broaden this concept more widely into a syntax for transferring XRDs/JRDs, then it also directly gives us a method to do what @trwnh proposed with skipping JRD by basically defining a syntax for JRD-in-JSON-LD/AS2

The current way Mastodon (and most implementations) handle this doesn’t align with what the spec says, in a way that’s deeply unfortunate

As the spec says:

preferredUsername
A short username which may be used to refer to the actor, with no uniqueness guarantees.

There’s a reason its termed “preferredUsername” and not just “username”

Presentational characteristics are really implementation specific but I think we can encourage

  • If wishing to display the user’s “name”, use the display name
  • If wishing to display the user as a plain “handle”, just use preferredUsername alone (and expect it to be non-unique)
  • If wishing to display a “user@domain” ID, use the first acct: URI in the aliases list
  • If wishing to present a HTTPS URI for the user, use the “url” property (as is done today)

In my understanding, WebFinger in Fediverse is used as a serialization of Web Linking to establish a self link from an acct: resource to an Activity Streams actor, and I wonder if we can also formalize the reverse discovery in terms of the Web Linking framework.

Come to think of it, Activity Vocabulary helpfully defines the Link type, which serves as a JSON-LD serialization of Web Linking. So I think we can use it to link an Activity Streams actor to an acct: resource, like the following:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://social.example.com/users/1",
  "type": "Person",
  "name": "John Doe",
  "url": [
    "https://social.example.com/@John",
    {
      "type": "Link",
      "href": "acct:John@example.com",
      "rel": "alternate"
    }
  ]
}

I think the benefit of this approach is that it can be expressed in the core Activity Vocabulary terms without inventing an extension property or borrowing an external vocabulary.

1 Like
    "webfinger": {
      "@id": "wf:webfinger",
      "@type": "xsd:string"
    }

IIUC, JSON-LD strings are xsd:string by default (https://www.w3.org/TR/2020/REC-json-ld11-20200716/#data-model: “A JSON-LD value is […], a string (which is interpreted as a typed value with type xsd:string), […].”) so I think the expanded term definition can simply be "webfinger": "wf:webfinger".

1 Like

Pleroma seems to have started to signal the webfinger property:

2 Likes

I wrote a short FEP describing the aliases property: feps/d2da/fep-d2da.md at main - silverpill/feps - Codeberg.org. However, I don’t need this property anymore, so this FEP will likely remain unpublished.

For the specific use case discussed here, webfinger seems to be good enough.

1 Like

also, the datatyping to xsd:string is generally unnecessary and creates more headaches for plain JSON processors, since it means that compacting against activitystreams only will NOT produce the following:

{
  "https://purl.archive.org/socialweb/webfinger#webfinger": "acct:foo@bar.com"
}

but will produce this instead:

{
  "https://purl.archive.org/socialweb/webfinger#webfinger": {
    "@value": "acct:foo@bar.com",
    "@type": "http://www.w3.org/2001/XMLSchema#string"
}

also, the prefixes wf and xsd are unused within the data graph, and can pollute the context of the JSON-LD processor.

a better context would simply be:

{
  "@context": {
    "webfinger": "https://purl.archive.org/socialweb/webfinger#webfinger"
  }
}

cc @eprodrom

1 Like

aside from this, concerns from 2 years ago remain unaddressed:

issue 1: “webfinger address” is not defined in webfinger

A Webfinger address is an email-address-like identity in the form user@activitypub.example. Following the Webfinger protocol, a client can discover information about the person at that address

this statement is false. webfinger allows discovering information about resources by their uri. you can’t take a string like user@activitypub.example and get any meaning out of it unless you give it a scheme, which comes with its own semantics. for example, mailto:user@activitypub.example identifies a mailbox (specifically, the act of sending an email to that mailbox), while acct:user@activitypub.example identifies an account on a system (similar to a UNIX user account, but allowing for other account systems that use email addresses, such as acct:a%40trwnh.com@site.example identifying “the account a@trwnh.com on site.example”, assuming that site.example tracks accounts by email addresses instead of by usernames.

furthermore, the acct: URI scheme defined in RFC 7565 does not have a default resolution method. it identifies the account even if webfinger is not used, and can be used without webfinger.

this part of the motivation should be rewritten to accurately describe how webfinger is actually used in fedi, which is for mastodon-style “handles” of the form @user@domain, which have an associated resolution protocol using webfinger:

  1. let DOMAIN be the last part when you split on @
  2. let RESOURCE be the result of replacing the first @ of the handle with acct:
  3. construct a webfinger uri of the form https://DOMAIN/.well-known/webfinger?resource=RESOURCE
  4. filter the JRD links for an item with rel=self and type=AS2
  5. the href of that item is the actor id.

you can’t assume this protocol is always in effect simply from a string user@domain or even a uri acct:user@domain. the uri for the webfinger result is https://DOMAIN/.well-known/webfinger?resource=RESOURCE. (you could consider a uri scheme like webfinger: which makes this shorter, but it probably isn’t worth breaking the network effects of https: just to be able to refer to webfinger://DOMAIN/RESOURCE. maybe web+finger:// could be useful, but like other web+ schemes it shares the same issues.)

issue 2: preferredUsername is functionally required by mastodon et al

This technique can cause issues for certain actor URLs. First, preferredUsername is not a required property for an ActivityPub actor.

introducing a new property which is also “not a required property for an ActivityPub actor” seems like weak justification. i would remove the quoted part here entirely.

issue 3: incorrect description of canonicalization

Second, it becomes inconvenient to use subdomains or alternate domains for actor URLs. If the original WebFinger is evan@organization.example, and the ActivityPub URL is https://social.organization.example/evan, the Webfinger will be canonicalized to the longer evan@social.organization.example. A similar problem arises if the actor URL uses one subdomain per user, like https://evan.organization.example/.

no, the canonical handle is the subject of the JRD returned from social.organization.example’s or evan.organization.example’s webfinger endpoints.

going from a handle to an actor, you take the domainpart as the webfinger host, and lookup the corresponding acct: URI of the handle. it then links to the actor.

once you have the actor, you can go from the actor to the canonical handle. to do this, you use the actor’s host as a webfinger host and lookup the actor (or their preferredUsername + host) via the host’s webfinger endpoint. the subject is then the “canonical handle”. you can then verify this handle if the domainpart of the acct: uri in the subject is different from the host of the actor.

in other words, if evan.organization.example says that acct:evan@evan.organization.example has a subject of acct:pompous@idiot.example, then the canonical handle is @pompous@idiot.example. you can verify this by checking the webfinger endpoint on idiot.example to see if it agrees.

there’s no “inconvenience” here, just 1 extra request if you don’t trust the actor host to make claims about cross-origin accounts.

using a dedicated property for a handle still incurs verification to see what the host says the subject is. ironically, depending on your trust model, you could use the so-called “webfinger” property to skip webfinger resolution entirely (since you already have the claimed subject!) if it’s on the same domain and you apply same-origin trust (and then you only need to do webfinger lookup if the domainpart and the host are different).

issue 4: considerations for jsonld

the FEP seems to assume the jsonld context of https://purl.archive.org/socialweb/webfinger will always be used, but there is not a requirement that actor documents MUST use this jsonld context. hence, other serializations are possible, and by default (AS2 only), this is what the current jsonld context expects for compaction:

{
  "https://purl.archive.org/socialweb/webfinger#webfinger": {
    "@value": "acct:foo@bar.com",
    "@type": "http://www.w3.org/2001/XMLSchema#string"
}

this is mentioned in the previous post in further detail.