Skip to content

Implement HTTP Signatures for ActivityPub federation #6

Description

@solargate

Grom already generates per-user RSA keys and exposes them in the actor document (publicKey.publicKeyPem, key ID https://{domain}/users/{nick}#main-key), but federation traffic is currently unsigned and inbox requests are not verified.

Current state

  • Outgoing delivery (internal/federation/delivery.go, postActivity) sends plain POST requests with Content-Type and Date only.
  • Incoming inbox (api/v1/federation_routes.go) accepts any JSON activity without authentication.
  • Shared inbox (POST /inbox) is a stub (returns 202, no processing).

What to implement

Outgoing signatures

  • Sign all inbox deliveries: Follow, Undo, Accept, Create, Delete.
  • Add Signature, Digest, and Date headers per the Cavage HTTP Signatures draft (de-facto Fediverse standard).
  • Sign with the actor's private key from LoadOrCreateActorKey.

Incoming verification

  • Verify Signature (and Digest when present) on POST /users/:nickname/inbox.
  • Fetch the sender's publicKey from their actor document if needed.
  • Reject requests where the verified key owner does not match the activity actor (401/403).
  • Consider making verification configurable (strict vs permissive) for dev/Grom-to-Grom setups.

Why

  • Interoperability: Mastodon, Pixelfed, Misskey, and most Fediverse servers require signed inbox deliveries; unsigned POSTs are typically rejected.
  • Security: Public inbox endpoints are reachable without JWT; without verification, anyone can spoof Follow/Create/Delete activities.

Out of scope (for now)

  • Shared inbox routing (POST /inbox)
  • LD-Signatures / Linked Data proofs

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions