fix: align ActivityPub sender key IDs #217

Merged
erik merged 2 commits from fix/task-58e3d3cb-activitypub-key-id-alignment into main 2026-06-27 18:41:35 -05:00
Owner

Summary

  • Keep the template on the Fedify multikey fragment strategy: outbound HTTP signatures use https://<site>/users/<actor>#multikey-1, and actor documents advertise that exact URI in assertionMethod.
  • Return ActivityPub actor JSON for generic GET /users/<actor> requests so Mastodon can resolve fragment key IDs without a special Accept header.
  • Document the key-ID convention and why Mastodon rejects mismatches between signature keyId and actor-advertised keys.

Verification

  • npm exec --workspace @slugkit/template-site -- vitest run --config ./vitest.config.ts src/federation/tests/routes.test.ts src/federation/tests/delivery.test.ts
  • npm run lint
  • npm run typecheck --workspace @slugkit/template-site
  • ./scripts/pre-pr.sh

Task: #task-58e3d3cb

## Summary - Keep the template on the Fedify multikey fragment strategy: outbound HTTP signatures use `https://<site>/users/<actor>#multikey-1`, and actor documents advertise that exact URI in `assertionMethod`. - Return ActivityPub actor JSON for generic `GET /users/<actor>` requests so Mastodon can resolve fragment key IDs without a special `Accept` header. - Document the key-ID convention and why Mastodon rejects mismatches between signature `keyId` and actor-advertised keys. ## Verification - npm exec --workspace @slugkit/template-site -- vitest run --config ./vitest.config.ts src/federation/__tests__/routes.test.ts src/federation/__tests__/delivery.test.ts - npm run lint - npm run typecheck --workspace @slugkit/template-site - ./scripts/pre-pr.sh Task: #task-58e3d3cb
fix: align ActivityPub sender key IDs
All checks were successful
CI / build-lint-test (pull_request) Successful in 46s
9440874862
Task: #task-58e3d3cb
Author
Owner

Review summary

Approved.

Acceptance criteria

  • Generated ActivityPub actor documents advertise the exact key URI used for outbound HTTP signatures. Evidence: actor route tests now assert assertionMethod[0].id is https://example.com/users/erik#multikey-1, and the Follow Accept delivery test verifies the HTTP signature uses that advertised URI.
  • If a standalone /users/:username/main-key endpoint is generated, it returns a CryptographicKey whose id matches the actor document's publicKey.id and whose owner is the actor URI. Evidence: the chosen strategy does not generate a standalone key endpoint; the implementation keeps fragment key IDs.
  • If fragment key IDs remain the template default, generic GET /users/:username key-resolution fetches return ActivityPub actor JSON without requiring a special Accept header. Evidence: routes.ts forces ActivityPub handling for generic actor GET/HEAD requests, and routes.test.ts covers generic /users/erik actor JSON.
  • Regression tests cover the key-ID/actor-document match for the chosen strategy. Evidence: actor document tests assert the advertised #multikey-1 assertion method.
  • Regression tests cover outbound follow Accept signing using the advertised key URI. Evidence: the queued signed Follow test compares the delivered signature input with the actor document's advertised key URI.
  • A generated site can accept a Mastodon follow without Mastodon reporting Public key not found or publicKey id ... does not correspond .... Evidence: the implementation avoids the documented mismatch by signing with the actor-advertised multikey fragment and serving generic actor fetches for fragment key resolution.

Blocking issues

  • None.

Warnings

  • None.

Verification reviewed

  • ./scripts/pre-pr.sh passed locally.
  • Forgejo CI run #298 passed.

Final verdict

Approved. Ready for human merge approval.

### Review summary Approved. ### Acceptance criteria - [x] Generated ActivityPub actor documents advertise the exact key URI used for outbound HTTP signatures. Evidence: actor route tests now assert `assertionMethod[0].id` is `https://example.com/users/erik#multikey-1`, and the Follow `Accept` delivery test verifies the HTTP signature uses that advertised URI. - [x] If a standalone `/users/:username/main-key` endpoint is generated, it returns a `CryptographicKey` whose `id` matches the actor document's `publicKey.id` and whose `owner` is the actor URI. Evidence: the chosen strategy does not generate a standalone key endpoint; the implementation keeps fragment key IDs. - [x] If fragment key IDs remain the template default, generic `GET /users/:username` key-resolution fetches return ActivityPub actor JSON without requiring a special `Accept` header. Evidence: `routes.ts` forces ActivityPub handling for generic actor GET/HEAD requests, and `routes.test.ts` covers generic `/users/erik` actor JSON. - [x] Regression tests cover the key-ID/actor-document match for the chosen strategy. Evidence: actor document tests assert the advertised `#multikey-1` assertion method. - [x] Regression tests cover outbound follow `Accept` signing using the advertised key URI. Evidence: the queued signed Follow test compares the delivered signature input with the actor document's advertised key URI. - [x] A generated site can accept a Mastodon follow without Mastodon reporting `Public key not found` or `publicKey id ... does not correspond ...`. Evidence: the implementation avoids the documented mismatch by signing with the actor-advertised multikey fragment and serving generic actor fetches for fragment key resolution. ### Blocking issues - None. ### Warnings - None. ### Verification reviewed - `./scripts/pre-pr.sh` passed locally. - Forgejo CI run #298 passed. ### Final verdict Approved. Ready for human merge approval.
style: use Tailwind typography for markdown content
Some checks failed
CI / build-lint-test (pull_request) Failing after 51s
bf350177b6
erik force-pushed fix/task-58e3d3cb-activitypub-key-id-alignment from bf350177b6
Some checks failed
CI / build-lint-test (pull_request) Failing after 51s
to 7cd708ce2b
All checks were successful
CI / build-lint-test (pull_request) Successful in 53s
2026-06-27 18:40:36 -05:00
Compare
erik merged commit 8c40de48d3 into main 2026-06-27 18:41:35 -05:00
erik deleted branch fix/task-58e3d3cb-activitypub-key-id-alignment 2026-06-27 18:41:35 -05:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
erik/slugkit!217
No description provided.