1
Inbound Activity Handling
Gabriel Kaszewski edited this page 2026-05-29 02:09:58 +00:00

Inbound Activity Handling

k-ap handles the following inbound activities out of the box. All arrive via POST /inbox or POST /users/{id}/inbox, after HTTP signature verification.


Handled activities

Activity What k-ap does
Follow Saves follower with Pending status; checks blocklist first
Accept Updates outbound following status to Accepted
Reject Updates outbound following status to Rejected
Undo(Follow) Removes the follower record; calls on_actor_removed
Undo(Like) Calls on_unlike
Undo(Announce) Removes announce record from ActorRepository; calls on_announce_removed
Undo(Add) No-op
Undo(Block) No-op
Create Calls on_create with the wrapped object JSON; dispatches mentions
Update Calls on_update with the wrapped object JSON; dispatches mentions
Delete Calls on_delete with the object URL; if object is an actor, calls on_actor_removed
Announce Records in ActorRepository; calls on_announce_received (local object) or on_announce_of_remote (remote object)
Like Calls on_like
Add Calls on_create with the object JSON
Block No-op (you may surface this in your UI separately)
Move Verifies alsoKnownAs, migrates follower records, re-follows in background

Deduplication

Before any handler is called, k-ap calls ActivityRepository::is_activity_processed with the activity's id. If already processed, the handler is skipped and the inbox returns 200. After successful processing, mark_activity_processed is called.

This makes inbound delivery safe to retry — the sender can retry on network failure without causing duplicate effects.


Mention dispatch

For Create and Update activities, k-ap extracts the tag array from the wrapped object and looks for {"type":"Mention","href":"<local-actor-url>"} entries. For each mention that resolves to a local user, ApObjectHandler::on_mention is called with the object's AP ID, the local user's UUID, and the mentioning actor's URL.

on_mention failures are logged and swallowed — a broken notification must not cause the activity to be rejected.


Move (account migration)

When a Move activity is received:

  1. k-ap fetches the target actor's JSON
  2. Verifies that the target's alsoKnownAs array contains the source actor's URL (all aliases checked)
  3. Calls FollowRepository::migrate_follower_actor to update follower records
  4. Spawns a background task (non-blocking) to re-follow the new actor on behalf of local users who followed the old one

Step 4 runs in the background so the inbox handler returns immediately.


Error responses

4xx responses sent to remote servers use generic messages. Internal error details are only logged via tracing, never sent to clients. This prevents information leakage to potentially adversarial servers.


Body limit

Both inbox routes enforce a 1 MB body limit via axum's DefaultBodyLimit. Oversized payloads are rejected with 413 before any processing.


Actor types accepted

k-ap accepts activities from Person, Service, Application, Organization, and Group actors.