WebFinger
WebFinger is a protocol that enables the discovery of information about people or other entities on the Internet using standard HTTP methods over HTTPS, primarily through queries based on URIs such as email addresses or account identifiers.[1] Defined in RFC 7033 and published by the Internet Engineering Task Force (IETF) in September 2013, it allows clients to retrieve static metadata about a resource, such as profile details, associated services, or alternative identifiers, without requiring prior knowledge of the entity's location.[1][2]
The protocol operates by directing clients to send a GET request to the /.well-known/webfinger endpoint on the host derived from the target URI, including a resource parameter specifying the entity (e.g., acct:username@[example.com](/page/Example.com)) and optionally a rel parameter to filter for specific link relations.[1] Servers respond with a JSON Resource Descriptor (JRD), a structured document containing the subject's URI, aliases (alternative URIs), properties (key-value pairs like names or photos), and links to related resources with types defined by the Link Relations registry.[1] This design supports decentralized discovery across domains, facilitating interoperability in applications like social networking, identity management, and federated services, while mandating HTTPS for transport to ensure security.[1]
Key features include support for Cross-Origin Resource Sharing (CORS) to allow browser-based queries, redirection for hosted services, and extensibility via the properties and links in JRDs, though it explicitly excludes dynamic or real-time data to maintain simplicity and privacy boundaries.[1] Security considerations emphasize the use of valid TLS certificates, rate limiting to prevent abuse, and user consent for published information, as exposure of personal details can lead to privacy risks or spam harvesting.[1] Developed by Paul E. Jones, Gonzalo Salgueiro, Michael B. Jones, and Joseph Smarr, WebFinger builds on earlier discovery mechanisms like LRDD but standardizes them into a single, RESTful interface for broader adoption.[1][3]
Overview
Definition and purpose
WebFinger is a protocol defined in RFC 7033 that enables the discovery of information about people or other entities on the Internet through standard HTTP methods, primarily using identifiers in the form of "acct:" URIs or email addresses.[1] It operates by allowing clients to query a server's well-known endpoint, typically via HTTPS, to retrieve static metadata associated with the identifier, without requiring direct access to the entity's location on the web.[1]
The core purpose of WebFinger is to facilitate decentralized discovery of public profile information, contact details, or other metadata, avoiding the need for centralized directories or proprietary systems.[1] By leveraging HTTP, it promotes interoperability among diverse services such as social networks, email providers, and identity systems, enabling users to share and access information across platforms in a standardized manner.[1] This approach supports broader goals of decentralized identity management on the web, where entities can expose links to resources like profile pages without relying on siloed APIs.[1]
WebFinger draws conceptual inspiration from earlier user discovery mechanisms, including the UNIX "finger" protocol and integrations with systems like OpenID for simplifying identity lookups.[4] It has been adapted for use in OpenID Connect to dynamically discover identity providers based on user identifiers.[1] The protocol returns results in a JSON Resource Descriptor (JRD) format, which encapsulates links and properties related to the queried entity.[1]
Key concepts
WebFinger relies on the acct: URI scheme to identify users and entities in a standardized manner. The format is acct:[user](/page/User)@host, where "user" represents the local identifier and "host" is the domain, providing a URI-based account reference that is distinct from email addresses despite superficial similarity, as it functions solely for resource discovery rather than message routing.[1]
At the core of the protocol are resource descriptors, which are structured documents typically formatted as JSON Resource Descriptors (JRDs). These descriptors contain an array of links pointing to related resources, such as user profiles, avatar images, or additional metadata, enabling clients to retrieve contextual information about the identified entity.[1]
Discovery begins at a standardized well-known URI endpoint, specifically /.well-known/webfinger on the target host, which serves as the entry point for querying resource information via HTTP.[1]
Each resource descriptor includes essential properties, with the subject field mandating the acct: URI of the entity (e.g., acct:user@host), and an array of link relations defined by the rel parameter to specify the type of connection, such as rel="http://webfinger.net/rel/profile-page" for linking to a user's profile webpage. These relations use either IANA-registered values or full URIs for precision, accompanied by optional attributes like href for the target URL, type for media types, and properties for embedded metadata.[1]
History
Development origins
WebFinger originated in 2009, when Brad Fitzpatrick, then at Google and known for his work on LiveJournal and OpenID, proposed the protocol as an extension of XMPP's XEP-0157 to enable web-based discovery of user information.[5] This proposal aimed to adapt the XMPP extension's approach to contact addresses—originally designed for specifying service details like email and JabberIDs—into a simpler HTTP-based mechanism for broader internet use.[5][6]
The development was driven by the growing interest in decentralized social networking during the late 2000s, where users sought ways to link identities and profiles across independent sites without relying on centralized platforms.[5] Fitzpatrick's idea built on existing efforts to make email addresses more expressive as identifiers, influenced by OpenID's decentralized authentication model and the Friend of a Friend (FOAF) project's emphasis on semantic web descriptions of relationships and profiles.[5]
Early prototypes focused on practical implementations tied to blogging platforms, including LiveJournal, to support cross-site profile linking and user discovery through straightforward HTTP queries.[5] These initial efforts highlighted WebFinger's potential for enabling services like social graph exploration and identity verification in distributed environments.
Key early discussions involved the IETF's XMPP Working Group, where contributors like Peter Saint-Andre recognized similarities to XEP-0157 and advocated for broader standardization to refine the protocol for internet-scale adoption.[5]
Standardization process
The standardization of WebFinger began with an individual Internet-Draft submission titled "The WebFinger Protocol" (draft-hammer-webfinger-00), authored by Eran Hammer-Lahav, Brad Fitzpatrick, and Blaine Cook, and posted to the IETF on October 19, 2009.[7] This initial draft outlined the protocol's use of HTTP GET requests to a well-known URI for discovering metadata about entities identified by URIs, including the introduction of the 'acct' URI scheme for user accounts.[8]
In April 2012, the IETF issued a call for adoption of the evolving draft by the Applications Area Working Group (APPSAWG), marking its transition to a working group effort under the name draft-ietf-appsawg-webfinger.[9] The working group, chaired by Barry Leiba and Murray Kucherawy, refined the specification through 19 iterations of drafts between July 2012 and August 2013, addressing feedback on security, extensibility, and integration with HTTP standards.[10] Key contributors during this phase included Paul E. Jones, Gonzalo Salgueiro, Michael B. Jones, and Joseph Smarr.[2]
The finalized document was approved by the Internet Engineering Steering Group (IESG) and published as RFC 7033, "WebFinger," on September 27, 2013, achieving Proposed Standard status.[11] This RFC formally defines the protocol's core mechanics, including the use of HTTPS for all requests to ensure secure discovery, the structure of JSON Resource Descriptors (JRDs) for responses, and extensibility through link relations; it also incorporates security considerations such as protection against information leakage and denial-of-service attacks.[1] Additionally, the 'acct' URI scheme was further specified in a separate RFC 7565, published in August 2015.[12]
Following publication, RFC 7033 has seen no major formal updates or revisions, with no reported errata as of the latest IETF records. Community-driven extensions have emerged in related standards, such as the W3C's ActivityPub (published as a Recommendation in 2018), which leverages WebFinger for actor discovery in federated social networks while enforcing HTTPS as mandated; these adaptations focus on integration with modern web architectures without altering the core protocol.
Technical specification
Resource discovery
WebFinger resource discovery involves parsing the input URI to identify the target host. The acct: URI, an identifier of the form acct:username@[hostname](/page/Hostname), is parsed according to RFC 3986 to extract the hostname component, which forms the base for the HTTPS URL (e.g., https://[hostname](/page/Hostname)).[1][13]
The client then constructs the WebFinger URI by appending the fixed path /.well-known/webfinger to the hostname and adding the required resource query parameter with the encoded target URI (e.g., https://[hostname](/page/Hostname)/.well-known/webfinger?resource=acct%3Ausername%40[hostname](/page/Hostname)).[1]
Upon querying the WebFinger URL, a 404 status indicates the resource is unknown to the server.[1]
Once the WebFinger endpoint has been discovered for a given host, clients retrieve metadata about a specific resource by sending an HTTP GET request to the path /.well-known/webfinger on that host, appending the required resource query parameter that specifies the target URI (e.g., acct:[email protected], URL-encoded as acct%3Auser%40example.com).[1] To indicate the desired response format, clients include an Accept header with the value application/jrd+json, ensuring the server returns the resource descriptor in JSON Resource Descriptor (JRD) format if supported.[1]
The request supports an optional rel parameter to filter the response by specific link relation types, allowing clients to retrieve only relevant metadata; for instance, specifying rel=http://webfinger.net/rel/avatar limits results to avatar-related links.[1] Multiple rel values can be provided for broader filtering, and the parameter uses URL encoding for any special characters in relation URIs.[1] Servers process these parameters to generate a targeted response, which upon success returns a 200 OK status code with a Content-Type header set to application/jrd+json.[1] In cases of failure, such as an invalid resource or server error, the server issues appropriate 4xx or 5xx HTTP status codes without disclosing sensitive details.[1]
All WebFinger queries must use HTTPS to protect the confidentiality and integrity of the exchanged metadata, with the request host matching the host portion of the resource URI to prevent cross-host leaks.[1] For performance and scalability, servers include standard HTTP caching headers, such as Cache-Control, in responses to specify expiration times or validators, enabling clients to cache resource descriptors and reduce repeated queries.[1] This caching mechanism aligns with HTTP/1.1 guidelines, allowing conditional requests to refresh stale data efficiently.[1]
The JSON Resource Descriptor (JRD) serves as the standardized response format in the WebFinger protocol, consisting of a single JSON object that conveys metadata about the queried resource.[14] As specified in RFC 7033, the root object of a JRD includes a "subject" member, which SHOULD be present and is a string representing the URI (typically an acct: URI) of the entity being described, and an optional "links" member that is an array of link description objects.[15] Additional optional root-level members include "aliases", an array of alternative URIs for the subject, and "properties", an object mapping URI keys to string or null values for arbitrary metadata.[15]
Each element in the "links" array is a JSON object describing a hyperlink, with the following properties: "rel", a required string indicating the relation type (a URI or registered link relation name); "href", an optional string providing the target URI; "type", an optional string specifying the media type of the target resource; "titles", an optional object of language-tagged strings for human-readable titles; and "properties", an optional object for extension metadata similar to the root "properties".[16] Servers may include multiple links, and clients must ignore any unrecognized properties or members to ensure extensibility.[15]
Common relation types in JRD links include "http://webfinger.net/rel/profile-page", which points to the user's profile page, as illustrated in the protocol's normative example.[17] Another frequently used relation is "me", a registered link relation indicating that the target resource represents the same entity as the subject, often linking to a self-referential profile or identity endpoint.
For instance, a typical JRD response for the subject "acct:[email protected]" might appear as follows:
json
{
"subject": "acct:[email protected]",
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"href": "https://www.example.com/~bob/"
},
{
"rel": "me",
"href": "https://www.example.com/~bob/",
"type": "text/html"
}
]
}
{
"subject": "acct:[email protected]",
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"href": "https://www.example.com/~bob/"
},
{
"rel": "me",
"href": "https://www.example.com/~bob/",
"type": "text/html"
}
]
}
This structure adheres to the schema in RFC 7033, where validation ensures the "subject" matches the queried resource and links conform to the defined object format, though servers are not required to perform strict schema validation.[15]
Examples
Basic profile lookup
To perform a basic profile lookup using WebFinger, consider a hypothetical query for the identifier acct:[email protected] on the fictional host example.com. This initiates a discovery process where a client sends an HTTP GET request to the server's /.well-known/webfinger endpoint, specifying the resource parameter to identify the user. The server responds with a JSON Resource Descriptor (JRD) containing links to relevant resources, such as a profile page and contact information.[14]
The request is constructed as follows:
GET /.well-known/webfinger?resource=acct%3Aalice%40example.com HTTP/1.1
Host: example.com
Accept: application/jrd+json
GET /.well-known/webfinger?resource=acct%3Aalice%40example.com HTTP/1.1
Host: example.com
Accept: application/jrd+json
This URL-encodes the acct:[email protected] URI in the resource query parameter and requests the JRD media type. For manual verification, the curl command-line tool can be used:
curl -H "Accept: application/jrd+json" "https://example.com/.well-known/webfinger?resource=acct%3Aalice%40example.com". This fetches the response directly from the server, assuming HTTPS is enforced for security.[14]
A successful response includes an HTTP 200 status, appropriate headers, and the JRD body. The headers typically specify the content type and may include CORS allowances:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/jrd+json; charset=utf-8
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/jrd+json; charset=utf-8
The JRD payload is a JSON object with a subject field matching the queried resource and an array of links describing discoverable items. For this example:
json
{
"subject": "acct:[email protected]",
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"href": "https://example.com/~alice/"
},
{
"rel": "http://webfinger.net/rel/avatar",
"href": "https://example.com/~alice/photo.jpg",
"type": "image/jpeg"
},
{
"rel": "http://packetizer.com/rel/businesscard",
"type": "text/vcard",
"href": "https://example.com/~alice/alice.vcf"
}
]
}
{
"subject": "acct:[email protected]",
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"href": "https://example.com/~alice/"
},
{
"rel": "http://webfinger.net/rel/avatar",
"href": "https://example.com/~alice/photo.jpg",
"type": "image/jpeg"
},
{
"rel": "http://packetizer.com/rel/businesscard",
"type": "text/vcard",
"href": "https://example.com/~alice/alice.vcf"
}
]
}
Parsing this output yields links to Alice's profile page (a personal webpage), avatar photo (an image file), and business card (a vCard file containing contact details like name, email, and address). These relations follow registered link types for interoperability.[14][18]
Social networking integration
WebFinger plays a crucial role in enabling user discovery across federated social networks, particularly in platforms like Mastodon, where it facilitates interactions between users on different instances without relying on centralized directories. In Mastodon, when a user enters a handle such as @[email protected] to follow someone remotely, the local instance triggers a WebFinger lookup by querying the remote server's /.well-known/webfinger endpoint with the resource parameter set to the account URI (e.g., acct:[email protected]). This process allows seamless cross-instance following by resolving the remote user's identity and associated resources.[19][20]
The response from a Mastodon server in the Fediverse is a JSON Resource Descriptor (JRD) that includes the subject's URI and an array of links pointing to key resources, such as the ActivityPub actor JSON document (via a self rel with application/activity+json type), the user's profile page (via profile-page rel with text/html type), and the avatar image (via an http://webfinger.net/rel/avatar rel). These links enable the requesting instance to fetch the remote user's profile details, posts, and media for integration into the local feed, supporting features like displaying avatars and bios during follows.[19]
Beyond Mastodon, WebFinger supports cross-instance discovery in other federated platforms. In Diaspora, it resolves user handles to hCard documents and seed location endpoints, allowing pods to exchange profile data and initiate connections across the network. Similarly, Pump.io employs WebFinger to identify users via acct: URIs and discover their feeds and social graph endpoints, promoting interoperability in decentralized social environments.[21][22]
This integration provides significant benefits in social contexts by enabling decentralized user search and federation, where individuals can locate and interact with others across independent servers using simple identifiers, eliminating the need for central registries and enhancing privacy through distributed control.[19]
Implementations and adoption
Several open-source libraries and servers facilitate the implementation of WebFinger endpoints on the server side, enabling hosts to provide discoverable resource descriptors for users or entities. One prominent PHP-based option is the Sabre WebFinger library, a lightweight implementation that handles HTTP requests to the /.well-known/webfinger path and returns JSON Resource Descriptors (JRDs) compliant with RFC 7033.[23] This library integrates easily into PHP applications, such as content management systems, by mapping user identifiers to profile data like profile URLs or avatar links. Similarly, the WebFinger plugin for WordPress, developed by Norbert Pfefferle, extends the platform to serve WebFinger responses for blog users, pulling data from user profiles and post feeds.[24]
In Node.js environments, the node-webfinger-service provides a dedicated server module for exposing WebFinger endpoints, supporting both standalone operation and integration into Express.js applications.[25] It processes resource queries (e.g., acct:username@host) and generates JRDs dynamically from a configurable data store, making it suitable for custom social or identity services. For broader ecosystems like the Fediverse, WebFinger is natively built into platforms such as Mastodon and Pleroma to ensure ActivityPub compatibility. Mastodon's implementation resolves acct: URIs to actor profiles via its Rails-based routing, while Pleroma's Elixir backend handles WebFinger lookups to federate user discovery across instances.[20]
Setting up a WebFinger endpoint typically involves configuring web server routes for /.well-known/webfinger and implementing logic to generate JRDs from user data, such as linking to profile pages or service endpoints. For instance, in PHP or Node.js setups, developers route GET requests with resource and rel parameters to a handler that queries a database for the user's information and formats it as a JSON object with subject, aliases, and links arrays.[26] This process adheres to the protocol's requirements for HTTP 200 responses with application/jrd+json content type, often secured via HTTPS.
As of November 2025, WebFinger's adoption in the Fediverse exceeds 19,000 active instances, primarily through integrations in Mastodon and Pleroma, underscoring its role in decentralized social networking. By March 2025, the Fediverse had surpassed 15 million users.[27][28]
Client-side usage
Client-side usage of WebFinger involves applications querying remote servers to discover resource descriptors for entities identified by URIs, typically using HTTP GET requests to well-known endpoints.[1] This enables dynamic retrieval of metadata such as profile links, avatars, or contact information without prior configuration.[1]
Several open-source libraries facilitate WebFinger queries in client applications. In Python, the python-webfinger library provides a straightforward implementation for performing lookups compliant with RFC 7033, supporting resource discovery via LRDD or direct JRD formats.[29] For JavaScript environments, the e14n/webfinger module offers a Node.js client that handles XRD and JRD documents over HTTP/HTTPS, while the silverbucket/webfinger.js library extends support to browsers and Node.js with TypeScript types for modern web applications.[30][31]
Common use cases include auto-discovering contact details in email clients, where a client can provision configuration data like IMAP/SMTP servers by querying a user's URI.[32] In verification-focused apps, WebFinger allows confirmation of user identities by resolving links to authoritative profiles or endpoints.[1]
Integration examples demonstrate WebFinger's role in authentication flows, such as embedding it within OAuth 2.0 and OpenID Connect to dynamically locate issuers based on user identifiers. It also supports decentralized identity systems, where clients resolve domain-based URIs to fetch credential endpoints, as seen in blockchain name services like Unstoppable Domains.[33]
Adoption has grown in decentralized web projects since 2020, particularly within the IndieWeb and Fediverse ecosystems; for instance, ActivityPub implementations like Mastodon rely on WebFinger for actor discovery across federated servers.[20] In Web3 contexts, its use in self-sovereign identity protocols has increased, enabling URI-based resolution in distributed applications.[33]
Security considerations
Privacy risks
WebFinger's public discovery endpoints can lead to unintended information leakage, as they allow any unauthenticated party to retrieve metadata about users, such as profile links, avatars, or associated services, without requiring explicit consent. This exposure occurs because the protocol relies on standard HTTP GET requests to well-known URIs, making personal data discoverable by anyone with network access. For instance, querying a user's account URI can reveal existence confirmation and linked resources, potentially enabling enumeration of user accounts or social graphs.[34]
Historically, early implementations and drafts of WebFinger prior to RFC 7033 in 2013 were susceptible to risks from unencrypted HTTP transports, which could expose query details, including sensitive resource identifiers, to interception on compromised networks. Although the final specification mandates HTTPS to mitigate such eavesdropping, legacy systems or misconfigurations in pre-RFC deployments allowed plaintext transmission of user metadata, heightening the potential for data interception and abuse.[35]
WebFinger utilizes Cross-Origin Resource Sharing (CORS), inheriting all applicable security considerations from the CORS specification, including potential risks associated with cross-origin requests from web browsers.[36]
Mitigation strategies
To mitigate privacy risks associated with unauthorized access to user metadata, WebFinger implementations must enforce the use of HTTPS for all queries and responses, as non-secure HTTP connections are explicitly prohibited to prevent man-in-the-middle attacks that could intercept or alter sensitive information.[1] Clients are required to validate server certificates and reject invalid or untrusted ones, ensuring end-to-end encryption and integrity of the JSON Resource Descriptor (JRD) exchanged during lookups.[1]
Server operators should implement robust access controls to curb potential abuse, such as large-scale data harvesting or denial-of-service attempts through excessive queries. Rate limiting based on client IP addresses or other identifiers is recommended to restrict the frequency of requests, thereby reducing the feasibility of automated scraping while allowing legitimate usage.[1] For queries involving sensitive information, servers may require token-based authentication or other mechanisms to verify client legitimacy before disclosing non-public details, enabling differentiated responses that withhold private links or properties from unauthenticated requesters.[1]
Minimizing data disclosure is a core best practice for preserving user privacy in WebFinger deployments, where servers must limit JRD contents to publicly intended properties only, excluding any private identifiers, locations, or relationships unless explicitly authorized by the user.[1] System administrators are advised to provide granular user controls, allowing individuals to configure which elements of their metadata—such as profile URLs or contact details—are exposed via WebFinger, thereby preventing inadvertent leakage of personal information to unauthorized parties.[1]
On the client side, developers should incorporate practices that respect user intent and enhance query anonymity, such as performing WebFinger lookups only with explicit user authorization to avoid unintended privacy intrusions.[1] Where applicable, clients can include Do Not Track headers in requests to signal a preference against persistent logging of query activity, and anonymize requests by omitting unnecessary identifying headers or using privacy-preserving proxies to further obscure the requester's origin.