faultables

Social Internet: ActivityPub, ATProto dan Nostr

Saya menjalankan instance Mastodon sekitar 3 tahun. Lalu pada suatu waktu di tahun ini, instance tersebut terpaksa saya matikan yang meskipun pada akhirnya diganti dengan instance baru yang sama-sama menggunakan protokol ActivityPub: GoToSocial.

Jika aspek sosial dari internet hanyalah tentang microblogging, aplikasi-aplikasi yang menggunakan protokol ActivityPub seperti Mastodon, Pleroma, Misskey dan sebagainya saya rasa sudah lebih dari cukup. Kendala dari media sosial mainstream umumnya terletak di moderasi, namun khususnya, di monetasi. Akan cukup panjang jika membahas tentang ini, namun tagline “Your home feed should be filled with what matters to you most, not what a corporation thinks you should see” dari halaman utama Mastodon saya rasa cukup merangkum.

ATProto: the Bluesky

Fondasi utama dari ATProto adalah Personal Data Server (PDS). Semua konten (informasi profile, unggahan status, gambar, video, dsb) disimpan di PDS yang bisa dikelola oleh penyedia layanan (seperti Bluesky Social) ataupun dikelola mandiri (self-hosting).

Secara teknis, konsepnya cukup sederhana:

  1. Client menyimpan data ke PDS
  2. PDS mengirim “event” ke “relay”
  3. Relay mengirim “event” tersebut ke “app view”
  4. App view menampilkan data yang terstruktur

Mengambil contoh untuk postingan ini, alurnya berarti:

  1. AppView akan “resolve handle” dari social.faultables.net untuk mendapatkan Decentralized Identifires (DIDs)
  2. Resolver memberikan response DID (did:web:social.faultables.net) tersebut
  3. AppView query “lokasi PDS” berdasarkan informasi DID yang diterima (https://social.faultables.net/.well-known/did.json)
  4. AppView query data untuk app.bsky.feed.post dengan Record Key/rkey 3ly6trelmps26
  5. PDS memberikan data tersebut (yang pada dasarnya bisa disederhanakan dengan akses ke at://did:web:social.faultables.net/app.bsky.feed.post/3ly6trelmps26)

Di beberapa kasus, terkadang AppView tidak perlu mengakses PDS secara langsung karena pada dasarnya, data (event) sudah dikirim dari PDS ke relay dan dari relay ke AppView tersebut.

Tapi dari perspektif pengguna yang menggunakan PDS yang dikelola mandiri, data (feeds, posts, dsb) selalu diambil dari PDS nya tersebut.

Nostr: Notes and Other Stuff Transmitted by Relays

Cara kerja Nostr cukup serupa dengan ATProto namun sedikit cukup unik. Konsep “akun” dari Nostr adalah sebuah public key dengan npub sebagai user identifier nya. Siapapun dapat membuat key-pair tersebut secara gratis, kapanpun, dimanapun. Tapi, bagaimana si “jaringan” ini mengetahui jika npub dengan nilai npub13....5mu terasosiasi dengan akun tertentu? Jawabannya: tidak ada.

Bahkan, jika akun tersebut tidak pernah berinteraksi sama sekali dengan “relay populer” di jaringan nostr, eksistensi dari akun tersebut dapat dikatakan tidak ada.

Tentu, mengingat npub13....5mu tidak akan pernah diinginkan oleh setiap orang. Ini seperti mengingat alamat IP alih-alih sebuah sistem bernama nama domain untuk mengakses sebuah situs. Tapi mari kita kesampingkan dulu masalah identitas dan dimulai dengan pertanyaan: bagaimana si npub13....5mu tersebut “membuat” data?

Jika mengambil konsep dari ATProto, ini cukup jelas: Sebuah akun menulis data ke PDS (database), PDS mengirim data tersebut ke relay, relay mem-broadcast data tersebut ke siapapun yang ingin mengkonsumsinya.

Di Nostr, singkatnya, akun hanya mengirim event ke relay. Artinya, dapat dikatakan relay itu sendiri adalah “PDS” dari si akun tersebut. Konsep relay di Nostr cukup beragam namun tidak berbeda jauh dengan yang ada di ATProto: ada untuk indexing dan caching.

Untuk mempermudah, anggap saya menjalankan 3 relay: id.relay.rs, en.relay.rs dan p.relay.rs. Setiap akan membuat status (“notes”), jika menggunakan bahasa Indonesia, saya ingin mengirimnya ke id begitupula jika untuk yang en untuk yang berbahasa Inggris, misalnya.

Untuk relay p anggap sebagai relay pribadi. Sebuah relay yang, konten-konten (notes & other stuff) nya dapat diakses dari Nostr client yang tersambung langsung ke relay tersebut saja. Relay tersebut bisa dilindungi dengan autentikasi ataupun tidak.

Ingat bagian “Bahkan, jika akun tersebut tidak pernah berinteraksi sama sekali dengan “relay populer” di jaringan nostr, eksistensi dari akun tersebut dapat dikatakan tidak ada.”? Exactly. Pemeran utama dari protokol Nostr adalah “nostr client” dan pada dasarnya client tersebut bertanggung jawab akan pemilihan relay yang digunakan.

Untuk pengguna awam, kita biasanya expect sesuatu yang “it just works”. Menggunakan aplikasi Bluesky, kita tidak ingin memusingkan hal-hal detail (PDS, DID, dsb) dan hanya ingin bisa melakukan sesuatu di protokol ATProto tersebut. Begitupula dengan Nostr, misal, jika menggunakan Nos Social, kita tidak perlu memusingkan konfigurasi relay ataupun NIP-05 (“handler”) sebagai identifier, it just works.

Social Internet untuk awam

Umumnya, kita cenderung bergabung ke perkumpulan yang cukup banyak kerumunannya. Join twitter karena banyak “thought leader” disana? Reddit? Instagram? Threads? Medium? LinkedIn?

Sayangnya, pengguna Twitter tidak dapat berinteraksi dengan pengguna Reddit; pengguna tersebut hanya bisa berkomunikasi dengan sesama pengguna di platform tersebut, dan itu by design. Contoh klasik dan sering kali digunakan sebagai perbandingan adalah bagaimana protokol memungkinkan pengguna @gmail.com dapat berinteraksi dengan pengguna @icloud.com menggunakan pesan elektronik meskipun keduanya berada di layanan berbeda.

Tapi, apa pentingnya? Sangat panjang. Namun paling sederhana: bayangkan harus memiliki akun twitter terlebih dahulu untuk bisa melihat tautan yang teman kita bagikan tentang sesuatu yang dia bagikan ke sebuah platform yang dianggap internet tersebut.

Dengan menggunakan sosial media alternatif untuk bersosial di internet, tembok autentikasi/login tersebut hampir tidak ada. Karena pada dasarnya, protokol tidak bertindak sebagai gerbang. Seperti, jika email yang dikirim oleh [email protected] ke [email protected] tidak pernah diterima oleh doe, besar kemungkinan, antara layanan gmail.com, layanan icloud.com atau apapun diantara nya, yang membuatnya terjadi, bukan protokol SMTP ataupun IMAP itu sendiri.

Mastodon (dengan protokol ActivityPub nya untuk berinteraksi) cocok untuk perkumpulan yang mengutamakan interest tertentu, namun tidak sedikit juga untuk yang general purposes. Identifier di ActivityPub adalah @[email protected], yang berarti, @username adalah sebuah akun yang dikelola di server.tld.

ATProto dan Nostr, sekali lagi, sangat bergantung dengan client yang digunakan. Jika untuk microblogging, Bluesky (ATProto) dan Nos.social (Nostr) adalah pilihan yang direkomendasikan untuk yang masih awam.

Social Internet untuk pengembang

Di ActivityPub, Mastodon dan Pixelfed adalah dua layanan dan dunia yang berbeda namun berkomunikasi dengan protokol yang sama untuk bertukar informasi (ActivityPub). Apakah “status” di Mastodon adalah “status” di Pixelfed juga? Ya dan tidak. Dan bagaimana jika sebaliknya? Ya dan tidak juga. Tapi “reply”, di kedua client, kemungkinanan dua hal yang sama.

Di ATProto (dan Nostr), saya rasa lebih sederhana. ATProto memiliki konsep Lexicon dan Nostr memiliki NIP. Entitas dengan lexicon app.bsky.post dan event dengan kind:1 mempermudah bagaimana data harus ditampilkan.

Mungkin dapat dibilang bahwa ActivityPub adalah protokol tentang “social interaction” sedangkan ATProto dan Nostr adalah tentang “social web” secara keseluruhan. Ini terlihat dari bagaimana aplikasi/layanan yang menggunakan ActivityPub seperti Mastodon, PeerTube, FunkWhale dan sebagainya memiliki API tersendiri untuk bertukar informasi sedangkan ATProto dan Nostr adalah tentang spesifikasi terkait informasi yang ingin dikonsumsi.

Yang maksudnya, data “status” di Mastodon dan Pixelfed yang bisa diakses melalui /api/v1/statuses/:id berpotensi memiliki struktur yang berbeda: Seperti, di Mastodon (dan semacamnya), status mungkin berisi “polling” sedangkan di Pixelfed tidak memiliki konsep tersebut.

Jika di ATProto dan Nostr, saya rasa cukup sederhana: Jika ingin menampilkan status dengan lexicon app.bsky.post ataupun event dengan kind:1, ada struktur yang bisa dirujuk. Tentu, misal client “Orangesky” menggunakan lexicon app.bsky.post dan tidak mengikuti “standar” yang sudah dibuat bisa saja terjadi dan relay mungkin “menerima” nya. Namun poinnya, tidak ada konsep “app.bsky.post versi Bluesky dan app.bsky.post versi Orangesky” di ATProto. Hanya sebuah client yang membuat data berdasarkan struktur app.bsky.post.

The Identity

ATProto menggunakan DID dan Nostr menggunakan public key. Untuk lookup, DID bisa menggunakan Public Ledger of Credentials (PLC) ataupun WEB (HTTP/DNS based) dan untuk nostr… ini cukup kompleks.

Pertama, untuk ATProto. Jika ingin mendapatkan informasi metadata untuk akun social.faultables.net, proses lookup DID yang bisa dilakukan adalah dengan DNS (dig _atproto.social.faultables.net TXT) atau HTTP https://social.faultables.net/.well-known/atproto-did. Selanjutnya, untuk keperluan reverse lookup, jika did:plc: maka akan cek ke https://plc.directory/did:plc:xyz (atau kemanapun tergantung yang client/pds gunakan) dan jika did:web: akan ke https://social.faultables.net/.well-known/did.json. Dan satu akun tidak bisa menggunakan dua DID karena DID bersifat unik (identitas).

Kedua, untuk Nostr. Nostr menggunakan “pubkey” sebagai identifier, namun bisa menggunakan NIP-05. Seperti, jika ingin mendapatkan metadata untuk akun social.faultables.net (NIP-05), proses lookup pubkey nya adalah mengakses https://social.faultables.net/.well-known/nostr.json. Jika melihat akun nostr dengan format NIP-05 lain seperti [email protected], untuk proses lookup nya berarti ke https://social.faultables.net/.well-known/nostr.json?name=me. Beruntungnya, nostr mendukung “domain sebagai identifier”, jadi, jika NIP-05 nya adalah social.faultables.net, untuk lookup pubkey nya bisa mengakses nostr.json?name=_.

Bagaimana dengan reverse lookup di nostr? Umm, likely akan query ke relay dengan event kind 0. Tapi pertanyaannya, query ke relay yang mana? Misal, jika saya mengubah profile (termasuk menambahkan NIP-05) menggunakan klien Nos, dan di klien tersebut saya hanya menggunakan 1 relay (nostr.faultables.net), maka, hanya relay itu saja yang “aware” dengan event penambahan NIP-05 tersebut.

Query nya kurang lebih seperti ini:

1[
2  "REQ",
3  "query:data",
4  {
5    "authors": ["8cb333a64aaa245fb9378d1eed970d29d720cd0d8900463ba76d1d35bf2de398"],
6    "kinds": [0]
7  }
8]

Dan response nya (jika ada) kurang lebih akan seperti ini:

 1[
 2  "EVENT",
 3  "query:data",
 4  {
 5    "content": "{\"nip05\":\"[email protected]\"}",
 6    "created_at": 1757783528,
 7    "id": "c303303b527089b681afbeccf680da762ba910959972134ad9c15a1f5ebcb6d2",
 8    "kind": 0,
 9    "pubkey": "8cb333a64aaa245fb9378d1eed970d29d720cd0d8900463ba76d1d35bf2de398",
10    "sig": "518e3c70240396257f...87629f03",
11    "tags": []
12  }
13]

Dan disitu terlihat bahwa content["nip05"] adalah handler untuk pubkey 8cb333a64aaa245fb9378d1eed970d29d720cd0d8900463ba76d1d35bf2de398

Untuk Fediverse (Mastodon/ActivityPub), tidak ada konsep “decentralized identifier”, identitas pengguna nya adalah @[email protected] sebagaimana konsep email. Jika akun @[email protected] ingin “pindah” ke @[email protected], singkatnya, tidak bisa. Karena segala hal yang berkaitan dengan akun tersebut, terlekat dengan akun tersebut, di server tersebut. Di Mastodon direkomendasikan untuk membuat akun baru dan “menampilkan pesan” bahwa akun tersebut sudah berpindah ke tempat (server) baru.

Moderasi

Di Fediverse (Activity-pub based/Mastodon-compatible), moderasi cukup sederhana: setiap instance operator bertanggung jawab akan setiap konten yang ada. Mereka dapat memoderasi aktivitas user di server tertentu ataupun memoderasi “komunikasi” antar server yang terjadi.

Di ATProto, ini bergantung dengan “labeler”. Di aplikasi Bluesky, default labeler yang digunakan adalah dari moderation.bsky.app yang struktur nya bisa dilihat disini.

Di Nostr, hmm, bisa dikatakan tidak ada. Atau mungkin layaknya seperti di Fediverse. Pada akhirnya, pertama, kita bisa mengatur relay mana saja yang ingin kita hubung. Dan kedua, relay operator dapat memoderasi aktivitas. Misal, ada 2 user: social.faultables.net dan antisocial.faultables.net. Social mengikuti antisocial, dan keduanya terhubung ke 2 relay yang sama: clean.relay.rs dan filtered.relay.rs. Jika antisocial “termoderasi” oleh relay filtered, si social masih dapat mendapatkan “status” dari si antisocial karena keduanya terhubung ke relay clean.

Tapi bagaimana jika social tidak ingin melihat lagi konten-konten dari antisocial? Unfollow, tentu saja.

Di sosial media mainstream, kita bisa mem-filter apa yang ingin kita lihat: dari berdasarkan kata kunci sampai ke “interest”, sehingga bagian “explore” atau “for you” tetap relevan dengan apa yang sekiranya ingin kita lihat.

Di ATProto, hal itu bisa dicapai dengan “label” yang sempat dibahas sedikit. Di Nostr, belum ada NIP khusus untuk melakukan itu namun ada NIP-51 untuk mute list (“things the user doesn’t want to see in their feeds”) yang bisa berisi pubkeys, hastags, words dan threads. Di Mastodon-compatible, kurang lebih sama dengan yang dilakukan oleh sosial media mainstream.

Concern saya pribadi tentang moderasi ini adalah: saya ingin membuat “status” yang sekiranya “cukup aman” untuk hanya berada di tempat pribadi dan “status” yang “cukup aman” berada di tempat lain juga. Ini alasan saya menjalankan instance Mastodon sendiri dan juga memiliki akun Bluesky.

Di Nostr, saya tidak perlu memusingkan itu. Jika sekiranya bersifat pribadi, saya hanya perlu mempublish event tersebut ke relay saya pribadi dan selainnya, bisa ke “relay populer”. Siapapun dapat terhubung ke relay pribadi saya, namun siapapun tidak harus terhubung ke relay pribadi saya untuk melihat “status” yang saya terbitkan.

Dan saya rasa itu keren.

Masalah pribadi dengan sosial media mainstream

Sosial media mainstream menampilkan iklan. Karena hal itu, mereka harus membuat “pengguna” nya “kecanduan” agar bisa terus kembali dan melihat banyak iklan. Karena hal itu, mereka harus membuat “pengguna” nya terus melihat apa yang harus mereka lihat. Karena hal itu, mereka harus membuat sebanyak mungkin “pembuat” untuk “membuat” dan dikonsumsi oleh si “pengguna”. Karena hal itu…. oke, cukup sampai disini.

Yang bagian terakhir dapat digarisbawahi. Hampir setiap sosial media mainstream (not sure jika fesnuk) memiliki “creator program” yang intinya memberikan insentif/kompensasi kepada pengguna nya yang tergabung. Ada berupa revenue sharing (yang of course dari iklan) dan ada yang dari afiliasi (pada akhirnya mereka lah yang mengiklankan). Lalu apa modalnya? Engagement rate. Semakin besar atensi, semakin besar (kemungkinan) kompensasi yang didapat.

Lalu dimana letak masalahnya? Spam. Sejujurnya, “creator program” yang paling ideal menurut saya pribadi adalah “instagram subscriptions” nya Meta (dan mungkin juga berlaku di fesnuk) yang memfasilitasi konten eksklusif. Oke, anyway.

Tapi masalah lain di sosial media mainstream adalah auth wall. Dan semakin mengganas berkat populer nya sebuah teknologi bernama LLM.

Kabar baiknya, internet tidak hanya tentang sosial media apalagi hanya tentang sosial media mainstream. Berbagi kabar melalui sebuah tulisan dari suatu blog pun termasuk bagian dari sosial di internet!

Tapi, apakah masalah dari sosial media mainstream sesederhana hanya perihal spam? Tidak juga, khususnya bila telah mempelajari lebih lanjut tentang “social media detox”, alasan atas dibalik adanya fitur “wellbeing” atau hal semacamnya.

Jadi, apa sebenarnya yang saya inginkan? Entahlah, mungkin sebuah tempat untuk bersosial dimana orang-orang berkumpul memang untuk bersosial.

Tapi, apakah sosial media alternatif tidak akan pernah dilindungi auth wall? Pertanyaan itu adalah seperti “apakah saya boleh melihat informasi dari sumber terbuka?”

Penutup

Tulisan ini adalah bahan riset untuk flo. Saya ingin membuat ListenBrainz atau Last.fm alternative untuk aplikasi kecil saya. Pilihan terbaik jatuh kepada ATProto karena konsep PDS nya (data scrobbler disimpan di PDS yang dikelola). Tapi Nostr pun cukup menarik karena data scrobbler dapat disimpan di relay khusus seperti wss://social.flooo.club.

Dan kabar baiknya, setiap pengguna flo memiliki kebebasan untuk memilih PDS ataupun mengirim ke relay Nostr yang diinginkan. Bahkan untuk mematikan fitur opsional tersebut dari flo!

Lalu apa inti dari tulisan ini? Entahlah. Saya malah menjadi mempertimbangkan ulang instance Mastodon baru saya.