Copyright © 2024 the Contributors to the ActivityPub and WebFinger Specification, published by the Social Web Incubator Community Group under the W3C Community Final Specification Agreement (FSA). A human-readable summary is available.
Identifiers in ActivityPub tend to be HTTPS URIs. The use of WebFinger (as defined in [RFC7033]) allows for discovery of an actor's identifier given a username and a hostname, which may be more socially salient or otherwise easier to communicate across various contexts and media. The username and hostname are resolved at the WebFinger endpoint of the hostname in order to discover a link to an actor associated with the user's account, and that actor similarly can be back-linked to the username and hostname.
This specification was published by the Social Web Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Final Specification Agreement (FSA) other conditions apply. Learn more about W3C Community and Business Groups.
GitHub Issues are preferred for discussion of this specification.
This section is non-normative.
Consider an HTTPS URI of the form https://social.example/actors/9c5b94b1-35ad-49bb-b118-8e8fc24abf80
being used as an identifier for an actor associated with a user account. Communicating this digitally may be done by simply using the HTTPS URI as-is, as a hyperlink reference. However, communicating this verbally or in a space-constrained visual format can be difficult. WebFinger allows communicating aliases of the form alyssa@social.example
, which are easier to work with in the previously-cited cases.
Additional benefits of using WebFinger include smoothing over the differences between varying actor URI schemas. Different softwares may provide human-friendly URLs for an actor's profile, but these URLs may take several different forms:
https://social.example/alyssa
https://social.example/@alyssa
https://social.example/~alyssa
https://social.example/u/alyssa
Conventionally, people can be identified by their user@domain address, while documents can be identified by their HTTPS location.
Discovery can occur in one of two directions:
The former will be referred to as "forward discovery" and the latter will be referred to as "reverse discovery".
Given a username and hostname in the form user@domain
:
acct:
URI of the form acct:user@domain
(as defined in [RFC7565])acct:
URI as the value of the resource
query parameter (as described in [RFC7033])For example, the WebFinger address alyssa@social.example
can be resolved as a resource by making an HTTP GET request for https://social.example/.well-known/webfinger?resource=acct:alyssa@social.example
(which is https://social.example/.well-known/webfinger?resource=acct:alyssa%40social.example
when percent-encoded). This request MUST returns a JRD (JSON Resource Descriptor, as defined in [RFC6415]) with application/jrd+json
as the content type (assuming no specified Accept
header).
The WebFinger request and response may look like this:
GET /.well-known/webfinger?resource=acct:alyssa@social.example HTTP/1.1
Host: social.example
HTTP/1.1 200 OK
Content-Type: application/jrd+json
{
"subject": "acct:alyssa@social.example",
"aliases": [
"https://social.example/@alyssa",
"https://social.example/actors/9c5b94b1-35ad-49bb-b118-8e8fc24abf80"
],
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": "https://social.example/@alyssa"
},
{
"rel": "self",
"type": "application/activity+json",
"href": "https://social.example/actors/9c5b94b1-35ad-49bb-b118-8e8fc24abf80"
}
]
}
At this point, you can parse for the href
of the element of links
that has a rel
of self
and a type
of either application/ld+json; profile="https://www.w3.org/ns/activitystreams"
or application/activity+json
(depending on the implementation). See 3.2 Establishing a link between the WebFinger resource and the actor document for more information about this.
Given an actor with an id
and a preferredUsername
:
id
to discover the WebFinger domainpreferredUsername
and the WebFinger domain in order to form a WebFinger addresssubject
and it contains an acct:
URI different from the one you constructed, perform a verification discovery against that acct:
URI afterward. (In such cases, the subject
of the JRD denotes the expected canonical identifier.)For example, given an actor document at https://activitypub.example.com/actor/1
like so:
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://activitypub.example.com/actor/1",
"preferredUsername": "alice",
"name": "Alice P. Hacker"
}
The reverse discovery process would extract alice
and activitypub.example.com
, construct the acct:
URI acct:alice@activitypub.example.com
, then request https://activitypub.example.com/.well-known/webfinger?resource=acct:alice@activitypub.example.com
like so:
GET /.well-known/webfinger?resource=acct:alice@activitypub.example.com HTTP/1.1
Host: activitypub.example.com
HTTP/1.1 200 OK
Content-Type: application/jrd+json
{
"subject": "acct:alice@example.com",
"aliases": [
"https://example.com/@alice",
"https://activitypub.example.com/actors/1"
],
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": "https://example.com/@alice"
},
{
"rel": "self",
"type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href": "https://activitypub.example.com/actors/1"
}
]
}
At this point, we have validated that alice@activitypub.example.com
links back to our actor document, but we can optionally verify that the canonical WebFinger address of alice@example.com
also links back to the same actor document:
GET /.well-known/webfinger?resource=acct:alice@example.com HTTP/1.1
Host: example.com
HTTP/1.1 307 Temporary Redirect
Location: https://activitypub.example.com/.well-known/webfinger?resource=acct:alice@example.com
GET /.well-known/webfinger?resource=acct:alice@example.com HTTP/1.1
Host: activitypub.example.com
HTTP/1.1 200 OK
Content-Type: application/jrd+json
{
"subject": "acct:alice@example.com",
"aliases": [
"https://example.com/@alice",
"https://activitypub.example.com/actors/1"
],
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": "https://example.com/@alice"
},
{
"rel": "self",
"type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href": "https://activitypub.example.com/actors/1"
}
]
}
To ensure smooth operation of the WebFinger discovery flows, identifiers and responses should follow certain guidelines for encoding.
The acct:
URI scheme is defined in [RFC7565], which contains ABNF ([RFC5234]) for allowed characters (inheriting from [RFC3986] as well):
acctURI = "acct" ":" userpart "@" host
userpart = unreserved / sub-delims
0*( unreserved / pct-encoded / sub-delims )
; userpart regex: [A-Za-z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=](?:[A-Za-z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=]|(?:%[0-9A-Fa-f]{2}))*
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
pct-encoded = "%" HEXDIG HEXDIG
host = IP-literal / IPv4address / reg-name
reg-name = *( unreserved / pct-encoded / sub-delims )
; reg-name regex: (?:[A-Za-z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=]|(?:%[0-9A-Fa-f]{2}))*
Further restrictions are specified in [RFC7565]:
unreserved
characters SHOULD be decoded if encountered as a percent-encoded octet.IdentifierClass
This section is non-normative.
Note that while there are several symbols allowed in the userpart, the de facto limits set by some current implementers are much more restrictive.
At the time of this writing, Mastodon enforces the following rules:
A
through Z
, a
through z
, 0
through 9
) and underscores (_
) are generally allowed anywhere in the username.
) and dashes (-
) are allowed in the middle of a username, but not as the first character or the last characterIn other words, Mastodon will accept the regular expression or the following ABNF:
; As a regular expression, this can be expressed as follows:
; /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
username = word
*( rest )
word = ALPHA / DIGIT / "_"
rest = *( extended )
word
extended = word / "." / "-"
Similarly at the time of this writing, Misskey is subject to the following limitations:
id
in any references to an actor. (Implementers that currently treat usernames as canonical identifiers SHOULD take steps to avoid doing so in the future.)A-Z, a-z, 0-9
) and underscores (_
).As discussed in 2.1 Forward discovery of an actor document given a WebFinger address, the link to the actor associated with a given WebFinger address will have the following qualifiers:
rel
MUST be self
type
MUST be either application/activity+json
or application/ld+json; profile="https://www.w3.org/ns/activitystreams"
Publishers SHOULD include only one such link.
Due to the prevailing use of WebFinger addresses as canonical primary identifiers for users, implementations that require WebFinger for compatibility will often also deduplicate actors based on the WebFinger address. Therefore, it is generally expected that there is only one self
link to an Activity Streams document, in a unary relationship. However, some implementations do not follow this expectation, and there might be multiple links to ActivityStreams documents for the same WebFinger acct:
resource. In such cases, one of the following strategies may be employed:
links
links
by their href
properties
which may give further hints as to which entry of links
is appropriate to followThis section is non-normative.
Aside from the self-link to the associated actor, resolving a WebFinger query may expose some other links of potential interest. The following link relations are currently common among WebFinger implementers, and are recommended for use especially when the actor document is not publicly available:
http://webfinger.net/rel/profile-page
(for quickly getting the HTML profile page of a user without resolving their actor document and checking for the url
)http://webfinger.net/rel/avatar
(for quickly getting the avatar of a user without resolving their actor document and checking for the icon
)The following link relations are less common, but offer useful information to ActivityPub implementers:
http://ostatus.org/schema/1.0/subscribe
(used to power features like Mastodon's remote follow buttons)http://schemas.google.com/g/2010#updates-from
(used by some implementations to link to an Atom feed)feed
(used by some implementations to link to one or more feeds; feeds can be disambiguated by checking type
and/or title
properties of the link)http://a9.com/-/spec/opensearch/1.1/
(for custom search bars)Also uncommon but supported by at least one implementation (WordPress) is the ability to query non-actor, non-user resources via WebFinger. The following link relations are exposed:
shortlink
author
alternate
license
canonical
webmention
This section is non-normative.
Using WebFinger can provide proof of existence of an associated actor document, as well as make it easier to discover that associated actor document; following this, an actor's inbox can be likewise discovered, and spam or other unwanted messages can be delivered to that actor's inbox. It may be desirable for some systems to not publicly expose an actor's existence and instead rely on the user manually entering their actor's HTTPS URI, or maintaining a "contact list" of bookmarked actors or resources. For such systems, the use of WebFinger is not advisable.
This section is non-normative.
The current use of WebFinger with ActivityPub could be improved in several ways:
preferredUsername
is not ideal for constructing WebFinger addresses, and it also does not allow for expressing actual "preferred usernames". An explicit property for denoting the user's "canonical" WebFinger address would ease reverse-discovery concerns.Accept
header specifies the correct media type, skipping the resolution of the JRD.As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MUST, SHOULD, and SHOULD NOT in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.