├── p2p ├── example │ └── social-ns │ │ ├── mike-ss │ │ └── activitystar │ │ │ └── 1.0 │ │ │ └── default │ │ │ ├── actor.yaml │ │ │ └── outbox │ │ │ ├── direct │ │ │ └── hash-expand-lea-bob │ │ │ │ └── 2024 │ │ │ │ └── 03 │ │ │ │ └── 21 │ │ │ │ ├── 1711062426.private.yaml │ │ │ │ └── 1711062618.yaml │ │ │ ├── public │ │ │ └── 2024 │ │ │ │ └── 03 │ │ │ │ └── 21 │ │ │ │ ├── 1711062933.like.yaml │ │ │ │ └── 1711060851.first-post.yaml │ │ │ └── followers │ │ │ └── 2024 │ │ │ └── 03 │ │ │ └── 21 │ │ │ └── 1711061958.secret.yaml │ │ └── bob-ss │ │ └── activitystar │ │ └── 1.0 │ │ └── default │ │ └── outbox │ │ ├── public │ │ └── 1711062719.yaml │ │ └── direct │ │ └── hash-expand-bob-lea │ │ └── 2024 │ │ └── 03 │ │ └── 21 │ │ └── 1711062518.yaml ├── activitystreams-vocabulary.md └── README.md ├── README.md └── federation ├── activitypub.md └── README.md /p2p/example/social-ns/mike-ss/activitystar/1.0/default/actor.yaml: -------------------------------------------------------------------------------- 1 | type: Person 2 | 3 | name: Lea 4 | preferredUsername: lea 5 | -------------------------------------------------------------------------------- /p2p/example/social-ns/mike-ss/activitystar/1.0/default/outbox/direct/hash-expand-lea-bob/2024/03/21/1711062426.private.yaml: -------------------------------------------------------------------------------- 1 | type: Note 2 | content: | 3 | Heya Bob 4 | -------------------------------------------------------------------------------- /p2p/example/social-ns/mike-ss/activitystar/1.0/default/outbox/direct/hash-expand-lea-bob/2024/03/21/1711062618.yaml: -------------------------------------------------------------------------------- 1 | type: Note 2 | content: | 3 | Third non-reply message here 4 | -------------------------------------------------------------------------------- /p2p/example/social-ns/mike-ss/activitystar/1.0/default/outbox/public/2024/03/21/1711062933.like.yaml: -------------------------------------------------------------------------------- 1 | type: Like 2 | 3 | object: /social-ns/bob-ss/activitystar/1.0/default/outbox/public/1711062719.yaml 4 | -------------------------------------------------------------------------------- /p2p/example/social-ns/bob-ss/activitystar/1.0/default/outbox/public/1711062719.yaml: -------------------------------------------------------------------------------- 1 | type: Note 2 | content: | 3 | I like things flat! 4 | 5 | The directory structure under outbox/*/ can have arbitrary nesting, only leaves matter 6 | -------------------------------------------------------------------------------- /p2p/example/social-ns/mike-ss/activitystar/1.0/default/outbox/followers/2024/03/21/1711061958.secret.yaml: -------------------------------------------------------------------------------- 1 | type: Note 2 | mediaType: text/markdown 3 | name: To my dearest friends... 4 | content: | 5 | Only my followers can read this! 6 | -------------------------------------------------------------------------------- /p2p/example/social-ns/bob-ss/activitystar/1.0/default/outbox/direct/hash-expand-bob-lea/2024/03/21/1711062518.yaml: -------------------------------------------------------------------------------- 1 | type: Note 2 | content: | 3 | Right back at you Mike! 4 | inReplyTo: /social-ns/mike-ss/activitystar/1.0/default/outbox/direct/hash-expand-lea-bob/2024/03/21/1711062426.private.yaml 5 | -------------------------------------------------------------------------------- /p2p/example/social-ns/mike-ss/activitystar/1.0/default/outbox/public/2024/03/21/1711060851.first-post.yaml: -------------------------------------------------------------------------------- 1 | type: Note 2 | 3 | mediaType: text/markdown 4 | name: First post 5 | content: | 6 | # My first post! 7 | 8 | Hope you like this new social media platform :D 9 | 10 | # id: Is defined as the path to this object, so we don't duplicate it inside the object 11 | # attributedTo: Is defined by the actor this is posted under 12 | # to: Is defined by the specific outbox this is posted under 13 | -------------------------------------------------------------------------------- /p2p/activitystreams-vocabulary.md: -------------------------------------------------------------------------------- 1 | # Activity Vocabulary 2 | 3 | This covers the adaption from https://www.w3.org/TR/activitystreams-vocabulary/ @ https://www.w3.org/TR/2017/REC-activitystreams-vocabulary-20170523/ 4 | 5 | ## 3.1 6 | 7 | ## Follow 8 | 9 | Can be posted to any of the three outbox feeds, depending on desired visibility. 10 | 11 | Clients _MAY_ wish to send this privately? 12 | 13 | ### Update 14 | Not used - updates happen automatically when people update their objects and they get synced 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # activitystar 2 | An adaption of ActivityStreams / ActivityPub to p2p, using Earthstar 3 | 4 | ## Status 5 | 6 | General musings at present... 7 | 8 | ## Why? 9 | 10 | Why use activities / activitypub as a base? 11 | - It offers the potential for some neat bridging, where you can run a relay that speaks both activitypub and earthstar, and anyone who opts in can have their feeds published on activitypub, or conversely can follow people in the fediverse. 12 | - It means less reinventing the wheel - don't need to think about what a Note means, use the existing definitions. 13 | 14 | ## Naming? 15 | 16 | ACTIVITYpub + earthSTAR 17 | 18 | Naming is hard. Tell me if you have a better idea :D 19 | 20 | Two bits at present: 21 | - [The p2p protocol](p2p) 22 | - [Some ideas on federation](federation) 23 | -------------------------------------------------------------------------------- /federation/activitypub.md: -------------------------------------------------------------------------------- 1 | This needs updating... 2 | 3 | # ActivityPub 4 | 5 | This covers the adaption from https://www.w3.org/TR/activitypub/ @ https://www.w3.org/TR/2018/REC-activitypub-20180123/ 6 | 7 | # 3 Objects 8 | 9 | Objects are all available via earthstar, and so are validated at a lower level, before they can be added to the store. 10 | 11 | Clients _SHOULD_ validate that the `id` property 12 | 13 | ## 3.1 Object Identifiers 14 | 15 | All objects have the following properties: 16 | 17 | *id*: The object's unique global identifier, which will always be the Earthstar path of the object in the format `earthstar:////activitystar/1.0/...` 18 | 19 | ## 3.2 Retrieving objects 20 | 21 | Objects aren't retrieved - they're available if they've been synced to the local client, or not. 22 | 23 | Objects are serialized payloads at their earthstar path in the `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` format. 24 | 25 | ## 3.3 The source property 26 | 27 | As per original spec 28 | 29 | # 4 Actors 30 | 31 | ## 4.1 Actor objects 32 | 33 | Earthstar location: `///activitystar/1.0//actor` 34 | 35 | A given author may have one, or multiple actors. These can be thought of as separate feeds 36 | 37 | Attribute differences: 38 | 39 | Example: 40 | 41 | ``` 42 | { 43 | "@context": ["https://www.w3.org/ns/activitystreams", 44 | {"@language": "ja"}], 45 | "type": "Person", 46 | "id": "earthstar:////activitystar/1.0/default/actor", 47 | "following": "earthstar:////activitystar/1.0/default/following.json", 48 | "followers": "earthstar:////activitystar/1.0/default/followers.json", 49 | # "liked": # Not used 50 | # "inbox": # Not used, there's no definition on an inbox in our p2p semantics 51 | "outbox": "earthstar:////activitystar/1.0/default/outbox/", 52 | "preferredUsername": "kenzoishii", 53 | "name": "石井健蔵", 54 | "summary": "この方はただの例です", 55 | "icon": [ 56 | "earthstar:////activitystar/1.0/default/icon.jpg" 57 | ] 58 | } 59 | ``` 60 | 61 | # 5.1 Outbox 62 | 63 | An earthstar URI ending in a / should be interpreted as a prefix, and for the outbox will then follow these conventions, following the Mastodon publishing levels: 64 | 65 | - `outbox/public/.../` 66 | - `outbox/followers/.../` 67 | - `outbox/direct//.../` 68 | 69 | Notes: 70 | - `/.../` Can have any path structure, depending on the writer's needs. readers should use any/all paths under here. 71 | - One pattern might be `outbox/public/yyyy/mm/dd`, allowing for rotating encryption keys etc for private follower only posts etc 72 | - payloads should be encrypted (TODO: spec here, use more general spec?). 73 | 74 | The more interesting one is the `direct` outbox: 75 | - `` is computed as `HKDF-Expand(scalarmult(my_sk, their_pk), "activitystar-direct", 32)`. This allows readers to discover which of the many subfeeds here is theirs. 76 | - You will disclose how many messages and when you send to someone, but not who, or the contents 77 | 78 | 79 | # 5.2 Inbox 80 | 81 | This is not used in our p2p context. Instead clients will dynamically construct appropriate shared channels under the outbox prefix 82 | 83 | # 5.3 Followers Collection 84 | 85 | This should be a serialized Collection. Readers should probably not trust this, and compute their own view from all of the feeds they see 86 | 87 | # 5.4 Following Collection 88 | 89 | This should be a serialized collection. 90 | 91 | # 5.7 Likes Collection 92 | 93 | Not used - readers should compute their own view from the feeds they see 94 | 95 | # 5.8 Shares Collection 96 | 97 | Not used 98 | 99 | # 6 Client to Server Interactions 100 | 101 | These are all out of scope - it's assumed that anyone using this spec will be using a p2p client. 102 | -------------------------------------------------------------------------------- /p2p/README.md: -------------------------------------------------------------------------------- 1 | # p2p protocol 2 | 3 | Check out an [example layout](example) - what the earthstart data structure might look like (Not including encryption, capabilities etc) 4 | 5 | ## How does this compare to Mastodon timelines? 6 | 7 | ### Home timeline 8 | 9 | Much the same - posts from anyone you directly follow 10 | 11 | ### Local / Community 12 | 13 | This is where it differs - I anticipate the existence of ssb-style `pub` servers / earthstar relays. 14 | 15 | Clients would follow a pub, and the pub follows back (pub owner does the moderation here, like a Mastodon server) 16 | 17 | So these posts would all show up in Federated too - but you could have tabs in the client for each of the pubs you follow. 18 | 19 | ### Federated 20 | 21 | All the public posts that you've synced. 22 | 23 | ## Capabilities 24 | 25 | So, we have a data format, but how do people see it? 26 | 27 | Grant capabilities to them! 28 | 29 | - The client app will need to grant capabilities to other identities using the [capability](https://github.com/earthstar-project/application-formats/pull/6) spec. 30 | - So the first cap is the cap for seeing capabilities, then further caps after that 31 | - If you're using one/many relays you'll also want them to have capabilities for everything to sync it, though not necessarily keys 32 | - You want the relay to sync your follower-only messages and DMs, but not decrypt them 33 | - Depending on your level of trust, you might let anyone download everything by granting a public cap, e.g. like SSB. Would mean people can see when you post, but not to who 34 | - It's likely you'll want to grant public access to `/capabilities`, so that can be synced everywhere, and let people pick up the relevant caps for other things 35 | - Also you'll probably want this for your `/actor`, and `/public/...` paths - like in Mastodon, public is public, anyone can see without auth etc. 36 | - Of course how do people get the initial capabilitiy even if it's signed to public? 37 | - Publish it in your `/actor`? 38 | - Ponder, should your list of followers/following also include their public caps to aid discovery? Not sure how else you'd be able to do the follower of follower thing like SSB 39 | 40 | ### Security Levels 41 | 42 | Some ideas on what security levels might look like for an individual user 43 | 44 | #### High security 45 | 46 | - Grant public access to `/capabilities`. This is the cap in your bio, the one you hand out as a link, etc 47 | - Your `/followers` contains a list of the public capability of each of the people you follow 48 | - Your `/following` contains a list of the public capabilitie of each of the people who follow you 49 | - Grant public access to /public 50 | - Grant your followers access to /followers 51 | - Grant individual DM recipients access to individual DM paths 52 | - Allows people to infer the total count of followers & DM recipients you have (because of the issued capabilities) 53 | - Requires you & a follower or DM recipient to be online and have the other as a peer to exchange any data 54 | 55 | #### Medium security 56 | 57 | In addition to the above: 58 | - Grant the relays you're on access to /followers 59 | - (?) Grant your followers access to /direct 60 | - Grant the relays you're on access to /direct 61 | - Allows the relays to see how many & when followers and DM posts happen 62 | - Allows your followers to see how many/when DMs etc 63 | 64 | This feels like it maps to the state of SSB? 65 | 66 | #### Low security 67 | 68 | In addition to the above: 69 | - Grant public access to your entire subspace. 70 | - Allows everyone to read your public posts 71 | - Allows everyone to know how many & when your followers posts are 72 | - Allows everyone to know how many, to how many people & when your DMs are 73 | - Doesn't allow people to read the contents of followers / DMs 74 | - Best usability and reach of your stuff. Potentially allows DM communication across many unknown hops 75 | 76 | ## FAQ 77 | 78 | **Q: Does activitystreams / activitypub constrain this?** 79 | 80 | **A:** Somewhat. Take the types of activities - if you want other people to understand them, then yes, you need to stick with the kinds their software understands. If we made up the protocol from scratch, none of this would be shared. By reusing the definitions of Follow, Notes etc, we can get a lot of the basics for free, in ways other people may already understand. This doesn't stop us making our own types of activites up though - other people will ignore them, but that's fine. And this doesn't need to be standardised up front - anyone can make up a new kind and start using it. 81 | -------------------------------------------------------------------------------- /federation/README.md: -------------------------------------------------------------------------------- 1 | # Federation 2 | 3 | ## Status 4 | 5 | General musings at present... 6 | 7 | ## Federation 8 | 9 | Principles: 10 | - This should be interoperable with the wider fediverse 11 | - Consent should be respected in line with the current fediverse semantics 12 | 13 | Theory: 14 | - We'll call a server that's running both earthstar and activitypub protocols a bridge node 15 | - From the earthstar side: 16 | - You have to send a `StartFederation` activity to the bridge node's identity 17 | - You _SHOULD_ only be federated with one server at a time (to avoid message duplication in the fediverse) 18 | - From this timestamp on, any activities it sees will be processed the same way they would normally - forwarded on to other servers in the `to` etc 19 | - It'll rewrite any identities into a form suitable for http semantics, e.g. mentions etc 20 | - If it's seen a `StartFederation` for some other identity, it'll use that server's address 21 | - If it's not they'll be left as an earthstar address? 22 | - TODO: `StopFederation`, stops forwarding, leaves identity active 23 | - A future `StartFederation` to another server should have the original one post a final `moved` message - or should the client need to do this BEFORE StopFederation? unsure 24 | - `DeleteFederation` to trash all hosted content? 25 | - This is not a _full_ bridge - it will act the way any other fediverse server works 26 | - If it sees a `Follow` it'll send the follow request to the destination 27 | - If they Reject, forwards that back into earthstar 28 | - If they accept, it'll start publishing their activities into it's local subspace. 29 | - To keep the convention with the way the fediverse works, these activities _MUST_ only be accessible by identities federated with this bridge, e.g. caps and keys 30 | - i.e. bridges should use the High security level. This seems fairly reasonable from a usability standpoint - the bridge is always online. 31 | - The owner of the bridge is responsible for moderation in the same way a fediverse server owner is, e.g. you'll get defederated if you let spam through etc. 32 | - From the activitypub side: 33 | - When it sees activities from a new identity, it creates a new `` for that actor and publishes the activities there. 34 | - It'll grant capabilities so the appropriate people who're using it for federation can access those outboxes. 35 | 36 | Summing up: 37 | - No-one else on the fediverse should see this as any different to a Mastodon instance, for example 38 | - They'll only see a given earthstar identity coming from one place 39 | - Messages they send will only be sent to the people in their followers, or other people on the same instance(bridge), in line with toot visibility 40 | 41 | Caveats: 42 | - Not all earthstar stuff will make it to the fediverse - opt-in by design 43 | - Obviously a bad actor can copy and forward stuff around - but they can do that with activitypub too 44 | - Private messages between earthstar and fediverse participants will be vulnerable to snooping by the bridge owner - same as with a fediverse server 45 | 46 | ### Diagram / Examples 47 | 48 | - Alice has asked `EarthStar Server 2` to be her bridge Node 49 | - Carol has asked `EarthStar Server 1` to be her bridge Node 50 | - Dave is registered on `Mastodon Server 1` 51 | 52 | ```mermaid 53 | 54 | graph LR 55 | 56 | subgraph Always Online 57 | es1{{Earthstar Server 1}} 58 | es2{{Earthstar Server 2}} 59 | md1{{Mastodon Server 1}} 60 | md2{{Mastodon Server 2}} 61 | md1 ---|activitypub| md2 62 | es1 ---|activitypub| md1 63 | es1 ---|activitypub| md2 64 | es2 ---|activitypub| md1 65 | es2 ---|activitypub| md2 66 | end 67 | 68 | Alice ---|earthstar| Bob 69 | Alice ---|earthstar| Carol 70 | Carol ---|earthstar| es1 71 | Alice ---|earthstar| es2 72 | Dave ---|activitypub| md1 73 | Frank ---|activitypub| md2 74 | 75 | ``` 76 | 77 | If I'm Bob, and I publish activities in my public share: 78 | - If Alice follows me, when we're both online or meet up, we can sync using Willow and she'll see my activities 79 | - If Carol follows Alice, then she'll be able to see them too after a sync 80 | - If I grant capabilities / publish a `StartFederation` message to `Earthstar Server 1` - when they sync across, they'll be visible on that server for people to see and interact with. 81 | - If people have followed me in the fediverse, those posts would also be sent on sync to `Mastodon Server 1`, `Mastodon Server 2` as appropriate - wherever someone follows me. 82 | 83 | If I'm Bob, and I write some DMs in my direct messages outbox 84 | - They get synced to whoever I've given capabilities to, e.g. both Alice and Carol. 85 | - If they're encrypted to Carol's key, Alice can't read them, but knows how many & when they were sent. Carol can read them when they're synced, and reply. 86 | - If I've sent them to the key set up by `Earthstar Server 1` on behalf of Dave (Because I've chosen that bridge to federate, and I follow Dave), they get synced with willow until they reach there, then the bridge software sends the activity unencrypted to `Mastodon Server 1`. (Note this is in line with current Fediverse security, not end to end encrypted, but would be over an HTTPS transport etc.). 87 | 88 | 89 | 90 | **Q: Doesn't activitypub mean you have to be always online?** 91 | 92 | **A:** No, but also yes. For the fediverse interopability, the bridge nodes need to be online. These are the pubs of the SSB world. But the clients, and any p2p operation doesn't need to be. If you don't want to federate to/from the fediverse, you don't need to be online at all. 93 | 94 | **Q: With the fediverse stuff, is there any duplication?** 95 | 96 | **A:** Some. The bridge node you've chose should be unique for you - no-one in the fediverse will see your Notes twice. Dave's Notes in the fediverse would get published under different subspaces by both Earthstar servers - however each individual participant in earthstar would only see them once, as you'd only be following a single bridge. 97 | --------------------------------------------------------------------------------