To do the signature validation you need to know/trust the public key signing the incoming request (which will use the keyId
in the signature to specify the key of the actor, usually a Person, that made the thing, when your server gets this comment the keyId
will be https://lemmy.nrd.li/u/terribleplan#main-key
). A good server will check that the keyId
only differs from the actor of the object by having a fragment appended.
Your server needs to fetch my Person object, of https://lemmy.nrd.li/u/terribleplan
. If you load that with an Accept
header of application/activity+json
you get:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"lemmy": "https://join-lemmy.org/ns#",
"litepub": "http://litepub.social/ns#",
"pt": "https://joinpeertube.org/ns#",
"sc": "http://schema.org/",
"ChatMessage": "litepub:ChatMessage",
"commentsEnabled": "pt:commentsEnabled",
"sensitive": "as:sensitive",
"matrixUserId": "lemmy:matrixUserId",
"postingRestrictedToMods": "lemmy:postingRestrictedToMods",
"removeData": "lemmy:removeData",
"stickied": "lemmy:stickied",
"moderators": {
"@type": "@id",
"@id": "lemmy:moderators"
},
"expires": "as:endTime",
"distinguished": "lemmy:distinguished",
"language": "sc:inLanguage",
"identifier": "sc:identifier"
}
],
"type": "Person",
"id": "https://lemmy.nrd.li/u/terribleplan",
"preferredUsername": "terribleplan",
"inbox": "https://lemmy.nrd.li/u/terribleplan/inbox",
"outbox": "https://lemmy.nrd.li/u/terribleplan/outbox",
"publicKey": {
"id": "https://lemmy.nrd.li/u/terribleplan#main-key",
"owner": "https://lemmy.nrd.li/u/terribleplan",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzX8XfO3F/nBKgST+Rqu8\noBxyE1GdvdXpYUYXq9OqwYEVIsE4Jth+aRzx4rSnotnMYyxbhBst3t77dSZAf7ir\nHjpdSoRYdZ0Ce3qJc4mpnctPtDSIjWl+fYwG9oPF51D8cwJewUejHcj6v6ud44Q5\nHbuiYqrMQo2YtWGKMAmjErE8cFinuNcpoNDCCzopCXWfpks48II6f4/aT/Kd66zo\niUYvBMrEmqWATZVbTwnh2MSwu7XTh8O5SlUeceb3LpC7dyCCpkVJU+DYDVqOfPBA\nSb+KmxqOVnewZor6zVDtfelXXx7Zikbff+IcUGbuiJRUlNsyqaq2kxJMZjO/UYCc\newIDAQAB\n-----END PUBLIC KEY-----\n"
},
"name": "terribleplan",
"summary": "<p>DevOps as a profession and software development for fun. Admin of lemmy.nrd.li.</p>\n",
"source": {
"content": "DevOps as a profession and software development for fun. Admin of lemmy.nrd.li.",
"mediaType": "text/markdown"
},
"icon": {
"type": "Image",
"url": "https://lemmy.nrd.li/pictrs/image/680ced6c-b461-4d7c-906a-9091268f6e7e.jpeg"
},
"endpoints": {
"sharedInbox": "https://lemmy.nrd.li/inbox"
},
"published": "2023-06-10T16:10:13.859768+00:00"
}
You can see my Person object contains .publicKey.publicKeyPem
, that is what your server will use (and store after fetching it once) to validate the incoming payload/header.