This document defines a lightweight, robust, and secure protocol for sending unsolicited notifications — especially comments and responses on syndicated feed content — to specified endpoints; along with rules to enable resulting content to itself be syndicated robustly and securely.
This protocol defines the 'rules of the road' for these mechanisms, tying together and relying on lower level protocols and specifications for implementation.
1.1. Requirements Language
3. Salmon Discovery
3.1. The 'salmon' Link Relation
3.2. Salmon Links for Replies
3.3. Salmon Links for Mentions
3.3.1. The Mentioned Link Relation
3.4. Additional Link Relations
4. Replies Protocol Flow
5. Reply Endpoint Semantics
6. Salmon Signing Requirements
6.1. The 'salmon-signer' Link Relation
7. Salmon Provenance and Syndication
7.1. Provenance in Atom Entries
7.2. Provenance in JSON Data Structures
8. Salmon Verification Requirements
9. Salmon Identification and De-Duplication
10. Salmon Reply Republishing Requirements
11. User Experience and Privacy
12. Activity Streams
14. IANA Considerations
15. Security Considerations
16. Normative References
Appendix A. Specification Feedback
§ Author's Address
Conversations are becoming distributed and fragmented on the Web. Content is increasingly syndicated and re-aggregated beyond its original context. Technologies such as Atom, RSS, and PubSubHubbub allow for a real time flow of updates to feed aggregators, but this leads to silo-ing of conversations. Replies, comments, ratings, and annotations increasingly happen at the aggregator and are invisible to the original source, and to anyone dependent on the original source. In addition, other types of non-content-based interaction — such as following, friending, and mentioning — are typically limited to social network silos. The Salmon protocol provides a way to let this data migrate between distributed silos in a secure and interoperable way. The Salmon Protocol is an open, simple, standards-based solution that lets services unify the conversations.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 (Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” March 1997.) [RFC2119].
- A signed entry.
- Salmon generator:
- A service or agent that creates new salmon on behalf of a user.
- Salmon endpoint:
- A URL to which a salmon is POSTed via HTTP.
- A service or client which aggregates multiple streams of content from other services in order to present a unified view.
- parent entry:
- An entry which can be the target of a reply, comment, or activity salmon
- reply feed:
- A feed of entries which are replies, comments, or activities such as likes which depend for their context and semantics on a parent entry; a feed identified by a link rel="replies" on a parent entry.
Discovery serves both to signal that a service is Salmon-enabled and provide the endpoint(s) to which salmon may be sent. It relies on link endpoint discovery per [WebLinking] (Nottingham, M., “Web Linking I-D, draft 7,” .) for feeds and HTML pages, and discoverable URIs per [LRDD] (Eran, E., “LRDD: Link-based Resource Descriptor Discovery,” .), [Webfinger] (Fitzpatrick, B., Hammer-Lahav, E., Cook, B., Panzer, J., and J. Gregorio, “The Webfinger Protocol,” .), and [XRD] (Hammer-Lahav, E. and W. Norris, “Extensible Resource Descriptor (XRD) Version 1.0, Working Draft 13,” .). The following sections define the semantics of the new link relation introduced by Salmon.
The 'salmon' link relation specifies a Salmon endpoint used to receive salmon of interest to the entity controlling the associated resource. These are typically comments, replies, or mentions that involve the resource. The following sections document the usage of this link relation in different contexts. Additional contexts may be added in the future and Salmon-aware processors MUST ignore contexts they cannot process.
Servers are able to differentiate between the different use cases via the signed content of the salmon itself. Note that a salmon may be both a reply and a mention at the same time, and servers may provide very general catch-all endpoints.
The 'salmon' link relation may specify a Salmon endpoint to be used for any replies to or commentaries about its associated resource. It may appear as a child of atom:entry, an atom:feed, or a HEAD element of an HTML page. When placed at a feed level, all entries within the feed which do not have salmon replies links of their own inherit their feed's salmon replies link (which MUST be obtained from the entry's atom:source element if it is present).
Salmon generators MAY choose to send content that is a reply to the appropriate salmon replies endpoint. Generators SHOULD only do this with user consent (see Section 11 (User Experience and Privacy)).
For an Atom feed, any salmon sent to the salmon replies endpoint MUST have a thr:in-reply-to element set to an entry covered by the endpoint per [RFC4685] (Snell, J., “Atom Threading Extensions,” September 2006.).
Example endpoint in an Atom feed:
<feed xmlns='http://www.w3.org/2005/Atom'> ... <link rel="salmon" href="http://example.org/all-replies-endpoint"/> </feed>
The 'salmon' link relation may specify a Salmon endpoint used to notify a resource, typically a user account, about external mentions of that resource. For a user account, the salmon mention link SHOULD appear in the Webfinger [Webfinger] (Fitzpatrick, B., Hammer-Lahav, E., Cook, B., Panzer, J., and J. Gregorio, “The Webfinger Protocol,” .) XRD document for the user account.
Salmon generators SHOULD only send salmon that explicitly mention the target resource.
Example in a user's XRD file:
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"> <Subject>acct:firstname.lastname@example.org</Subject> <Link rel="salmon" href="https://example.com/mention-handler" /> </XRD>
The 'mentioned' link relation specifies a user or resource mentioned in the salmon content. The presence of the link indicates that the author of the salmon intends to bring it to the target's attention, implying both permission to see the content and a desire for the target to be notified.
Salmon generators SHOULD include a mentioned link specifying mentioned resources when they know the user's intent. Salmon recipients SHOULD use mentioned links to determine where to route notifications.
Example Atom entry with a mention:
<entry xmlns='http://www.w3.org/2005/Atom'> ... <link rel="mentioned" href="acct:email@example.com" /> <content>Hey there @User!</content> </entry>
Additional salmon link relations MAY be defined at any time for additional purposes. Processors MUST ignore link relations they do not understand.
This section details the protocol flow for replies using Atom feeds. In Salmon, a reply is any type of activity that is primarily a response to a parent entry or activity. Whether something is primarily a response is a contextual decision dependent on the application(s) in use. Examples of replies include comments and likes/dislikes on syndicated feed items.
A reply flow begins with a parent entry which the Salmon generator has retrieved or received from a foreign source, e.g., a syndication feed. When the user replies to the entry, the Salmon generator creates a signed Atom entry per Section 6 (Salmon Signing Requirements) to represent the comment. The comment entry points at the parent entry using the Atom Threading Extension [RFC4685] (Snell, J., “Atom Threading Extensions,” September 2006.). The generator creates a signed, enveloped salmon from the comment using the Magic Signatures specification [MagicSig] (Panzer, J., Laurie, B., and D. Balfanz, “Magic Signatures,” .). The generator then POSTs the resulting envelope to the salmon endpoint for the parent entry.
For example, this reply
<?xml version='1.0' encoding='UTF-8'?> <entry xmlns='http://www.w3.org/2005/Atom'> <id>tag:example.com,2009:cmt-0.44775718</id> <author><name>firstname.lastname@example.org</name><uri>email@example.com</uri></author> <thr:in-reply-to xmlns:thr='http://purl.org/syndication/thread/1.0' ref='tag:blogger.com,1999:blog-893591374313312737.post-3861663258538857954'> tag:blogger.com,1999:blog-893591374313312737.post-3861663258538857954 </thr:in-reply-to> <content>Salmon swim upstream!</content> <title>Salmon swim upstream!</title> <updated>2009-12-18T20:04:03Z</updated> </entry>
would generate this POST request to the salmon endpoint discovered earlier (see Section 3.2 (Salmon Links for Replies)):
POST /all-replies-endpoint HTTP/1.1 Host: example.org Content-Type: application/magic-envelope+xml <?xml version='1.0' encoding='UTF-8'?> <me:env xmlns:me='http://salmon-protocol.org/ns/magic-env'> <me:data type='application/atom+xml'> PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4KPGVudHJ5IHhtbG5zPSdod HRwOi8vd3d3LnczLm9yZy8yMDA1L0F0b20nPgogIDxpZD50YWc6ZXhhbXBsZS5jb20sMjAwOT pjbXQtMC40NDc3NTcxODwvaWQ-ICAKICA8YXV0aG9yPjxuYW1lPnRlc3RAZXhhbXBsZS5jb20 8L25hbWU-PHVyaT5ib2JAZXhhbXBsZS5jb208L3VyaT48L2F1dGhvcj4KICA8dGhyOmluLXJl cGx5LXRvIHhtbG5zOnRocj0naHR0cDovL3B1cmwub3JnL3N5bmRpY2F0aW9uL3RocmVhZC8xL jAnCiAgICAgIHJlZj0ndGFnOmJsb2dnZXIuY29tLDE5OTk6YmxvZy04OTM1OTEzNzQzMTMzMT I3MzcucG9zdC0zODYxNjYzMjU4NTM4ODU3OTU0Jz50YWc6YmxvZ2dlci5jb20sMTk5OTpibG9 nLTg5MzU5MTM3NDMxMzMxMjczNy5wb3N0LTM4NjE2NjMyNTg1Mzg4NTc5NTQKICA8L3Rocjpp bi1yZXBseS10bz4KICA8Y29udGVudD5TYWxtb24gc3dpbSB1cHN0cmVhbSE8L2NvbnRlbnQ-C iAgPHRpdGxlPlNhbG1vbiBzd2ltIHVwc3RyZWFtITwvdGl0bGU-CiAgPHVwZGF0ZWQ-MjAwOS 0xMi0xOFQyMDowNDowM1o8L3VwZGF0ZWQ-CjwvZW50cnk-CiAgICA= </me:data> <me:encoding>base64url</me:encoding> <me:alg>RSA-SHA256</me:alg> <me:sig> cAIu8VKIhs3WedN91L3ynLT3GbZFhbVidDn-skGetENVH-3EguaYIjlPTq7Ieraq4SD BknM9STM9DR90kveUrw== </me:sig> </me:env>
Note that salmon generators who also publish the salmon themselves SHOULD include the atom:source element to identify the 'home' feed of the salmon, per [RFC4287] (Nottingham, M., Ed. and R. Sayre, Ed., “The Atom Syndication Format,” December 2005.).
The Salmon endpoint responds to the salmon with standard HTTP codes, which are detailed in the subsequent sections. The semantics of a successful POST is dependent on the Salmon endpoint server. The Salmon client's responsibility ends once it receives a 2xx response. A possible, and expected, result is for the salmon to be re-published and re-syndicated along with other native comments on the syndicated feed item. Therefore, salmon generators SHOULD use appropriate messaging to the user under the assumption that the data MAY be published with the same level of visibility as the rest of the comments. Endpoints are nevertheless not obligated to re-publish salmon; they may for example moderate them, spam block them, aggregate them, or analyze them.
If the salmon endpoint does re-publish the salmon in the parent's comment feed, it MUST conform to additional requirements in Section 10 (Salmon Reply Republishing Requirements) in order to support the end-to-end Salmon protocol. A salmon generator MAY use the mechanisms described in Section 10 (Salmon Reply Republishing Requirements) in order to subscribe to the consolidated feed of all replies, if available.
Salmon generators sign salmon using the mechanism described in [MagicSig] (Panzer, J., Laurie, B., and D. Balfanz, “Magic Signatures,” .). In the most common case, the Salmon generator is also the identity provider for the author URI. The Salmon generator MAY maintain keypairs on behalf of its users or use additional mechanisms to allow users to maintain their own private keys (while still publishing the public keys).
In a second scenario, the Salmon generator is itself a relying party (RP) for an external Identity Provider (IdP). In the most general case, there are four parties with no pre-existing trust relationship: IdP, RP(generator), salmon receiver, and downstream syndicator. From the viewpoint of the other parties, the IdP always signs the salmon. When the salmon generator is not also the IdP, it must delegate the signing task to the IdP. To facilitate this, IdPs MAY provide the following standard API, protected via OAuth, to create signed Salmon on behalf of the user.
The 'salmon-signer' link relation specifies a Salmon endpoint to be used to turn an unsigned entry into a signed salmon. It is discovered via XRD discovery on the IdP host; that is, look for the salmon-signer relation in /.well-known/host-meta and use the resulting endpoint.
The endpoint accepts a POST of an unsigned entry along with OAuth request credentials. On success, it returns a 200 response and a body of type application/magic-envelope containing the signed Salmon. On failure it returns standard error codes, including 401 or 403 for authorization failures and 400 for bad input. The IdP MUST verify that it understands the input to be signed and that the user has previously granted the salmon generator access to signing services for salmon. Note that the resulting signed salmon may be modified, e.g., unknown markup may be stripped out rather than being signed.
The full flow for signing a request in this most general case is then:
In some cases Salmon signatures must augment existing formats, e.g., Atom entries. For this reason, Salmon adds the me:provenance element to the magic-env namespace, and defines its semantics as an extension of the me:env element. A magic envelope can thus be added within existing XML construct, providing a verified copy of the sibling DOM nodes. When a processor sees an me:provenance element, it SHOULD override all sibling information with the verified information from within the envelope. Using the unverified information for any important purpose other than to determine putative delivery destination represents a security risk and SHOULD be avoided whenever possible.
In order to syndicate verified information via existing feed mechanisms, it is useful to augment standard Atom Entry construct. In this case the Magic Envelope elements are contained within an "me:provenance" root element to signal this purpose.
<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <id>tag:example.com,2009:3897938434</id> <author><name>E. Xample</name><uri>acct:firstname.lastname@example.org</uri></author> <content>Verify this content via me:provenance.</content> <title>A verifiable entry.</title> <updated>2009-12-18T20:04:03Z</updated> <me:provenance xmlns:me="http://salmon-protocol.org/ns/magic-env"> <me:data type='application/atom+xml'> PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0nVVRGLTgnPz4KPGVudHJ5IHhtbG5zPS dodHRwOi8vd3d3LnczLm9yZy8yMDA1L0F0b20nPgogIDxpZD50YWc6ZXhhbXBsZS5jb20s MjAwOTpjbXQtMC40NDc3NTcxODwvaWQ-ICAKICA8YXV0aG9yPjxuYW1lPnRlc3RAZXhhbX BsZS5jb208L25hbWUPHVyaT5hY2N0OmpwYW56ZXJAZ29vZ2xlLmNvbTwvdXJpPjwvYXV0a G9yPgogIDx0aHI6aW4tcmVwbHktdG8geG1sbnM6dGhyPSdodHRwOi8vcHVybC5vcmcvc3l uZGljYXRpb24vdGhyZWFkLzEuMCcKICAgICAgcmVmPSd0YWc6YmxvZ2dlci5jb20sMTk5O TpibG9nLTg5MzU5MTM3NDMxMzMxMjczNy5wb3N0LTM4NjE2NjMyNTg1Mzg4NTc5NTQnPnR hZzpibG9nZ2VyLmNvbSwxOTk5OmJsb2ctODkzNTkxMzc0MzEzMzEyNzM3LnBvc3QtMzg2M TY2MzI1ODUzODg1Nzk1NAogIDwvdGhyOmluLXJlcGx5LXRvPgogIDxjb250ZW50PlNhbG1 vbiBzd2ltIHVwc3RyZWFtITwvY29udGVudD4KICA8dGl0bGUU2FsbW9uIHN3aW0gdXBzdH JlYW0hPC90aXRsZT4KICA8dXBkYXRlZD4yMDA5LTEyLTE4VDIwOjA0OjAzWjwvdXBkYXRl ZD4KPC9lbnRyeT4KICAgIA </me:data> <me:encoding>base64url</me:encoding> <me:alg>RSA-SHA256</me:alg> <me:sig> EvGSD2vi8qYcveHnb-rrlok07qnCXjn8YSeCDDXlbhILSabgvNsPpbe76up8w63i2f WHvLKJzeGLKfyHg8ZomQ </me:sig> </me:provenance> </entry>
A Magic Envelope JSON data structure may be embedded within any JSON structure. When this is done to verify the provenance of associated data by augmenting an existing object, the object SHOULD use the key name "provenance" for the object containing the Magic Envelope fields, with the semantics as described above.
This section describes the steps used to verify a salmon once received. In each step, there is a specified error code to be used if the server wishes to inform the client about the error; the server is NOT REQUIRED to inform clients of errors and MAY simply return 202 Accepted to complete the request at any time. The verification checks are:
Salmon uses the Atom entry id mechanism to help filter out duplicates. Since salmon can be syndicated in arbitrary ways, including loops, it is very important that co-operating systems can reliably signal whether a given salmon is an exact or approximate duplicate of another. Salmon relies on the built in Atom id mechanism as the primary mechanism, with the Atom crosspost extension [Crosspost] (Atkins, M., “Atom Cross-posting Extensions I-D,” .) as an override when the primary mechanism is not available. The rest of this section refers to the globally universally unique ID determined by this process as the entry's guid.
Security note: When dealing with any entry which includes me:provenance, processors MUST determine the guid from the information within the signed provenance data rather than the unsigned top-level entry.
The steps for determining the guid for an entry are:
The salmon guid is also used to determine the proper action to take on receipt of a salmon. There are three cases:
An update in which the new and old authors do not match SHOULD be rejected with a 403 Unauthorized error. If the recipient has additional information (e.g., it knows that the new and old author ids are aliases) it MAY allow such updates as special cases.
If a server completes the verification steps and wishes to inform the client about the success, it SHOULD respond with either a 202 Created (if the salmon is new), or 200 OK (if the salmon is an update or delete). The server MAY provide a Location: header to inform the client of the published location of the resulting Atom entry on the server.
The goal of these requirements is to allow Salmon endpoints, generators, and syndicators to co-operate to present a unified view of the distributed conversation around a topic represented by a feed entry.
A common use case is for a salmon to be syndicated in a consolidated reply feed with all other replies to a parent entry. Specifically, the common feed mechanism is to publish a link with rel="replies" on the parent entry, which points at an Atom feed of replies ([RFC4685] (Snell, J., “Atom Threading Extensions,” September 2006.)). A service which wishes to re-syndicate salmon in this way SHOULD syndicate the salmon in the rel="replies" feed. Note that services MAY re-syndicate salmon in other feeds.
Services MUST NOT re-syndicate reply salmon which fail the verification process (Section 8 (Salmon Verification Requirements)).
Services MUST maintain the me:provenance element [MagicSig] (Panzer, J., Laurie, B., and D. Balfanz, “Magic Signatures,” .) originally sent by the salmon generator in the re-syndicated entry. This is used to re-verify the salmon as needed by downstream third parties, to ensure correct de-duplication, and in particular is important to allow verification of authorship without depending on an intermediary.
Services SHOULD either maintain the atom:id specified by the salmon generator, or use the crosspost:source/id of [Crosspost] (Atkins, M., “Atom Cross-posting Extensions I-D,” .) to maintain the original id. Note that the me:provenance element will convey this information in any case, and it overrides unsigned information for Salmon-aware processors.
Users SHOULD be made aware of and give effective consent to the publishing scope of their salmon content prior to and after publication. The details of this user experience is both outside the scope of this document and will vary by content type and application. As with security, Salmon generators and receivers SHOULD follow best current practices when implementing the user experience.
Salmon is fully compatible with Activity Streams [AAE] (Atkins, M., Recordon, D., Messina, C., Keller, M., Steinberg, A., and R. Dolin, “Atom Activity Extensions (Draft),” .) Salmon MAY be activities, by having at least one activity:verb child element and one or more activity:object child elements. Salmon endpoints SHOULD accept appropriate activity verbs. Salmon endpoints MAY reject unsupported activities. Note that a Salmon endpoint which is not aware of activity streams may simply accept and store (via the provenance element) the activity in question, but will treat it as a basic Atom entry.
If an activity verb is included in a salmon reply, the 'Post' Verb is the most appropriate generic verb to use. Other verbs are possible and salmon generators SHOULD use the most specific verb they can identify for their use case.
Nearly any activity verb could be appropriate for a salmon mention Section 3.3 (Salmon Links for Mentions). The 'Post', 'Share', 'Save', and 'Start Following' verbs [AABS] (Atkins, M., Recordon, D., Messina, C., Keller, M., Steinberg, A., and R. Dolin, “Atom Activity Base Schema (Draft),” .) are particularly pertinent and salmon generators SHOULD use the most specific verb they can identify.
This document is the outcome of meetings and feedback from a large number of people. In particular, feedback from the Federated Social Web, Webfinger, OAuth, Activity Streams, and Salmon Protocol communities has been invaluable. Some of the people who contributed to this effort are:
Bob Aman, Dirk Balfanz, Darren Bounds, Charlie Cauthen, DeWitt Clinton, George Fletcher, Hunter Freyer, Eran Hammer-Lahav, Timothy Jordan, Ben Laurie, Mike Macgirvin, James Manger, Sean McCullough, Breno de Medeiros, Chris Messina, Will Norris, Ade Oshineye, NeilFred Piccolo, Evan Prodromou, Arne Roomann-Kurrik, Brett Slatkin, Joseph Smarr, James Snell, Brian Stoler, James Walker, Stephen Paul Weber, Bob Wyman.
The authors apologize for any omissions from this list, which are certainly unintentional.
This document defines the new "salmon", "mentioned", "salmon-signer" link relations; these values are registered via the procedures documented in RFC 5988 (Nottingham, M., “Web Linking,” October 2010.) [RFC5988]. Therefore, this document has no IANA actions.
A primary concern with this type of distributed protocol is how to prevent spam and abuse. The protocol provides building blocks to allow services to implement in-depth defense against attacks, but is not itself a defense. Specifically, every salmon has verifiable author, associated author identity provider identifier, and generator identifier URIs. It also incorporates timestamps in the signed data. Since POSTing a salmon to a Salmon endpoint is idempotent from a security point of view, replay attacks can be treated similarly to DOS attacks.
Note that Salmon ties the salmon guid to the author identifier for purposes of updating, replacing, or de-duping content. Thus, poisoning a salmon repository with forged guids requires also forging Magic Signatures, or gaining control of the original author's signing keys.
It is possible to outsource salmon verification or to delay verification until after salmon have already been processed (or published). Salmon receivers should carefully consider the security implications of doing so for the content they are processing.
Salmon depends on the Magic Signatures [MagicSig] (Panzer, J., Laurie, B., and D. Balfanz, “Magic Signatures,” .) specification for its basic verification steps. Beyond that, it is RECOMMENDED that salmon recipients utilize best current anti-abuse practices, including implementing rate limiting of authors, identity providers, and generators, and in-depth spam and abuse control of the verified content.
|[AABS]||Atkins, M., Recordon, D., Messina, C., Keller, M., Steinberg, A., and R. Dolin, “Atom Activity Base Schema (Draft).”|
|[AAE]||Atkins, M., Recordon, D., Messina, C., Keller, M., Steinberg, A., and R. Dolin, “Atom Activity Extensions (Draft).”|
|[Crosspost]||Atkins, M., “Atom Cross-posting Extensions I-D.”|
|[LRDD]||Eran, E., “LRDD: Link-based Resource Descriptor Discovery.”|
|[MagicSig]||Panzer, J., Laurie, B., and D. Balfanz, “Magic Signatures.”|
|[RFC2119]||Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels,” BCP 14, RFC 2119, March 1997 (TXT, HTML, XML).|
|[RFC4287]||Nottingham, M., Ed. and R. Sayre, Ed., “The Atom Syndication Format,” RFC 4287, December 2005 (TXT, HTML, XML).|
|[RFC4685]||Snell, J., “Atom Threading Extensions,” RFC 4685, September 2006 (TXT).|
|[RFC5988]||Nottingham, M., “Web Linking,” RFC 5988, October 2010 (TXT).|
|[Tombstones]||Snell, J., “The Atom "deleted-entry" Element.”|
|[WebLinking]||Nottingham, M., “Web Linking I-D, draft 7.”|
|[Webfinger]||Fitzpatrick, B., Hammer-Lahav, E., Cook, B., Panzer, J., and J. Gregorio, “The Webfinger Protocol.”|
|[XRD]||Hammer-Lahav, E. and W. Norris, “Extensible Resource Descriptor (XRD) Version 1.0, Working Draft 13.”|
Feedback on this specification is thus welcomed via the salmon mailing list, email@example.com. For more information, see the Salmon discussion group.
|1600 Ampitheatre Parkway|
|Mountain View, CA|