diff --git a/FEDERATION.md b/FEDERATION.md index 7065802..1637ba8 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -85,3 +85,151 @@ Per-project inbox, to which projects receive ticket comments from other servers. If someone on another server publishes a comment on your project, then your project will receive the comment at this endpoint and the comment will be displayed when you visit the ticket page. + +## Spec + +Federation in Vervis is done using ActivityPub. Below comes a description of +the details that aren't already common on the Fediverse. The details are +written informally in the form of short simple proposals. + +### (A) Authentication + +Vervis uses HTTP Signatures to authenticate messages received in inboxes. The +Host, (request-target), Date and Digest headers are required to be present and +used in the signature, and the Digest header must be verified by computing the +hash of the request body. Other headers may need signing too, as specified in +the proposals below. + +The `publicKeyPem` field maps to the PEM encoding of the key. The PEM encoding +contains not just the key itself, but also a code specifying the key type. The +Fediverse de-facto standard is RSA, more precisely PKCS#1 v1.5, and used with +the SHA-256 hash algorithm. This is often referred to as RSA-SHA256. + +If the `algorithm` is specified in the Signature header, it must match the key +type in the PEM. But `algorithm` isn't required, and we should probably stop +using it. + +#### (1) Actor key(s) in a separate document + +Allow an actor's signing key to be a separate document, rather than embedded in +the actor document. In Vervis, the use of that is for server-scope keys (see +proposal below), but otherwise, an embedded key is just as good. + +``` +GET /users/aviva/keys/key1 + +{ "@context": "https://w3id.org/security/v1" +, "@id": "https://example.dev/users/aviva/keys/key1" +, "@type": "Key" +, "owner": "https://example.dev/users/aviva" +, "publicKeyPem": "-----BEGIN PUBLIC KEY----- ..." +} + +GET /users/aviva + +{ "@context": + [ "https://www.w3.org/ns/activitystreams" + , "https://w3id.org/security/v1" + ] +, "id": "https://example.dev/users/aviva +, "type": "Person" +, "preferredUsername": "aviva" +, "name": "Aviva" +, "inbox": "https://example.dev/users/aviva/inbox" +, "outbox": "https://example.dev/users/aviva/outbox" +, "publicKey": "https://example.dev/users/aviva/keys/key1" +} +``` + +Authentication requirements: + +- The `keyId` from the signature header matches the `@id` in the document you + receive +- The and key and the owner actor IDs are on the same host +- They key specifies the `owner`, and the owner actor's `publicKey` links back + to the key + +#### (2) Multiple actor keys + +Allow an actor to specify more than one key, or no key at all. This means that +when you examine the owner actor of the key, you verify the actor links back to +the key by checking that the key is listed among the actor's keys (instead of +requiring/expecting only a single key to be specified by the actor). + +The reason this is used in Vervis is for key rotation using a pair of +server-cope keys (see proposal below). + +When used along with proposal A.1, each key may be either embedded in the +document, or a URI specifying the ID of a key defined in a separate document. + +Actors that never need to post activities can simply not specify any keys at +all. + +``` +GET /users/aviva + +{ "@context": + [ "https://www.w3.org/ns/activitystreams" + , "https://w3id.org/security/v1" + ] +, "id": "https://example.dev/users/aviva +, "type": "Person" +, "preferredUsername": "aviva" +, "name": "Aviva" +, "inbox": "https://example.dev/users/aviva/inbox" +, "outbox": "https://example.dev/users/aviva/outbox" +, "publicKey": + [ { "id": "https://example.dev/users/aviva#main-key" + , "type": "Key" + , "owner": "https://example.dev/users/aviva" + , "publicKeyPem": "-----BEGIN PUBLIC KEY----- ..." + } + , "https://example.dev/users/aviva/extra-keys/extra-key1" + , "https://example.dev/users/aviva/extra-keys/extra-key2" + ] +} +``` + +#### (3) Server-scope actor key + +#### (4) Actor key expiration and revocation + +#### (5) Ed25519 actor keys + +#### (6) Key rotation using a pair of server-scope keys + +### (B) ActivityPub + +#### (1) Non-actor audience + +#### (2) Authenticated inbox forwarding + +#### (3) Non-announced following + +#### (4) Object nesting depth + +#### (5) Object capability authorization tokens + +### (C) ForgeFed + +#### (1) Actors + +#### (2) Authorization and roles + +#### (3) Comments + +#### (4) Tickets + +#### (5) Patches + +#### (6) Merge requests + +#### (7) Commits + +#### (8) Forks + +#### (9) SSH keys + +#### (10) Pushes + +#### (11) Avatars