gotosocial/docs/federation/actors.md
tobi dcfc9b7885 [feature] Use hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb properties for web visibility of statuses (#4315)
This pull request implements two new properties on ActivityPub actors: `hidesToPublicFromUnauthedWeb` and `hidesCcPublicFromUnauthedWeb`.

As documented, these properties allow actors to signal their preference for whether or not their posts should be hidden from unauthenticated web views (ie., web pages like the GtS frontend, web apps like the Mastodon frontend, web APIs like the Mastodon public timeline API, etc). This allows remote accounts to *opt in* to having their unlisted visibility posts shown in (for example) the replies section of the web view of a GtS thread. In future, we can also use these properties to determine whether we should show boosts of a remote actor's post on a GtS profile, and that sort of thing.

In keeping with our stance around privacy by default, GtS assumes `true` for `hidesCcPublicFromUnauthedWeb` if the property is not set on a remote actor, ie., hide unlisted/unlocked posts by default. `hidesToPublicFromUnauthedWeb` is assumed to be `false` if the property is not set on a remote actor, ie., show public posts by default.

~~WIP as I still want to work on the documentation for this a bit.~~

New props are already in the namespace document: https://gotosocial.org/ns

Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4315
Reviewed-by: kim <gruf@noreply.codeberg.org>
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
2025-07-09 16:50:25 +02:00

28 KiB

Actors and Actor Properties

Service vs Person actors

GoToSocial serves most accounts as the ActivityStreams Person type described here.

Accounts that users have selected to mark as bot accounts, however, will use the Service type described here.

This type distinction can be used by remote servers to distinguish between bot accounts and "regular" user accounts.

Inbox

GoToSocial implements Inboxes for Actors following the ActivityPub specification here.

Remote servers should deliver Activities to a GoToSocial server by making an HTTP POST request to each Inbox of the desired audience of an Activity, as described here.

GoToSocial accounts do not currently implement a sharedInbox endpoint, though this is subject to change. Deduplication of delivered Activities, in case more than one Actor on a GoToSocial server is in the audience for an Activity, is handled on GoToSocial's side.

POSTs to a GoToSocial Actor's inbox must be appropriately http-signed by the delivering Actor.

Accepted Inbox POST Content-Type headers are:

  • application/activity+json
  • application/activity+json; charset=utf-8
  • application/ld+json; profile="https://www.w3.org/ns/activitystreams"

Inbox POST requests that do not use one of the above Content-Type headers will be rejected with HTTP status code 406 - Not Acceptable.

For more information on acceptable content types, see the server-to-server interactions section of the ActivityPub protocol.

GoToSocial will return HTTP status code 202 - Accepted in response to validly-formed and signed Inbox POST requests.

Invalidly-formed Inbox POST requests will receive a 400 - Bad Request HTTP status code in response. The response body may contain more information on why the GoToSocial server considered the request content to be badly formed. Other servers should not retry delivery of the Activity in case of a code 400 response.

Even if GoToSocial returns a 202 status code, it may not continue processing the Activity delivered, depending on the originator(s), target(s) and type of the Activity. ActivityPub is an extensive protocol, and GoToSocial does not cover every combination of Activity and Object.

Outbox

GoToSocial implements Outboxes for Actors (ie., instance accounts) following the ActivityPub specification here.

To get an OrderedCollection of Activities that an Actor has published recently, remote servers can do a GET request to a user's outbox. The address of this will be something like https://example.org/users/whatever/outbox.

The server will return an OrderedCollection of the following structure:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/users/whatever/outbox",
  "type": "OrderedCollection",
  "first": "https://example.org/users/whatever/outbox?page=true"
}

Note that the OrderedCollection itself contains no items. Callers must dereference the first page to start getting items. For example, a GET to https://example.org/users/whatever/outbox?page=true will produce something like the following:

{
  "id": "https://example.org/users/whatever/outbox?page=true",
  "type": "OrderedCollectionPage",
  "next": "https://example.org/users/whatever/outbox?max_id=01FJC1Q0E3SSQR59TD2M1KP4V8&page=true",
  "prev": "https://example.org/users/whatever/outbox?min_id=01FJC1Q0E3SSQR59TD2M1KP4V8&page=true",
  "partOf": "https://example.org/users/whatever/outbox",
  "orderedItems": [
    {
      "id": "https://example.org/users/whatever/statuses/01FJC1MKPVX2VMWP2ST93Q90K7/activity",
      "type": "Create",
      "actor": "https://example.org/users/whatever",
      "published": "2021-10-18T20:06:18Z",
      "to": [
        "https://www.w3.org/ns/activitystreams#Public"
      ],
      "cc": [
        "https://example.org/users/whatever/followers"
      ],
      "object": "https://example.org/users/whatever/statuses/01FJC1MKPVX2VMWP2ST93Q90K7"
    }
  ]
}

The orderedItems array will contain up to 30 entries. To get more entries beyond that, the caller can use the next link provided in the response.

Note that in the returned orderedItems, all activity types will be Create. On each activity, the object field will be the AP URI of an original public status created by the Actor who owns the Outbox (ie., a Note with https://www.w3.org/ns/activitystreams#Public in the to field, which is not a reply to another status). Callers can use the returned AP URIs to dereference the content of the notes.

Followers / Following Collections

GoToSocial implements followers and following collections as OrderedCollections. A properly-signed GET request to an Actor's Following collection, for example, will return something like:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "first": "https://example.org/users/someone/following?limit=40",
  "id": "https://example.org/users/someone/following",
  "totalItems": 397,
  "type": "OrderedCollection"
}

From there, you can use the first page to start getting items. For example, a GET request to https://example.org/users/someone/following?limit=40 will produce something like:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/users/someone/following?limit=40",
  "next": "https://example.org/users/someone/following?limit=40&max_id=01V1AY4ZJT4JK1NT271SH2WMGH",
  "orderedItems": [
    "https://example.org/users/someone_else",
    "https://somewhere.else.example.org/users/another_account",
    [... 38 more entries here ...]
  ],
  "partOf": "https://example.org/users/someone/following",
  "prev": "https://example.org/users/someone/following?limit=40&since_id=021HKBY346X7BPFYANPPJN493P",
  "totalItems": 397,
  "type": "OrderedCollectionPage"
}

You can then use the next and prev endpoints to page down and up through the OrderedCollection.

!!! Info "Hidden Followers / Following Collections"

GoToSocial allows users to hide their followers/following collections if they wish.

If a user has chosen to hide their collections, then only a stub collection with `totalItems` will be returned, and you will not be able to page through the Actor's followers/following collections.

A `GET` to the following collection of an Actor with hidden collections will look like:

```json
{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/users/someone/following",
  "type": "OrderedCollection",
  "totalItems": 397
}
```

Profile Fields

Like Mastodon and other fediverse softwares, GoToSocial lets users set key/value pairs on their profile; useful for conveying short pieces of information like links, pronouns, age, etc.

For the sake of compatibility with other implementations, GoToSocial uses the same schema.org PropertyValue extension that Mastodon uses, present as an attachment array value on actors that have fields set. For example, the below JSON shows an account with two PropertyValue fields:

{
  "@context": [
    "http://joinmastodon.org/ns",
    "https://w3id.org/security/v1",
    "https://www.w3.org/ns/activitystreams",
    "http://schema.org"
  ],
  "attachment": [
    {
      "name": "should you follow me?",
      "type": "PropertyValue",
      "value": "maybe!"
    },
    {
      "name": "age",
      "type": "PropertyValue",
      "value": "120"
    }
  ],
  "discoverable": false,
  "featured": "http://example.org/users/1happyturtle/collections/featured",
  "followers": "http://example.org/users/1happyturtle/followers",
  "following": "http://example.org/users/1happyturtle/following",
  "id": "http://example.org/users/1happyturtle",
  "inbox": "http://example.org/users/1happyturtle/inbox",
  "manuallyApprovesFollowers": true,
  "name": "happy little turtle :3",
  "outbox": "http://example.org/users/1happyturtle/outbox",
  "preferredUsername": "1happyturtle",
  "publicKey": {
    "id": "http://example.org/users/1happyturtle#main-key",
    "owner": "http://example.org/users/1happyturtle",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTc6Jpg6LrRPhVQG4KLz\n2+YqEUUtZPd4YR+TKXuCnwEG9ZNGhgP046xa9h3EWzrZXaOhXvkUQgJuRqPrAcfN\nvc8jBHV2xrUeD8pu/MWKEabAsA/tgCv3nUC47HQ3/c12aHfYoPz3ufWsGGnrkhci\nv8PaveJ3LohO5vjCn1yZ00v6osMJMViEZvZQaazyE9A8FwraIexXabDpoy7tkHRg\nA1fvSkg4FeSG1XMcIz2NN7xyUuFACD+XkuOk7UqzRd4cjPUPLxiDwIsTlcgGOd3E\nUFMWVlPxSGjY2hIKa3lEHytaYK9IMYdSuyCsJshd3/yYC9LqxZY2KdlKJ80VOVyh\nyQIDAQAB\n-----END PUBLIC KEY-----\n"
  },
  "summary": "\u003cp\u003ei post about things that concern me\u003c/p\u003e",
  "tag": [],
  "type": "Person",
  "url": "http://example.org/@1happyturtle"
}

For actors that have no PropertyValue fields set, the attachment property will not be set at all. That is, the attachment key value will not be present on the actor (not even as an empty array or null value).

While attachment is not technically an ordered collection, GoToSocial--again, in line with what other implementations do--does present attachment PropertyValue fields in the order in which they should to be displayed.

GoToSocial will also parse PropertyValue fields from remote actors discovered by the GoToSocial instance, to allow them to be displayed to users on the GoToSocial instance.

GoToSocial allows up to 6 PropertyValue fields by default, as opposed to Mastodon's default 4.

GoToSocial allows users to feature (or 'pin') posts on their profile.

In ActivityPub terms, GoToSocial serves these pinned posts as an OrderedCollection at the endpoint indicated in an Actor's featured field. The value of this field will be set to something like https://example.org/users/some_user/collections/featured.

By making a signed GET request to this endpoint, remote instances can dereference the featured posts collection, which will return an OrderedCollection with a list of post URIs in the orderedItems field.

Example of a featured collection of a user who has pinned multiple Notes:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/users/some_user/collections/featured",
  "orderedItems": [
    "https://example.org/users/some_user/statuses/01GS7VTYH0S77NNXTP6W4G9EAG",
    "https://example.org/users/some_user/statuses/01GSFY2SZK9TPCJFQ1WCCPGDRT",
    "https://example.org/users/some_user/statuses/01GSCXY70MZCBFMH5EKJW9ENC8"
  ],
  "totalItems": 3,
  "type": "OrderedCollection"
}

Example of a user who has pinned one Note:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/users/some_user/collections/featured",
  "orderedItems": [
    "https://example.org/users/some_user/statuses/01GS7VTYH0S77NNXTP6W4G9EAG"
  ],
  "totalItems": 1,
  "type": "OrderedCollection"
}

Example with no pinned Notes:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/users/some_user/collections/featured",
  "orderedItems": [],
  "totalItems": 0,
  "type": "OrderedCollection"
}

Unlike Mastodon and some other implementations, GoToSocial does not serve full Note representations as orderedItems values. Instead, it provides just the URI of each Note, which the remote server can then dereference (or not, if they already have the Note cached locally).

Some of the URIs served as part of the collection may point to followers-only posts which the requesting Actor won't necessarily have permission to view. Remote servers should make sure to do their own filtering (as with any other post type) to ensure that these posts are only shown to users who are permitted to view them.

Another difference between GoToSocial and other server implementations is that GoToSocial does not send updates to remote servers when a post is pinned or unpinned by a user. Mastodon does this by sending Add and Remove Activity types where the object is the post being pinned or unpinned, and the target is the sending Actor's featured collection. While this conceptually makes sense, it is not in line with what the ActivityPub protocol recommends, since the target of the Activity "is not owned by the receiving server, and thus they can't update it".

Instead, to build a view of a GoToSocial user's pinned posts, it is recommended that remote instances simply poll a GoToSocial Actor's featured collection every so often, and add/remove posts in their cached representation as appropriate.

hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb

GoToSocial uses the properties hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb to indicate whether an actor prefers to hide posts addressed to or cc public from unauthenticated (ie., logged-out) visitors to web pages, web apps, and web APIs.

Some background for this: many ActivityPub server softwares allow unauthenticated visitors to the profile web page of an actor to see a list of posts that an actor has created that are addressed either to or cc public. These are often called "public" posts, and "unlisted", "unlocked", or "quiet public" posts, respectively. GoToSocial provides a settings flag that allows GtS accounts to hide posts from the web view of their profile, as one layer of protection to make it more of a nuisance to scrape/stalk someone with a GtS account.

While this setting works for hiding posts of an actor on their own instance, prior to GoToSocial v0.20.0, this preference was not federated out to other instances, nor was it federated in from other instances. This leads to two problems:

  1. Many other fedi server softwares permit logged-out visitors, via a web app, to look up profiles of remote accounts, and to see public and unlisted posts created by those accounts. This means that it is trivial to work around the ability of GtS users to hide their posts from the web. For example, say a GtS user at @someone@gts.example.org locks down their profile by setting the visibility of posts on their profile to "none"; this prevents visitors to gts.example.org from seeing posts, but one could visit eg. mastodon.example.org and, while logged out, look up @someone@gts.example.org, and see all the posts there that have been sent to, or dereferenced by, actors on mastodon.example.org. This makes the GtS user's choice to hide their posts significantly less meaningful.
  2. In an effort to support this extra layer of privacy, by default GoToSocial instances do not show posts from remote instances unless they are addressed to public. For example, if someone from mastodon.example.org were to reply to a post by @someone@gts.example.org, and the reply was only addressed cc public instead of to public, the GtS instance gts.example.org would not show that reply in the web view, as it could not determine the preferences of the user from mastodon.example.org with regard to showing the "quiet public" post to logged-out visitors to the web page. This could be frustrating for the GtS user, as they might want to show a more complete picture of the thread that they started, right there on their instance; this could also frustrate the Mastodon user, as are used to their "quiet public" posts being visible on the web even when logged out.

The actor properties hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb are a move towards solving these issues, by allowing actors to signal their preferences for hiding or showing to- and/or cc-public posts to unauthenticated visitors via the web.

For example, the following actor representation indicates that the actor is happy to show both "unlisted" and "public" posts via unauthed web view (this represents the de-facto default for actors on Mastodon and most other server softwares):

{
  "@context": [
    "https://gotosocial.org/ns",
    "https://www.w3.org/ns/activitystreams"
  ],
  "type": "Person",
  [... other properties here ...]
  "hidesToPublicFromUnauthedWeb": false,
  "hidesCcPublicFromUnauthedWeb": false,
  [... other properties here ...]
}

By contrast, the following indicates that the actor hides "unlisted" posts but is happy to show "public" posts unauthed (this is the default for actors on GtS instances):

{
  "@context": [
    "https://gotosocial.org/ns",
    "https://www.w3.org/ns/activitystreams"
  ],
  "type": "Person",
  [... other properties here ...]
  "hidesToPublicFromUnauthedWeb": false,
  "hidesCcPublicFromUnauthedWeb": true,
  [... other properties here ...]
}

And the following shows that the actor wants to show no posts unauthed at all:

{
  "@context": [
    "https://gotosocial.org/ns",
    "https://www.w3.org/ns/activitystreams"
  ],
  "type": "Person",
  [... other properties here ...]
  "hidesToPublicFromUnauthedWeb": true,
  "hidesCcPublicFromUnauthedWeb": true,
  [... other properties here ...]
}

Both hidesToPublicFromUnauthedWeb and hidesCcPublicFromUnauthedWeb are defined in the GoToSocial json-ld @context document.

In line with its emphasis on having people opt-in to greater visibility rather than opt-out, when receiving a post from a remote actor that does not set these flags, GoToSocial assumes hidesToPublicFromUnauthedWeb = false, and hidesCcPublicFromUnauthedWeb = true. That is, the pre-v0.20.x behavior of GoToSocial is still the default for remote servers that don't (yet) use these flags.

!!! note While unusual, it's possible for an actor to also specify that they want to show "unlisted" posts but hide "public" ones:

```json
{
  "@context": [
    "https://gotosocial.org/ns",
    "https://www.w3.org/ns/activitystreams"
  ],
  "type": "Person",
  [... other properties here ...]
  "hidesToPublicFromUnauthedWeb": true,
  "hidesCcPublicFromUnauthedWeb": false,
  [... other properties here ...]
}
```

GoToSocial respects these flags for incoming posts, but it does not let accounts set this combination of flags for outgoing posts. It may be desirable for other implementers to also prevent users from being able to set this state, as it doesn't make a lot of sense.

Actor Migration / Aliasing

GoToSocial supports account migration from one instance/server to another through a combination of the Move activity, and the Actor Object properties alsoKnownAs and movedTo.

alsoKnownAs

GoToSocial supports account aliasing using the alsoKnownAs Actor property, which is an accepted ActivityPub extension.

Incoming

On incoming AP messages, GoToSocial looks for the alsoKnownAs property on an Actor to be an array of ActivityPub IDs/URIs of other Actors by which the Actor is also known.

For example:

{
  "@context": [
    "http://joinmastodon.org/ns",
    "https://w3id.org/security/v1",
    "https://www.w3.org/ns/activitystreams",
    "http://schema.org"
  ],
  "featured": "http://example.org/users/1happyturtle/collections/featured",
  "followers": "http://example.org/users/1happyturtle/followers",
  "following": "http://example.org/users/1happyturtle/following",
  "id": "http://example.org/users/1happyturtle",
  "inbox": "http://example.org/users/1happyturtle/inbox",
  "manuallyApprovesFollowers": true,
  "name": "happy little turtle :3",
  "outbox": "http://example.org/users/1happyturtle/outbox",
  "preferredUsername": "1happyturtle",
  "publicKey": {...},
  "summary": "\u003cp\u003ei post about things that concern me\u003c/p\u003e",
  "type": "Person",
  "url": "http://example.org/@1happyturtle",
  "alsoKnownAs": [
    "https://another-server.com/users/1happyturtle",
    "https://somewhere-else.org/users/originalTurtle"
  ]
}

In the above AP JSON, the Actor http://example.org/users/1happyturtle is aliased to the other Actors https://another-server.com/users/1happyturtle and https://somewhere-else.org/users/originalTurtle.

GoToSocial will store incoming alsoKnownAs URIs in the database, but does not (currently) use them for anything except verifying a Move Activity (see below).

Outgoing

GoToSocial users can set multiple alsoKnownAs URIs on their account via the GoToSocial client API. GoToSocial will verify that these alsoKnownAs aliases are valid Actor URIs before storing them in the database and before serializing them in outgoing AP messages.

However, GoToSocial does not verify ownership of those alsoKnownAs URIs by the user setting the aliases before serializing them in outgoing messages; it expects remote servers to do their own verification before trusting any transmitted alsoKnownAs values.

As an example, the user http://example.org/users/1happyturtle, from their GoToSocial instance, might set alsoKnownAs: [ "https://unrelated-server.com/users/someone_else" ] on their account, and GoToSocial will duly transmit this alias to other servers.

In this case, though, https://unrelated-server.com/users/someone_else may not be the same person as 1happyturtle. 1happyturtle may have set this alias by mistake, or maliciously. To properly verify ownership of someone_else by 1happyturtle, a remote server should check that the alsoKnownAs property of the Actor https://unrelated-server.com/users/someone_else contains an entry http://example.org/users/1happyturtle.

In other words, remote servers should not trust alsoKnownAs aliases by default, and should instead ensure that a two-way alias exists between Actors before treating the alias as valid.

!!! info The reason that GoToSocial does not perform verification of alsoKnownAs values before sending them out to other servers is to avoid a chicken and egg problem. Say that 1happyturtle and someone_else are the same person, one of the two Actors must be able to set alsoKnownAs first, so that the instance of the other Actor can begin processing the alias. If both servers prevent an unverified alias from being serialized in the alsoKnownAs property, then it becomes impossible for either 1happyturtle or someone_else to alias to one another.

movedTo

GoToSocial marks accounts as moved using the movedTo property. Unlike alsoKnownAs this is not an accepted ActivityPub extension, but it has been widely popularized by Mastodon, which also uses it in connection with the Move activity. See the Mastodon docs for more info.

Incoming

For incoming AP messages, GoToSocial looks for the movedTo property on an Actor to be set to a single ActivityPub Actor URI/ID.

For example:

{
  "@context": [
    "http://joinmastodon.org/ns",
    "https://w3id.org/security/v1",
    "https://www.w3.org/ns/activitystreams",
    "http://schema.org"
  ],
  "featured": "http://example.org/users/1happyturtle/collections/featured",
  "followers": "http://example.org/users/1happyturtle/followers",
  "following": "http://example.org/users/1happyturtle/following",
  "id": "http://example.org/users/1happyturtle",
  "inbox": "http://example.org/users/1happyturtle/inbox",
  "manuallyApprovesFollowers": true,
  "name": "happy little turtle :3",
  "outbox": "http://example.org/users/1happyturtle/outbox",
  "preferredUsername": "1happyturtle",
  "publicKey": {...},
  "summary": "\u003cp\u003ei post about things that concern me\u003c/p\u003e",
  "type": "Person",
  "url": "http://example.org/@1happyturtle",
  "alsoKnownAs": [
    "https://another-server.com/users/1happyturtle"
  ],
  "movedTo": "https://another-server.com/users/1happyturtle"
}

In the above JSON, the Actor http://example.org/users/1happyturtle has been aliased to the Actor https://another-server.com/users/1happyturtle and has also moved/migrated to that account.

GoToSocial stores incoming movedTo values in the database, but does not consider an account migration to have been processed unless the Actor doing the Move had previously transmitted a Move activity (see below).

Outgoing

GoToSocial will only set movedTo on outgoing Actors when an account Move has been verified and processed.

Move Activity

To actually trigger account migrations, GoToSocial uses the Move Activity with Actor URI as Object and Target, for example:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/users/1happyturtle/moves/01HR9FDFCAGM7JYPMWNTFRDQE9",
  "actor": "https://example.org/users/1happyturtle",
  "type": "Move",
  "object": "https://example.org/users/1happyturtle",
  "target": "https://another-server.com/users/my_new_account_hurray",
  "to": "https://example.org/users/1happyturtle/followers"
}

In the above Move, Actor https://example.org/users/1happyturtle indicates that their account is moving to the URI https://another-server.com/users/my_new_account_hurray.

Incoming

On receiving a Move activity in an Actor's Inbox, GoToSocial will first validate the Move by making the following checks:

  1. Request was signed by actor.
  2. actor and object fields are the same (you can't Move someone else's account).
  3. actor has not already moved somewhere else.
  4. target is a valid Actor URI: retrievable, not suspended, not already moved, and on a domain that's not defederated by the GoToSocial instance that received the Move.
  5. target has alsoKnownAs set to the actor that sent the Move. In this example, https://another-server.com/users/my_new_account_hurray must have an alsoKnownAs value that includes https://example.org/users/1happyturtle.

If checks pass, then GoToSocial will process the Move by redirecting followers to the new account:

  1. Select all followers on this GtS instance of the actor doing the Move.
  2. For each local follower selected in this way, send a follow request from that follower to the target of the Move.
  3. Remove all follows targeting the "old" actor.

The end result of this is that all followers of https://example.org/users/1happyturtle on the receiving instance will now be following https://another-server.com/users/my_new_account_hurray instead.

GoToSocial will also remove all follow and pending follow requests owned by the actor doing the Move; it's up to the target account to send follow requests out again.

To prevent potential DoS vectors, GoToSocial enforces a 7-day cooldown on Moves. Once an account has successfully moved, GoToSocial will not process further moves from the new account until 7 days after the previous move.

Outgoing

Outgoing account migrations use the Move Activity in much the same way. When an Actor on a GoToSocial instance wants to Move, GtS will first check and validate the Move target, and ensure it has an alsoKnownAs entry equal to the Actor doing the Move. On successful validation, a Move message will be sent out to all of the moving Actor's followers, indicating the target of the Move. GoToSocial expects remote instances to transfer the actor's followers to the target.