FEP-ae97: Client-side activity signing
by silverpill silverpill@firemail.cc submited on 2023-08-14
Summary
Existing Fediverse servers manage signing keys on behalf of their users. This proposal describes a new kind of ActivityPub client that lets users sign activities with their own keys, and a server that can distribute client-signed activities to other servers.
History
Section 4.1 Actor objects of ActivityPub specification mentions two endpoints, provideClientKey
and signClientKey
. The exact interface is not specified, but the purpose of these endpoints is likely similar to the ones described in this proposal.
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.
Discovering endpoints
To begin communicating with the server, client MUST discover registration endpoints by sending an HTTP GET request to /.well-known/activitypub
.
The server MUST respond with a JSON document containing URLs of these endpoints:
registerIdentity
: the endpoint required for registering identity.verifyIdentity
: the endpoint required for verifying identity.
Example:
{
"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).preferredUsername
: the preferred username.
Example:
{
"subject": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
"preferredUsername": "alice"
}
If request is valid, server MUST generate actor ID and return it to the client.
Example:
The client MUST create a FEP-c390 identity proof and send it in a POST request to verifyIdentity
endpoint.
Example:
{
"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": "z26W7TfJYD9DrGqnem245zNbeCbTwjb8avpduzi1JPhFrwML99CpP6gGXSKSXAcQdpGFBXF4kx7VwtXKhu7VDZJ54"
}
}
If identity proof is valid, the server MUST create a new actor document, and attach provided identity proof to it.
Sending activities
The client MUST sign all activities by adding 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 activities to actor’s outbox. Contrary to what ActivityPub specification prescribes, 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 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), 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. 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.
Compatibility
To maintain interoperability with existing software, the server MAY generate a private key for each actor to sign Server-To-Server HTTP requests.
If recipient supports FEP-8b32, and both HTTP signature and integrity proof are present, the integrity proof MUST be given precedence over HTTP signature.
Server independent IDs
(This section is non-normative.)
Clients may derive object IDs from user’s identity, if chosen DID method supports DID URLs.
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/data-integrity/v1"
],
"type": "Create",
"id": "did:example:123456/actor/c9e7bd01-8bd9-4a8b-99ec-97eb2f7f24ce",
"object": {
"type": "Note",
"id": "did:example:123456/actor/dc505858-08ec-4a80-81dd-e6670fd8c55f",
"attributedTo": "did:example:123456/actor",
"inReplyTo": "did:example:987654/actor/f66a006b-fe66-4ca6-9a4c-b292e33712ec",
"content": "Hello world!",
"to": "did:example:123456/actor/followers",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"created": "2023-02-24T23:36:38Z",
"verificationMethod": "did:example:123456",
"proofPurpose": "assertionMethod",
"proofValue": "..."
}
},
"to": "did:example:123456/actor/followers",
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"created": "2023-02-24T23:36:38Z",
"verificationMethod": "did:example:123456",
"proofPurpose": "assertionMethod",
"proofValue": "..."
}
}
For generative DID methods such as did:key
implementers may attach a list of hosts where ID can be resolved using WebFinger as specified in FEP-4adb.
Example:
This identifier can be looked up using WebFinger:
{
"subject": "did:key:z6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2",
"links": [
{
"rel": "self",
"type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href": "https://server1.example/users/alice"
}
]
}
References
- [ActivityPub] Christine Lemmer Webber, Jessica Tallon, ActivityPub, 2018
- [RFC-2119] S. Bradner, Key words for use in RFCs to Indicate Requirement Levels, 1997
- [Decentralized Identifier] Manu Sporny, Dave Longley, Markus Sabadell, Drummond Reed, Orie Steele, Christopher Allen, Decentralized Identifiers (DIDs) v1.0, 2022
- [FEP-c390] silverpill, FEP-c390: Identity Proofs, 2022
- [FEP-8b32] silverpill, FEP-8b32: Object Integrity Proofs, 2022
- [FEP-4adb] Helge, FEP-4adb: Dereferencing identifiers with webfinger, 2023
Copyright
CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
To the extent possible under law, the authors of this Fediverse Enhancement Proposal have waived all copyright and related or neighboring rights to this work.