Local ActivityPub Actors are being created without keypairs

I can’t figure out how to get any posts to federate to Mastodon, I can follow the actors fine. I get these errors in the logs when Discourse attempts to deliver a post:

[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b failed to deliver to https://mstdn.party/users/staff/inbox --- !ruby/hash:ActiveSupport::HashWithIn
[Discourse Activity Pub] POST request to https://mastodon.neat.computer/users/jonah/inbox failed: Expected([200, 201, 202]) <=> Actual(401 Unauthorized)
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mastodon.neat.computer/users/jonah/inbox --- !ruby/hash:ActiveSupport:
[Discourse Activity Pub] POST request to https://mstdn.party/users/staff/inbox failed: Expected([200, 201, 202]) <=> Actual(401 Unauthorized) 

I disabled Activity pub require signed requests and enabled logging in settings, otherwise all the settings are still their defaults. These Mastodon instances are behind Cloudflare but I can see Cloudflare is not blocking the requests, and the mastodon-web service logs show that Mastodon itself is returning the 401 codes (although I don’t know how to increase the verbosity of Mastodon’s logs to see why that’s the case).

Is there any reason this’d happen?

Edit: Mastodon doesn’t like the HTTP signatures, although this instance does not have Authorized Fetch enabled:

Mar 08 16:47:07 neat-mastodon bundle[3119591]: D, [2025-03-08T16:47:07.963455 #3119591] DEBUG -- : [e6b2bc50-09e1-464e-a937-4c43ef32bd99] Signature verification failed: Request not signed
Mar 08 16:47:07 neat-mastodon bundle[3119591]: I, [2025-03-08T16:47:07.964520 #3119591]  INFO -- : [e6b2bc50-09e1-464e-a937-4c43ef32bd99] method=POST path=/users/jonah/inbox format=html controller=ActivityPub::InboxesController action=create status=401 allocations=1256 duration=9.15 view=0.69 db=1.86

Edit 2: Seems like the inbox for my Discourse users are inaccessible: https://verify.funfedi.dev/?actor_uri=jonah%40discuss.privacyguides.net

    "Resolving acct:jonah@discuss.privacyguides.net using webfinger",
    "Resolved to https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce",
    "Running verification for alice",
    "Got inbox None", [...]

It does work as expected for the group actor: https://verify.funfedi.dev/?actor_uri=articles%40discuss.privacyguides.net :thinking:

Edit 3: for a GET request to https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce

{
    "id": "https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce",
    "type": "Person",
    "updated": "2025-03-08T06:34:19Z",
    "url": "https://discuss.privacyguides.net/u/jonah",
    "name": "Jonah Aragon",
    "inbox": null,
    "outbox": null,
    "sharedInbox": "https://discuss.privacyguides.net/ap/users/inbox",
    "followers": "https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce/followers",
    "preferredUsername": "jonah",
    "icon": {
        "type": "Image",
        "mediaType": "image/png",
        "url": "https://forum-cdn.privacyguides.net/user_avatar/discuss.privacyguides.net/jonah/96/8151_2.png"
    },
    "@context": "https://www.w3.org/ns/activitystreams"
}

Hey @JonahAragon1, let’s see if we can figure it out.

Did you disable this before or after testing? If before, try enabling it.

More broadly, I’ve been meaning to add better error response message logging to make it easier to diagnose different cases. To that end, I’ve raised a PR

If you could have another go when that’s merged and share the same logs.

1 Like

I do have this setting enabled again now that I identified the issue as the user inboxes not being created. I’ll update the plugin now :+1:

Person Actors of Discourse Users are not meant to have individual inboxes currently. Mastodon uses and understands the sharedInbox. There’s something else going on.

Besides logging all settings are back to their defaults:

[Discourse Activity Pub] POST request to https://mastodon.neat.computer/users/jonah/inbox failed: {"error":"Request not signed"}
backtrace
activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:130:in `block in warn'

activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `block in dispatch'

activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `each'

activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `dispatch'

activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:130:in `warn'

/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/logger.rb:26:in `log'

/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/logger.rb:63:in `warn'

/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/request.rb:66:in `rescue in perform'

/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/request.rb:48:in `perform'

/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/request.rb:44:in `post_json_ld'

/var/www/discourse/plugins/discourse-activity-pub/app/jobs/discourse_activity_pub_deliver.rb:34:in `perform_request'

/var/www/discourse/plugins/discourse-activity-pub/app/jobs/discourse_activity_pub_deliver.rb:15:in `execute'

/var/www/discourse/app/jobs/base.rb:316:in `block (2 levels) in perform'

rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
/var/www/discourse/app/jobs/base.rb:303:in `block in perform'

/var/www/discourse/app/jobs/base.rb:299:in `each'

/var/www/discourse/app/jobs/base.rb:299:in `perform'

sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in `execute_job'

sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in `block (4 levels) in process'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in `traverse'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'

/var/www/discourse/lib/sidekiq/pausable.rb:132:in `call'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'

sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in `call'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'

sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in `track'

sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in `call'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'

sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in `invoke'

sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in `block (3 levels) in process'

sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in `block (6 levels) in dispatch'

sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in `local'

sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in `block (5 levels) in dispatch'

sidekiq-7.3.9/lib/sidekiq/config.rb:39:in `block in <class:Config>'

sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in `block (4 levels) in dispatch'

sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in `stats'

sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in `block (3 levels) in dispatch'

sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in `call'

sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in `block (2 levels) in dispatch'

sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in `global'

sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in `block in dispatch'

sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in `prepare'

sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in `dispatch'

sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in `block (2 levels) in process'

sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `handle_interrupt'

sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `block in process'

sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `handle_interrupt'

sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `process'

sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in `process_one'

sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in `run'

sidekiq-7.3.9/lib/sidekiq/component.rb:10:in `watchdog'

sidekiq-7.3.9/lib/sidekiq/component.rb:19:in `block in safe_thread'

Hey, so it looks like the issue Mastodon has is that the request is not signed.

Are you sure that log entry was created after you re-enabled Activity pub require signed requests?

That’s correct, yes.

Sorry to push on this, however Mastodon returns that error when there is no signature in the request headers at all, so it seems unlikely that Activity pub require signed requests was enabled when the request is sent. Could you triggering an entirely new POST request.

Ah, I think the issue is that Cloudflare is stripping the headers from the request.

1 Like

Yes, this is the error with the settings at their defaults and that setting enabled.

[Discourse Activity Pub] POST request to https://mstdn.party/users/staff/inbox failed: {"error":"Request not signed"}
10:40 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mstdn.party/users/staff/inbox --- !ruby/hash:ActiveSupport::HashWithIn
10:40 am
[Discourse Activity Pub] POST request to https://mastodon.neat.computer/users/jonah/inbox failed: {"error":"Request not signed"}
10:40 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mastodon.neat.computer/users/jonah/inbox --- !ruby/hash:ActiveSupport:
10:40 am
[Discourse Activity Pub] POST request to https://social.lol/users/jonah/inbox failed: {"error":"Request not signed"}
10:40 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://social.lol/users/jonah/inbox --- !ruby/hash:ActiveSupport::HashWithInd 

(I’ll note social.lol is not behind Cloudflare nor is the forum)

Edit: if you want to follow @videos@discuss.privacyguides.net from a Mastodon account you know works let me know and I can resend a post from the forum.

Ok, please create a new post with that actor.

Did you receive the posts correctly? Seems like you might’ve.

 2
[Discourse Activity Pub] POST request to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox failed: {"errors":["Request not signed"]}
10:56 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox --- !ru
10:56 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/705b7513d0446e001d7f750115e6395f successfully delivered to https://mstdn.party/users/staff/inbox --- !ruby/hash:ActiveSupport::HashW
11:00 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/705b7513d0446e001d7f750115e6395f successfully delivered to https://social.lol/users/jonah/inbox --- !ruby/hash:ActiveSupport::HashWi
11:00 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/705b7513d0446e001d7f750115e6395f successfully delivered to https://mastodon.neat.computer/users/jonah/inbox --- !ruby/hash:ActiveSup
11:00 am
3
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mstdn.party/users/staff/inbox --- !ruby/hash:ActiveSupport::HashWithIn
11:01 am
3
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://social.lol/users/jonah/inbox --- !ruby/hash:ActiveSupport::HashWithInd
11:01 am
3
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mastodon.neat.computer/users/jonah/inbox --- !ruby/hash:ActiveSupport:
11:01 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mstdn.party/users/staff/inbox --- !ruby/hash:ActiveSupport::HashWithIn
11:01 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mastodon.neat.computer/users/jonah/inbox --- !ruby/hash:ActiveSupport:
11:01 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://social.lol/users/jonah/inbox --- !ruby/hash:ActiveSupport::HashWithInd
11:01 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce successfully delivered to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox --
11:01 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce successfully delivered to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox --
11:01 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/705b7513d0446e001d7f750115e6395f successfully delivered to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox --
11:01 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b successfully delivered to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox --
11:02 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b failed to deliver to https://mstdn.party/users/staff/inbox --- !ruby/hash:ActiveSupport::HashWithIn
11:02 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b failed to deliver to https://mastodon.neat.computer/users/jonah/inbox --- !ruby/hash:ActiveSupport:
11:02 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b failed to deliver to https://social.lol/users/jonah/inbox --- !ruby/hash:ActiveSupport::HashWithInd
11:02 am
15
[Discourse Activity Pub] POST request to https://mastodon.neat.computer/users/jonah/inbox failed: {"error":"Request not signed"}
11:02 am
12
[Discourse Activity Pub] POST request to https://social.lol/users/jonah/inbox failed: {"error":"Request not signed"}
11:02 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mastodon.neat.computer/users/jonah/inbox --- !ruby/hash:ActiveSupport:
11:02 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://social.lol/users/jonah/inbox --- !ruby/hash:ActiveSupport::HashWithInd
11:02 am
[Discourse Activity Pub] POST request to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox failed: The endpoint angus.ngrok.io is offline. ERR_NGROK_3200
11:02 am
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://angus.ngrok.io/ap/actor/0eafb34c67153d61db44234de294a98d/inbox --- !ru
11:02 am
16
[Discourse Activity Pub] POST request to https://mstdn.party/users/staff/inbox failed: {"error":"Request not signed"}
11:02 am
2
[Discourse Activity Pub] https://discuss.privacyguides.net/ap/actor/227cc2ddaa4ded69c2a58214031da3ce failed to deliver to https://mstdn.party/users/staff/inbox --- !ruby/hash:ActiveSupport::HashWithIn
11:02 am 

Note that @JonahAragon1 and I discussed this via chat and the issue is that local User Actors are somehow being created without keypairs.

@JonahAragon1 I will test a few things and get back to you.

1 Like

Hey @JonahAragon1,

Are there any differences between these users on your forum, anything that comes to mind

Keys were created for the actors for Shampoo and Bhaelros but not basenote and jonah. Are there any common differences between those two groups of users on your site?

Hm, no. I can’t think of any reason for this. While jonah is an admin the rest are normal users.

misc.

Bhaelros and basenote are both Trust Level 3 Regulars so they should be the same.

Weird that Shampoo also has inbox/outbox generated while basenote and jonah did not, so neither ensure_keys nor ensure_inbox_and_outbox are working?:

GET https://discuss.privacyguides.net/ap/actor/310a0986b6bf613b61ca5e85a8521ecb

{
    "id": "https://discuss.privacyguides.net/ap/actor/310a0986b6bf613b61ca5e85a8521ecb",
    "type": "Person",
    "updated": "2025-03-11T17:58:08Z",
    "url": "https://discuss.privacyguides.net/u/Shampoo",
    "inbox": "https://discuss.privacyguides.net/ap/actor/310a0986b6bf613b61ca5e85a8521ecb/inbox",
    "outbox": "https://discuss.privacyguides.net/ap/actor/310a0986b6bf613b61ca5e85a8521ecb/outbox",
    "sharedInbox": "https://discuss.privacyguides.net/ap/users/inbox",
    "followers": "https://discuss.privacyguides.net/ap/actor/310a0986b6bf613b61ca5e85a8521ecb/followers",
    "preferredUsername": "Shampoo",
    "publicKey": {
        "id": "https://discuss.privacyguides.net/ap/actor/310a0986b6bf613b61ca5e85a8521ecb#main-key",
        "owner": "https://discuss.privacyguides.net/ap/actor/310a0986b6bf613b61ca5e85a8521ecb",
        "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAleqeCRZW1utTN/L5GjkY\n+2Baron4FnSKRMKW70IWfqI4rs8dfh2xhKW5qXxaBPhXf13FAOJvQvFhQ90eqRrn\nKkuMsntZN0dfpDUZ3E0iIp8fuUEVk2PmquLziiy9+zu8n5ak65lJKDYnKVtFth5G\nFJyUt6GYicY8UlUh6dPxafJ/gw6YTlvT3hO0X0H0L+hYwqHJpppl6niSDi6WQzME\nWM1hyBpv2Y2NspEexrkSVh+SIR3nJ8J1R+o+2bLJ4Hl34nYhtNyTy9AOddoQYDMw\nICZAkCLQDweid50fGakWmRB5EXfL6s2EdzEh8MOE7cyCOXgFrxTJYUTwg5TiLEQY\npQIDAQAB\n-----END PUBLIC KEY-----\n"
    },
    "icon": {
        "type": "Image",
        "mediaType": "image/png",
        "url": "https://forum-cdn.privacyguides.net/user_avatar/discuss.privacyguides.net/shampoo/96/4073_2.png"
    },
    "@context": "https://www.w3.org/ns/activitystreams"
}

GET https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b

{
    "id": "https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b",
    "type": "Person",
    "updated": "2025-03-08T06:34:19Z",
    "url": "https://discuss.privacyguides.net/u/basenote",
    "inbox": null,
    "outbox": null,
    "sharedInbox": "https://discuss.privacyguides.net/ap/users/inbox",
    "followers": "https://discuss.privacyguides.net/ap/actor/a93549c3c7883784eda700f30de0c96b/followers",
    "preferredUsername": "basenote",
    "icon": {
        "type": "Image",
        "mediaType": "image/png",
        "url": "https://forum-cdn.privacyguides.net/user_avatar/discuss.privacyguides.net/basenote/96/15_2.png"
    },
    "@context": "https://www.w3.org/ns/activitystreams"
}

I’m still not sure how these actors ended up in this state. It is specific to your site. As a general matter, actor key and inbox/outbox creation works as expected. Nevertheless, this update should ensure such a situation is resolved as needed:

1 Like

@JonahAragon1 The PR is merged. Could you try updating and let me know how you go?

1 Like

This specific issue seems to have been fixed, although I still seem to be running into general issues getting posts to show up on Mastodon.