Mayel is a user on You can follow them or interact with them if you have an account anywhere in the fediverse.
Mayel @mayel

I've started putting together a list of apps, focused on implementations of , documenting their status and what tech stack they're (being) built with:

This is a publicly editable doc, so would appreciate corrections/additions, and feedback especially from fediverse devs, but also from instance admins and users:

- What app/implementation/stack did you try?
- Pros/cons you encountered
- What stack & libraries would you choose if starting today?

ยท 37 ยท 38
@mayel fontina dev here

it's worth noting fontina is on hiatus at the moment while I'm working on Pubstomp, a generic AP backend server that fontina is going to be built on top of down the line that uses golang and dgraph as a DB

PS. We've been talking with @bhaugen and others about the need for a generic agent-centric server, so that instead of signing up to a bunch of different servers, a user could have their indentity and data all in one place, and all the apps they use (clients, but if necessary server-side "plugins" as well) would interact with the activity/objects types that they support.

What do you think?

cc @cwebber @aaronpk @deadsuperhero @aral

@mayel @aral @deadsuperhero @aaronpk @cwebber @bhaugen totally. We need an ID that we can migrate from service to service. OpenID plus more.

Right now my data is spread. My identity is spread. And frankly I don't own my ID. If I wanted to migrate instances I'm at the mercy of the instance admins.

@thinkMoult @bhaugen @cwebber @aaronpk @deadsuperhero @aral @mayel

Paradoxically, it seems to me that if we'd like to have *safe* SSO, we'd need a decentralized solution.

@mayel @cwebber couldn't that be solved by various fedi services using each other as oauth providers?

@valerauko @cwebber

That would be handy for easier authentication, but the agent-centric server approach would also give the user total control over their identity and private data (at least for those with a domain name and self-hosting, though this could be provided as a service for non-technical folks too.)

@mayel @aral @deadsuperhero @aaronpk @cwebber @bhaugen

wouldn't this cause bottlenecks in the network? Like: imagine your identity is stored on a server that goes down when you most need it. Could this be mitigated by some form of cross-server data propagation/mirroring, just like different torrent trackers can index the same torrent file?

@Antanicus @cwebber @aaronpk @deadsuperhero @aral @mayel

> imagine your identity is stored on a server that goes down when you most need it.

1. That's a problem in any radically decentralized architecture. SSB handles it by gossip replication and resyncing, that is tolerating offline situations.
2. Can also happen in a federated architecture like Mastadon where your identity is stored on one server with a bunch of others. That server can also do down.

@bhaugen @mayel @aral @deadsuperhero @aaronpk @cwebber

> That server can also do down

- it sure can, but going down will not affect any other instance. But what happens if a hypothetical service holding the identities of thousands of users across the whole fediverse goes down? I'm not being negative, I'm just curious :)

@Antanicus @cwebber @aaronpk @deadsuperhero @aral @mayel

Now (just talking and thinking stage) is the best time to be negative.

> a hypothetical service holding the identities of thousands of users

That's not what I am thinking about, anyway. I'm thinking about combos of people who host their own identity and community-oriented servers that might host identities for community members who do not want to host their own.

@mayel @aral @deadsuperhero @aaronpk @cwebber @Antanicus

So not that different from the fediverse that exists, and compatible with the fediverse that exists.

@Antanicus @cwebber @aaronpk @deadsuperhero @aral @mayel

When I looked at Pleroma instances, I saw a lot of single-person self-hosted sites.

@bhaugen @Antanicus @cwebber @aaronpk @deadsuperhero @aral @mayel I'm not interested in identity (singular), controlling it or otherwise. But I do want to build tech that protects personhood and however many identities we decide to have :)

@aral @mayel @deadsuperhero @aaronpk @cwebber @Antanicus

We're also good with multiple identites, but if we want to have one identity and use it in lots of AP contexts, we want to be able to do that. And we are definitely looking for a P2P architecture.

@Antanicus @cwebber @aaronpk @deadsuperhero @aral @mayel @bhaugen No different than going down. A generic AP server would host the Actors and their posts snd followings. Unless you had client-side caching like an email client, you will lose access to your data, and you certainly can't send/receive.

Then distributed copies(like IPFS or DAT do) of the database are the only way...

@bhaugen @mayel @aral @deadsuperhero @aaronpk @cwebber

@Antanicus @bhaugen Not necessarily. That would be a distributed system as opposed to a federated one. ActivityPub is not meant to be a database in itself, it's a traversable graph that can be converted to a local database.

You could have a DHT that resolves to a changing URL, but that doesn't really address availability of the content by itself. You'd need a replication strategy like primary/secondary, and then point to URLs so that they can be tried in-order. Out-of-scope with current AP spec

@bhaugen @Antanicus @cwebber @aaronpk @deadsuperhero @aral @mayel That's why you have an always-on node. I'm exploring the use of DAT for that. See for posts on Web+ and a step in that direction.

@mayel @bhaugen @cwebber @aaronpk @deadsuperhero @aral That's closer to a peer to peer model and it's similar to what we're exploring also. I want to see "instances of one" :)

@mayel @aral @deadsuperhero @aaronpk @cwebber @bhaugen This would be awesome. Reminds me a bit of (dead now). Alternatively we build / borrow a separate auth platform (and run some servers for it) which is integrated into the "standard" AP stack by default.

@mayel That's the direction I wanted to go a year ago with those mockups.

@mayel The fastest path to build a performant server is using the scaffolding already available:

See here progress about feature set, what's implemented already and what's still missing:

@h That's definitely what I'd rather do. Have you played around with that library? Opinions?

@mayel It's not complete but it's the best thing available out there today. It's actively maintained and the lead developer is here on Mastodon (going to look up what was their account).
It's not Ruby but a single static binary daemon written in Go could make up for the complexities of maintaining a Mastodon server.

I think I read somebody else was starting a similar project in Rust, but that's probably going to be less accessible code and it's going to take a while to get to completion.

@mayel You've probably talked to @cj before of the go-fed project.
I think the code is promising and it contains some scaffolding that makes the prospect of writing a proper server far less challenging than it would be the case if you started from scratch with say... C++.

@h @mayel I'm happy to answer any specific questions, including discussing limitations of the current library. I've tried to be honestly thorough in the GitHub issues, although please ignore the GitHub milestones, I need to redo those.

A basic tutorial and the library's documentation are also available at

@remotenemesis Thanks! I'm not a front end JS kind of person so plain HTML and CSS it is.

@cj @h

I am very interested if/how the library supports extensions, as that's a key requirement for a couple projects for which I'm looking for the best implementation approach, and your docs say that "ActivityStreams vocabulary supports extensions beyond the Core and Extended types. However, this will be outside the scope of this tutorial"

@mayel @h Gotcha. go-fed could do it, but involves a few hours of time to make 2 code changes.

1) In the tool used to auto-generate the ActivityStreams implementation.

2) The go-fed/activity/pub library also would need to pass-through any new Activities defined in this way.

I'm gonna go ahead and capture both in github issues.

What kinds of extensions are you looking at, specifically?

@mayel OK, I've given it some serious thought and have created two issues to track this work:


In all honesty the work is larger than my gut feel (isn't it always?!) so I've scheduled it as part of the next major version release. I don't have a great sense as to when that will be (on order of months given my current life schedule) so I understand if you eliminate go-fed as a choice because of that.


It always is! Thanks a lot for giving it thought and documentating the issues :)

This still will require hardcoding the extensions pre-compilation, right? That's fine for most use cases but wouldn't work for a "generic server" that can support any activities/objects as in:

@mayel You're right. Creating a generic Go server would mean either: raw map[string]interface{} handling (no static typing, still having to code, compile, deploy) or plugging in a scripting engine (no static typing, still having to code and deploy). I decided to do static typing + code + compile + deploy. I haven't seen another compelling way for "generic" handling of ActivityPub data in a statically-typed language. The core problem is that while the data is generic, behavior isn't.

@mayel (Unless of course it is generic behavior desired: proxy-ing, etc. Then some partial deserialization into an ActivityStreams type could occur, if any deserialization is required at all. Go-fed currently does some form of partial deserialization by preserving unrecognized properties, but it's not exactly the same use case).

@cj @h

One project is for which we need extensions related to educational resource metadata.

Ther other is for which we'll need extensions related to economic activities, adapting to ActivityStreans.

@mayel @h Thanks! I am aware of ValueFlows thanks to @bhaugen, and this is the first I've heard of the Moodle one. So I will need to look into that one and keep both on my radar.

@bhaugen @cwebber @aaronpk @deadsuperhero @aral @mayel

I basically came up with the idea of using SSH logins. the public key is shared across multiple instances, the private key is kept private at all times. when you login to one instance, the public key is NOT used to scrape other instances, but rather the instance itself keeps track of the instances you signed up with. (this is part of the trust mechanism)

@bhaugen @cwebber @aaronpk @deadsuperhero @aral @mayel

the trust mechanism works by giving other instances your instances. basically each one of your instances would send a message, signed by you, to the "new" instance (where you want an account). this instance would then remember those other instances, and those instances would remember the new instance.

this can be bad, so there needs to be an opt-out mechanism. this opt-out mechanism would prevent you from logging in between 2 instances you opted-outof

@bhaugen @cwebber @aaronpk @deadsuperhero @aral @mayel

but if you have more logins than those 2 instances, those could still potentially see them and you'd still eventually login everywhere. this trust system can also be used to allow you to even make an account, as an anti-spam mechanism.

so I guess both the public and private keys are kept mostly safe.

@bhaugen @cwebber @aaronpk @deadsuperhero @aral @mayel

anyway the useful features here are:

- your login details are NOT shared with instances. because it's a private key. sure, it's a KDF based on username/password, but still it's not shared.

- it logins you everywhere, regardless of where you first login!

- it attempts to prevent spam, by having a trust mechanism. (instances may be invite-only or manual-approval. trusted instances are selected by admins.)

@bhaugen @cwebber @aaronpk @deadsuperhero @aral @mayel

but due to username/password -> KDF -> public/private key pair, password resets aren't really a thing. that's the biggest disadvantage. that's the caveat I'm trying to fix and I don't know how to fix it.

@mayel hey for Pinafore, the frontend stack is Svelte/Sapper

@mayel Dev for @cloutstream here. Stack is Laravel.

@dansup is using the same for @pixelfed

@mwpdx @pixelfed @dansup

Are you creating a shared library?

@Mayel @Dion Moult - on nomadic identity. :-)

@Mike Macgirvinย ย is close to completing version 6 of the Zot protocol, see for details. If you are familiar with Hubzilla, you know what is possible with Zot, but Zot 6 differs from previous versions in some respects, building on what has been learned about providing decentralized publishing with privacy and nomadic identity over the last 10 years.

Differences from earlier Zot versions

- Streamlined communications using direct (push) transfer. Earlier versions used a 'notify/pickup' delivery model.
- The authentication component (Magic-Auth) has been spun off into a separate and independent specification 'OpenWebAuth'.
- Inclusion of ActivityStreams (JSON-LD) as a supported (primary) serialisation.
- Dropping the requirements for implementations to support secondary serialisations.
- Moving service discovery to "Accept-header" based service endpoints; where different representations can be selected by modification of the HTTPS request Accept: header.
- Separation of the "portable-id" from the signature algorithm used.

Differences between Zot and other WebMTA services

Zot is architecturally different from other HTTPS-based "social communications" protocols such as OStatus, ActivityPub, and Diaspora. The primary differences are:

- Support for nomadic identity where an identity is not permanently bound to a DNS server.
- MUAs built on top of Zot are able to use and express detailed cross-domain permissions.
- Encryption negotation for additional message protection in addition to HTTPS
- Zot does not define an absolute payload format for content. Implementations MUST support ActivityStreams. Additional message types and serialisation formats MAY provide vendor specific enhancements.
- Federation between other WebMTA protocols is not hampered by unnecessary restrictions on 3rd party communications. Messages from incompatible systems may be relayed to other sites which do not support the 3rd party protocol.
- Detailed delivery reporting is provided for auditing and troubleshooting; which is critical in a distributed communications service.

Here's a followup to this thread (TLDR: we've decided to build with Elixir, starting by forking Pleroma to create a set of libraries):

@mbajur @prismo

@mayel hi, @prismo dev here!

I'm using Ruby on Rails stack for prismo development and i'm pretty happy with it. The biggest pro of using it is that mastodon is based on RoR as well so i can use a lot of code from it. On the other hand, ruby ecosystem lacks any libraries dedicated to work with AP so it's all about taking a lot of small pieces from mastodon and refactoring them for my needs.

When prismo is stable and ready, i would really love to make some ruby lib to make working with AP easier

@mayel just wanna point out that funkwhale is more of a soundcloud alternative than a spotify one. the top 2 comparisons should be grooveshark and soundcloud. (gpm is a half-comparison because it lets you upload your own tracks)

@mayel (i'd edit myself but etherpad doesn't scroll on mobile)

@trwnh @mayel I also have ethercalc issues. When I try to Archive the document, returns "Page cannot be displayed due to robots.txt."

@sebboh @trwnh looks like ethercalc site admins are not allowing docs to be indexed, maybe export as open office file instead ?