diff --git a/fep/ae97/fep-ae97.md b/fep/ae97/fep-ae97.md index b2f2a93..3f2e32a 100644 --- a/fep/ae97/fep-ae97.md +++ b/fep/ae97/fep-ae97.md @@ -1,10 +1,10 @@ --- slug: "ae97" -authors: silverpill +authors: silverpill <@silverpill@mitra.social> status: DRAFT dateReceived: 2023-08-14 trackingIssue: https://codeberg.org/fediverse/fep/issues/148 -discussionsTo: https://codeberg.org/fediverse/fep/issues/148 +discussionsTo: https://socialhub.activitypub.rocks/t/fep-ae97-client-side-activity-signing/3502 --- # FEP-ae97: Client-side activity signing @@ -14,117 +14,56 @@ Existing Fediverse servers manage signing keys on behalf of their users. This pr ## History -Section [4.1 Actor objects](https://www.w3.org/TR/activitypub/#actor-objects) of ActivityPub specification mentions two endpoints, `provideClientKey` and `signClientKey`. The exact interface is [not specified](https://github.com/w3c/activitypub/issues/382), but the purpose of these endpoints is likely similar to the ones described in this proposal. +[Initial version](https://codeberg.org/fediverse/fep/src/commit/fc9c65daca267be9f91761ed854eac9e829222a2/fep/ae97/fep-ae97.md) of this proposal relied on linking of cryptographic identities to actor objects via [FEP-c390] identity proofs. That mechanism was superseded by [FEP-ef61] which achieves full data portability. ## Requirements 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][RFC-2119]. -## Discovering endpoints +## Registering an actor -To begin communicating with the server, client MUST discover registration endpoints by sending an HTTP GET request to `/.well-known/activitypub`. +Client creates portable actor objects according to [FEP-ef61] and stores them. -The server MUST respond with a JSON document containing URLs of these endpoints: +Before registering a portable actor on the server, the client MUST generate an RSA key and attach it to actor object via `publicKey` property, and also add it to the `assertionMethod` array as described in [FEP-521a]. Then it MUST add the server URL to the `gateways` array of the actor object. -- `registerIdentity`: the endpoint required for registering identity. -- `verifyIdentity`: the endpoint required for verifying identity. +To register the actor, the client MUST send an HTTP POST request to the gateway endpoint at `/.well-known/apgateway` path. The body of the request MUST be an actor object. The request MUST have an `X-Rsa-Secret-Key` header containing the previously generated RSA secret key in `secretKeyMultibase` format described in section *2.3.1.2 Multikey* of [Data Integrity](https://www.w3.org/TR/vc-data-integrity/#multikey) specification. -Example: - -```json -{ - "registerIdentity": "https://server.example/register_identity", - "verifyIdentity": "https://server.example/verify_identity" -} -``` - -## Creating an actor - -To create an actor, the client MUST send an HTTP POST request to `registerIdentity` endpoint. The body of the request MUST be a JSON document with the following properties: - -- `subject`: the identity of the user, in the form of a [Decentralized Identifier][DID] (DID). -- `preferredUsername`: the preferred username. - -Example: - -```json -{ - "subject": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2", - "preferredUsername": "alice" -} -``` - -If request is valid, server MUST generate actor ID and return it to the client. - -Example: - -```json -{ - "id": "https://server.example/users/alice" -} -``` - -The client MUST create a [FEP-c390][FEP-c390] identity proof and send it in a POST request to `verifyIdentity` endpoint. - -If identity proof is valid, the server MUST create a new actor document, and attach provided identity proof to it. - -Example: - -```json -{ - "type": "VerifiableIdentityStatement", - "subject": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2", - "alsoKnownAs": "https://server.example/users/alice", - "proof": { - "type": "DataIntegrityProof", - "cryptosuite": "eddsa-jcs-2022", - "created": "2023-02-24T23:36:38Z", - "verificationMethod": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2", - "proofPurpose": "assertionMethod", - "proofValue": "..." - } -} -``` - -**WARNING: The example above uses eddsa-jcs-2022 cryptosuite, which doesn't have stable specification.** +If the server accepts registration request, its response MUST have `201 Created` status code. ## Sending activities -The client MUST sign all activities by adding [FEP-8b32][FEP-8b32] integrity proofs to them. The `verificationMethod` property of integrity proof MUST correspond to the `subject` of one of identity proofs attached to an actor. +Client submits signed [FEP-ef61] activities to actor's outbox. Contrary to what ActivityPub specification prescribes in section [6. Client to Server Interactions](https://www.w3.org/TR/activitypub/#client-to-server-interactions), the server MUST NOT overwrite the ID of activity. Instead of assigning a new ID, the server MUST verify that provided ID has not been used before. If activity ID is in compatible format (HTTP(S) URI), the server MUST check that its [origin](https://developer.mozilla.org/en-US/docs/Glossary/Origin) is the same as the server's origin. If the server accepts activity, its response MUST have `202 Accepted` status code. -Client submits signed activities to actor's outbox. Contrary to what ActivityPub specification prescribes in section [6. Client to Server Interactions](https://www.w3.org/TR/activitypub/#client-to-server-interactions), the server MUST NOT overwrite the ID of activity. Instead of assigning a new ID, the server MUST verify that provided ID has not been used before. If activity ID is an HTTP(S) URI, the server MUST check that its [origin](https://developer.mozilla.org/en-US/docs/Glossary/Origin) is the same as the server's origin. The server MAY put additional constraints on the structure of activity IDs if necessary. +If activity contains a wrapped object (as in `Create` and `Update` activities), it MUST be a portable object created according to [FEP-ef61]. The server MUST validate object IDs in the same way it validates activity IDs. -If activity contains a wrapped object (as in `Create` and `Update` activities), and the object is not transient, it MUST be signed as well. The server MUST validate object IDs in the same way it validates activity IDs. +The server MUST deliver activities to their indended audiences without altering them. -The server MUST deliver activities to their indended audiences without altering them. Recipients of signed activities (including the actor's server) MUST verify integrity proofs on them. If verification method of the integrity proof doesn't match any of FEP-c390 identity proofs attached to the actor, the activity MUST be rejected. +## Receiving activities -## Compatibility +Client receives activities by polling the actor's inbox. -To maintain interoperability with existing software, the server MAY generate a private key for each actor to sign Server-To-Server HTTP requests. +Requests to inbox endpoint MUST have an HTTP signature created using the RSA secret key generated during registration. -If recipient supports FEP-8b32, and both HTTP signature and integrity proof are present, the integrity proof MUST be given precedence over HTTP signature. +## Implementations -## Server independent IDs - -Object IDs can be derived from user's identity. - -This idea is described in more detail in [FEP-ef61: Portable Objects][FEP-ef61]. +- [fep-ae97-client](https://codeberg.org/silverpill/fep-ae97-client) (client) +- Mitra (server) ## References - Christine Lemmer Webber, Jessica Tallon, [ActivityPub][ActivityPub], 2018 - S. Bradner, [Key words for use in RFCs to Indicate Requirement Levels][RFC-2119], 1997 -- Manu Sporny, Dave Longley, Markus Sabadell, Drummond Reed, Orie Steele, Christopher Allen, [Decentralized Identifiers (DIDs) v1.0][DID], 2022 - silverpill, [FEP-c390: Identity Proofs][FEP-c390], 2022 -- silverpill, [FEP-8b32: Object Integrity Proofs][FEP-8b32], 2022 - silverpill, [FEP-ef61: Portable Objects][FEP-ef61], 2023 +- silverpill, [FEP-521a: Representing actor's public keys][FEP-521a], 2023 +- Dave Longley, Manu Sporny, [Verifiable Credential Data Integrity 1.0][DataIntegrity], 2023 [ActivityPub]: https://www.w3.org/TR/activitypub/ [RFC-2119]: https://tools.ietf.org/html/rfc2119.html -[DID]: https://www.w3.org/TR/did-core/ [FEP-c390]: https://codeberg.org/fediverse/fep/src/branch/main/fep/c390/fep-c390.md -[FEP-8b32]: https://codeberg.org/fediverse/fep/src/branch/main/fep/8b32/fep-8b32.md [FEP-ef61]: https://codeberg.org/fediverse/fep/src/branch/main/fep/ef61/fep-ef61.md +[FEP-521a]: https://codeberg.org/fediverse/fep/src/branch/main/fep/521a/fep-521a.md +[DataIntegrity]: https://www.w3.org/TR/vc-data-integrity/ ## Copyright