Sébastien R.
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # SemApps et ActivityPub ## Partie 1 : Faut-il développer un seul serveur qui gère à la fois les protocoles ActivityPub et SOLiD/LDP ? ### Problématique Il y a actuellement deux projets proches: SemApps, dont le backend serait développé par Simon et Niko, et un serveur ActivityPub qui serait éventuellement développé en commun par Sébastien et Adu. L'idée est de mutualiser le stockage en triple store, en passant pour les deux projets par un triple store Jena qui gère les WebACL. Mais la question légitime qu'on peut se poser, c'est: ne pourrait-on pas greffer le serveur ActivityPub sur le backend SemApps (qui se veut le plus universel possible), afin de mutualiser le développement et réduire les coûts ? ### Qu'est-ce que SOLiD/LDP ? * Le protocole LDP, qui est une des briques de SOLiD, a pour but de mettre à disposition des "serveurs universels" en read-write qui permettent à n'importe qui d'enregistrer et partager des données sémantiques (RDF/JSON-LD) mais aussi des données binaires (images...), tout en gardant le contrôle complet des droits sur ces données. ### Qu'est-ce qu'ActivityPub ? * ActivityPub a été développé par le SocialWG du W3 dans le but de proposer un protocole pour faire du réseau social décentralisé. Il s'agissait d'offrir les fonctionnalités de base des réseaux sociaux, à savoir "follow", "like", "repost" ("announce" dans ActivityPub) et puis le fil personnalisé que les utilisateurs de Facebook, Twitter & co connaissent bien. L'idée c'est avant tout de pouvoir suivre les activités des acteurs qui nous intéressent, où qu'ils soient sur le web. * ActivityPub est basé sur trois types d'entités: * Les [acteurs](https://www.w3.org/TR/activitystreams-vocabulary/#actor-types) (utilisateurs, organisations, etc.) * Les [activités](https://www.w3.org/TR/activitystreams-vocabulary/#activity-types) qui sont créées par ces acteurs * Les [objets](https://www.w3.org/TR/activitystreams-vocabulary/#object-types) qui sont attachés aux activités telles que `Create`, `Update` et `Delete`. * Chaque acteur émet un flux d'activités que l'on peut retrouver dans son `Outbox`. * Un acteur dispose également d'une `Inbox` dans laquelle sont postées les activités des acteurs qu'il suit ou celles qui lui sont directement adressés (en principe, les messages privés). * Les activités peuvent concerner la création / mise à jour d'objets, mais aussi des activités "sociales" (`Follow`, `Like`, `Announce`). Tout est enregistré dans ce flux d'activités. * Les activités sont toujours adressées à un ou plusieurs destinataires, via les champs `to`/`bto`/`cc`/`bcc`. Le destinataire peut être `https://www.w3.org/ns/activitystreams#Public` pour indiquer que l'activité est publique, ou alors ses propres followers, ou alors des acteurs en particulier (ce qui permet l'envoi de messages privés) * Pour identifier un acteur (et potentiellement vérifier son identité via le protocole HTTP signature), on utilise soit son URI, soit son adresse de type `@user@server.com`. Dans ce cas, on passe par le protocole [Webfinger](https://tools.ietf.org/html/rfc7033) pour retrouver l'URI de l'acteur. ### Quel est le serveur ActivityPub qu'on veut développer ? Il faut noter que le serveur ActivityPub qu'on veut développer est déjà particulier, et va nécessiter de relever de nombreux défis: - Communication entre le client et le serveur uniquement en ActivityPub, contrairement à toutes les implémentation existantes qui ont développé un protocole maison pour le C2S. - Stockage en triple store, et non pas en BDD relationnelle comme toutes les implémentations existantes. - Endpoint SparQL qui prend en compte les droits d'accès spécifiques (via WebACL) - Gestion native de tous les types d'objets ActivityStreams + de toutes les extensions d'ontologies (serveur vraiment universel) En plus de cela, nous avons dû développer des particularités propres au serveur de Reconnexion: - Authentification CAS - Gestion des webhooks entrants - Notifications push sur mobile ### Quelles sont les limites d'ActivityPub ? ActivityPub est un nouveau protocole qui a des limites qu'il s'agira, soit de contourner par des "hacks", soit de dépasser en proposant des extensions à faire valider par la communauté (Mastodon a déjà ajouté [3 extensions](https://docs.joinmastodon.org/development/activitypub/#extensions), elles ne cassent rien mais ne sont pas encore validées). - Avec ActivityPub, on ne peut suivre qu'un acteur, pas un objet. Si un objet peut être modifié par plusieurs acteurs, mais qu'on en suit qu'un seul, on ne sera pas tenu au courant de toutes les modifications. Quelques solutions possibles: - On pourrait étendre les objets ActivityStreams avec une propriété `history` qui serait une collection d'activitées liées à l'objet. Il faudrait alors ajouter la possibilité de "suivre" n'importe quel objet. - Autre solution: créer un "super acteur" qui reposte toutes les activités de tous les acteurs. Il suffirait de s'y abonner pour être sûr d'être tenu au courant de toutes les modifications. Mais suivant les cas, cela ne sera pas toujours optimal en terme de performances. - ActivityPub, tout comme SOLiD, ne dit rien sur la notion de versioning. Si on veut garder un historique des modifications (`Update`) dans les flux d'activités, il faudrait pouvoir gérer ça au niveau du triple store. - Deux solutions alternatives : enregistrer le JSON de l'objet à l'instant T (sorte de cache permanent) ou ne référencer que l'URI (mais on perd les données de modification) - ActivityPub a une gestion des droits très basique. En lecture, on ne peut lire une activité (et l'objet associé ?) que s'il nous est adressé ou s'il est public. En écriture, rien n'est dit sur les droits d'un utilisateur à modifié un objet créé par un autre. A priori c'est possible, mais le mécanisme pour donner les droits d'accès n'est pas défini dans ActivityPub. ### Quelle est la compatibilité entre SOLID et un serveur ActivityPub ? A priori, il n'y a eu aucune concertation entre le groupe qui a développé le standard ActivityPub et celui qui travaille sur SOLID, les deux standards répondant à différents objectifs. Il se trouve que JSON-LD a été choisi pour ActivityPub, ce qui ouvre ce format à l'univers du web sémantique, mais jusqu'à maintenant, aucune implémentation n'a vraiment pris en compte cette dimension. Le JSON-LD est traité comme du JSON normal par les implémentations. Voilà un récapitulatif des différences et éventuelles compatibilités : | | SOLiD/LDP | ActivityPub | Compatibilité | |:-------------- |:----------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------:| | **Auth** | OIDC ou WebId-OIDC ou DID | [Pas spécifié](https://www.w3.org/wiki/SocialCG/ActivityPub/Authentication_Authorization) pour C2S, [HTTP signature](https://tools.ietf.org/html/draft-cavage-http-signatures-10) pour S2S | ? | | **ID** | WebID | [Webfinger](https://tools.ietf.org/html/rfc7033) | ? | | **Containers** | Basic / Direct Containers | [Collections (AS)](https://www.w3.org/TR/activitystreams-core/#collections), avec possibilité d'avoir des listes ordrées | Voir si les listes ordrées sont compatibles avec LDP | | **Lecture** | Simple GET sur des URIs | Simple GET sur des URIs | Oui | | **Ecriture** | On peut potentiellement écrire dans n'importe quel container si on a les droits. On peut aussi modifier une ressource directement. | On ne peut poster que des activités dans son `Outbox`, tout le reste est géré en side-effects (`Create`, `Update`, `Like`, `Follow`...). Pour la fédération (S2S), on peut POSTer dans l'Inbox d'un autre serveur, mais il faut signer les messages pour qu'ils soient acceptés | Oui en théorie, mais si on peut modifier directement une ressource sans passer par l'`Outbox`, ça va être compliqué à gérer au niveau du triple store. | | **ACL** | WebACL | Droits définis en fonction du destinataire de l'activité. Pas de notion de droit d'écriture : dans des réseaux sociaux simples comme Mastodon, seul le créateur d'une `Note` peut la modifier | A priori on pourrait utiliser WebACL en background | #### Et les Linked Data Notifications ? Les Linked Data Notifications (LDN) ne sont pas prises en compte dans le tableau ci-dessus car elles sont incompatibles avec ActivityPub. Les LDN permettent uniquement d'attacher une `Inbox` à une ressources existante. On peut ensuite POSTer des ressources sur cette `Inbox`. En lisant cette `Inbox`, on peut voir ces ressources sous forme de Containers LDP... ou pas (rien n'est spécifié quant à la gestion ACL). Il n'y a pas d'`Outbox` dans LDN, ni de notions de Followers. Il n'y a que des `Consumers` qui peuvent lire l'Inbox (en mode pull). Avec ActivityPub, toutes les actions passent par des "side effects". On ne poste JAMAIS dans l'`inbox` de quelqu'un, ni dans la collection `followers`, ni dans la collection `liked`, etc. Tout passe par notre `outbox`. On y poste des activités de type Follow, Like, Create, Update, Delete, etc, et le serveur s'occupe ensuite de traiter les side-effets. La seule exception est la fédération: lorsqu'un serveur envoie une activité vers un autre serveur, alors il poste dans l'`inbox` du destinataire. Cependant le serveur de destination doit vérifier (via la signature HTTP) la validité de cet envoi, on est donc dans un processus qui sort de SOLiD. Je n'ai entendu qu'un cas d'usage de LDN qui me parait cohérent : si on a un document, on peut y attacher une Inbox, et n'importe qui peut poster des commentaires dans cette Inbox, qui s'afficheront éventuellement en-dessous du document. #### Et les agents des serveurs SOLiD ? Il a été évoqué l'idée qu'ActivityPub serait géré par des agents. Il faut cependant remarquer que ces agents n'ont fait l'objet d'aucune spécification dans le cadre de SOLiD. On peut bien sûr ajouter des side-effects à un serveur LDP, mais c'est quelque chose qui sera propre à chaque implémentation. ### Conclusion provisoire de Sébastien Un serveur ActivityPub "greffé" sur un serveur SOLiD/LDP aurait a priori peu d'intérêt, puisqu'on ne pourrait reprendre pour le serveur ActivityPub presque aucun des protocoles de SOLiD. Tout devrait être redéveloppé, si ce n'est la connexion au triple store. On pourrait bien sûr développer le serveur ActivityPub comme un "middleware" du serveur SOLiD en NodeJS, mais s'il s'agit juste de faire le pont, on peut aussi envisager un système de webhook très simple pour permettre au serveur SOLiD d'envoyer les données au serveur ActivityPub. On n'aurait alors pas la contrainte de développer dans le même langage. Reste la question de la mutualisation de certaines parties du code, mais cela nécessite alors une concertation sur le langage utilisé. ------------- ## Partie 2: comment ajouter ActivityPub à SemApps ? ### Problématique On a toujours évoqué l'idée qu'il faudrait que SemApps soit compatible ActivityPub, mais on gardait cette problématique pour plus tard, puisqu'on avait déjà assez de problèmes à régler. Au vu des questions qui se posent ci-dessus, j'ai cependant pris le temps de lister les besoins qu'on pourrait avoir à l'avenir en terme d'ActivityPub, afin d'avoir déjà une vision de ce qu'il y aurait à faire, et je propose une implémentation via des webhooks. ### Besoins (user stories) #### Etape 1: permettre à des serveurs ActivityPub extérieurs de suivre les activités d'un acteur sur SemApps Il s'agit d'inclure SemApps dans le graphe global des données ActivityPub, pour permettre à n'importe quelle application ActivityPub de se connecter au flux d'activité qui est généré par un acteur sur une instance donnée. - Permettre à tout utilisateur / organisation sur SemApps de devenir un acteur ActivityPub, avec implémentation des endpoints `/inbox`, `/outbox` et `/followers` - Inscrire chacun des opérations CRUD de l'acteur dans son flux d'activités (Outbox) - Traiter les requêtes `Follow` venant d'autres serveurs - Faire suivre aux followers le flux d'activité, à condition que la ressource manipulée soit lisible par l'utilisateur connecté (un follower n'a pas forcément les droits de lecture sur tous les objets) #### Etape 2: Rendre visible sur SemApps le flux d'activités des acteurs Une fois qu'on a rendu public le flux d'activités d'un acteur, il ne serait pas forcément compliqué de le rendre visible directement sur SemApps, ou sur n'importe quelle autre interface. Il suffirait de lire l'`Outbox`. - Sur la page d'un acteur (utilisateur / organisation), afficher son flux d'activité (`Outbox`), en filtrant selon les droits de l'utilisateur loggé (ou en ne montrant que les activités publiques si l'utilisateur n'est pas connecté) > Note: A ce stade, on ne pourrait pas voir les anciennes versions des ressources modifiées, sauf si on implémente le versionning avant l'étape 4, par exemple dès la première version de SemApps. #### Etape 3: Intégrer la notion de fil personnalisé à SemApps Là on passe à une autre échelle, puisque SemApps prend les allures d'un réseau social, avec un fil personnalisé regroupant les activités de tous les acteurs qu'on suit. - Permettre à un utilisateur SemApps de suivre un autre utilisateur / organisation, y compris sur une autre instance, en ajoutant un bouton "Suivre" sur la page de cet acteur. - Ajouter à SemApps, ou sur une autre interface, la possibilité de voir sa propre Inbox, qui contiendrait les activités de tous les acteurs qu'on suit. > Note: On pourrait aussi imaginer un bouton "Suggérer à des amis" qui permettrait d'envoyer à tous ses followers - ou à des utilisateurs en particulier - la suggestion de suivre un acteur. ~~Cela nécessiterait une petite extension d'ActivityPub, qui ne serait pas forcément difficile à mettre en oeuvre.~~ [L'activité `Offer` permet ce genre de choses](https://socialhub.activitypub.rocks/t/idea-for-a-new-suggest-activity/328/6). #### Etape 4: Afficher l'historique d'une ressource Afficher l'historique des activités d'une ressource peut-être précieux, surtout dans le cas d'objets qui sont fréquemment modifiés. On s'approcherait du fonctionnement d'un wiki, en donnant plus largement les droits de modifications sans risquer de perdre les données. - Etendre les objets ActivityStreams pour ajouter une propriété `history`, qui contiendrait la liste ordonnée de toutes les activités liées à cette ressource (Follow, Update, Like...). - Pouvoir voir une ressource à un instant T. Ou encore mieux: voir la différence d'une ressource entre deux instants. #### Etape 5: Pouvoir suivre les activités liées à une ressource Cela permettrait à un logiciel externe (type YesWiki) d'être tenu au courant de toutes les modifications d'une ressource, quel que soit l'acteur qui l'a modifiée. On pourrait ainsi garder un cache des ressources, sans avoir à les requêter à chaque fois pour savoir si elles ont été mises à jour. On pourrait même généraliser ce fonctionnement aux communications inter-instances SemApps. - Etendre les objets ActivityStreams en ajoutant une propriété de type `subscribers` et ajouter une propriété de type `subscriptions` aux acteurs (cela éviterait de confondre avec l'activité `Follow` ?) - Quand une activité est effectuée sur un objet (`Update`, `Delete`, `Like`), envoyer automatiquement toute l'activité aux followers, en signant le message dans le cas de fédération. ### Possible implémentation via des webhooks et un serveur "externe" Il suffirait que SemApps implémente un système de webhooks sortant lors des opérations CRUD et qu'il envoie les donnée au serveur ActivityPub (qui gère déjà les webhooks entrant dans [sa version prototype actuelle](https://github.com/reconnexion/reconnexion-server)) On aurait alors deux serveurs indépendants, qui pourraient toutefois se baser sur une instance Jena unique (avec toutefois deux datasets, pour éviter les conflits de version) | Serveur SOLiD/LDP | Serveur ActivityPub | |:-----------------:|:-------------------:| | Jena Dataset | Jena Dataset | Avec trois container Docker, on a tout ficellé sur la même machine. #### Etape 1 - A chaque création d'utilisateur ou d'organisation, créer un acteur (`User` / `Organisation`) correspondant sur le serveur ActivityPub - A chaque opération CRUD, envoyer l'activité au webhook, en faisant attention de respecter les droits de lecture. #### Etape 2 et 3 - Rien à faire de particulier, on se contente de lire les `inbox` et `outbox` des acteurs. Il faudra juste réfléchir à comment authentifier l'utilisateur connecté sur le serveur ActivityPub. #### Etape 4 et 5 - On est dans de l'extension ActivityPub pure. Il n'y a pas plus de travail à faire en l'implémentant sur un serveur ActivityPub externe.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully