marnanel: (Default)
Here's my hackathon session for APConf2020 on Kepi:

https://socialhub.activitypub.rocks/t/hackathon-wheres-kepi-going-next/988

Thank you to all who encouraged this!
marnanel: (Default)
ActivityPub in Godmother's House

Last time, you received an ActivityPub message claiming to be from your goddaughter, Marigold. But it's possible that someone is tricking you, pretending to be Marigold. How can you be sure the message is really from her?

We're going to do a bit of crypto here, but don't be afraid. All you need to know is:
  • Everyone on ActivityPub has two related keys: a public key (which is public), and a private key (which is, er, private). We'll represent Marigold's public key as PPPPP.
  • Any message can be represented by a unique signature, which we'll represent by SSSSS.
  • Signatures are created using private keys.
  • Signatures are verified (checked) using public keys.
Let's look at the HTTP headers of Marigold's message to you.
Content-Type: application/activity+json
Date: Fri, 05 Apr 2019 20:40:09 GMT
Digest: SHA-256=DDDDD
Host: house.example.com
Signature: keyId="https:‌//pegs.example.org/users/marigold#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="SSSSS"

As you see, the Signature line contains a bunch of different parts: "signature" gives the message signature, and "keyId" tells us where to find the public key. The other parts of Signature aren't directly relevant right now, but I can explain them in comments if you like.

keyId isn't the public key; it just tells us where to find the public key. If it contained the public key itself, it would be really easy to fake a message and sign it using your own key. So we have to go looking.

Unsurprisingly, this message is signed using Marigold's own main public key (https‌://pegs.example.org/users/marigold#main-key). If it was signed using someone else's, it would be time to ask questions!

Now, do we already have a copy of Marigold's public key? If this is the first message from her, probably not. keyId told us to look in https‌://pegs.example.org/users/marigold#main-key. The "#main-key" part is a "fragment", which doesn't form part of the address itself. So let's take a look at https‌://pegs.example.org/users/marigold.

Up till now, we've only received ActivityPub objects from other people. Now that we're going to fetch them ourselves, over ordinary HTTPS. we have to remember to include the header
 
Accept: application/activity+json

Otherwise the remote server would assume we were an ordinary web browser, and show you text/html content meant for mortal humans.

We look up https:‌//pegs.example.org/users/marigold and receive:
 
{
"@‌‌context": "https‌:‌//www.w3.org/ns/activitystreams",
"id":"https://pegs.example.org/users/marigold",
"type":"Person",
"inbox":"https‌://pegs.example.org/users/marigold/inbox",
"preferredUsername":"marigold",
"name":"Marigold Mobbs",
"summary":"Ordinary. Not called Sarah or Anne.",
"publicKey":{
     "id":"https‌://pegs.example.org/users/marigold#main-key",
     "owner":"https‌://pegs.example.org/users/marigold",
     "publicKeyPem":"PPPPP"
},

(... and plenty more information)

Now we know that Marigold's public key is PPPPP. We check the first message's signature with this key, and it matches! So we can be reasonably sure that message came from Marigold.

Next time we'll look at the types of information you can send with ActivityPub: posts, reblogs, likes, follows, and so on.

Click for: previous part, all parts.
marnanel: (Default)
ActivityPub in Godmother's House

ActivityPub is a protocol which connects social media sites, like Mastodon, together to form a network called the fediverse.

Let's start with an example.

Once upon a time, your goddaughter Marigold decided to follow you on social media. You received a message containing a JSON object:

{
"@‌context": "https:‌//www.w3.org/ns/activitystreams",
"id": "https:‌//pegs.example.org/activity/1234",
"type": "Follow",
"actor": "https:‌//pegs.example.org/users/marigold",
"object": "https:‌//house.example.com/users/godmother"
}

As you can probably guess, someone named "https:‌//pegs.example.org/users/marigold" (that's Marigold) is asking to follow someone called "https:‌//house.example.com/users/godmother" (that's you).

You are delighted! You reply, accepting Marigold's message:

{
"@‌context": "https‌://www.w3.org/ns/activitystreams",
"id": "https‌://house.example.com/activity/9876",
"type": "Accept",
"actor": "https‌://house.example.com/users/godmother",
"object": "https‌://pegs.example.org/activity/1234"
}

Now Marigold is following you, and will hear all your news.

Next time: how did we know the message was really from Marigold?

Click for: next part, all parts.

Profile

marnanel: (Default)
Monument

January 2022

S M T W T F S
      1
2345678
9101112131415
1617 1819202122
23242526272829
3031     

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 11th, 2025 06:32 am
Powered by Dreamwidth Studios