Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for moving the domain of an entire server (and all its hosted actors, activities, and objects) #473

Open
ThisIsMissEm opened this issue Oct 11, 2024 · 8 comments
Labels
Needs Primer Page Needs a page in the ActivityPub primer

Comments

@ThisIsMissEm
Copy link

Given an event like .io potentially being removed, and cases where a ccTLD decided to boot a domain registration due to policy, such as queer.af and afghanistan, we'd need to support "full server migrations" to a new domain name.

Currently doing this would require issuing a Move on all the actors on that domain, then Move's on all the objects and activities. This seems incredibly inefficient at a protocol level and likely needs a different mechanism to handle it.

@qazmlp
Copy link

qazmlp commented Oct 11, 2024

I spontaneously sketched something up on Bluesky in this regard yesterday.
I'll try to structure it a bit better (and catch some more edge cases, but likely not all since this is very much just a sketch still!).


Assumptions

  • All objects on the affected domain can be moved.
  • The relative paths of all IDs on one domain are stable across the move.
  • Authorisation is available at most per Actor.1
  • Objects attributed to one Actor may reside on multiple domains.
  • The instance is one and the same (so it retains all object relationships and cryptographic keys).

Goals / Requirements

  • Easy implementation in existing software (at least on the observing end).
  • Seamless user experience, with ideally no disruptions at all. (Complete move.)
  • Minimal network traffic.
  • Avoid service degradation in combination with instances that don't support this (yet).
  • The source domain and original IDs can be reused eventually, for distinct objects.
  • Don't reveal private information (like object IDs a remote instance may or may not be aware of).
  • Detect success, ability to fall back cleanly on e.g. LOLA Portability.

My Idea

Moving instance's timeline

  1. Expose the moving instance's endpoints on the old and new domain simultaneously.2

  2. Determine what to move. This should take the form of a dictionary of URL prefixes, e.g.

    old new
    https://old.example.com/ https://new.example.com/
    https://example.com/old/ https://example.com/new/
    https://example.com/ future-protocol://example.com/

    More specific paths on the same (sub)domain have precedence over shorter ones when selecting an entry in the table. The mapping MUST be idempotent when applied repeatedly.

  3. Host authorisation of receipt on the new domain. That can just be 2. attached to the "new" Actor.

  4. Broadcast an Activity with 2. as payload to announce the move, addressed to …#Public.

    The moving instance can choose how far to broadcast here, but SHOULD deliver it to the Actor's followers at least.

  5. Detect use of the old endpoints. Reply as normal, but also resolve HTTP Signature -> key -> owner (Actor) -> inbox and send the Activity from 4. there. The moving instance SHOULD debounce and rate-limit this per receiving domain. This phase SHOULD last relatively long.

  6. Fall back to e.g. Move-broadcasting according to LOLA Portability.

    (As long as this scheme's aliasing is in place, such a Move should resolve into a "no change" operation that can be discarded immediately.)

When receiving the announcement from 4. or 5.

  1. Remember the prefix changes in the context of that specific Actor.

    If such changes are already remembered for that Actor, the receiving instance MUST NOT clear the existing information, but rather MUST update it so that chained moves A -> B, B -> C are resolved to A -> C.

  2. Supporting receiving instances MUST do either all or none of the following:

    1. if affected, fetch the Actor at its new location and update its information,

    2. reply with an Accept or other activity to confirm the domain move,

    3. apply the prefix replacement rules when persisting new objects,

    4. update the IDs of objects attributed to the Actor according to the replacement.

      This step can be done slowly as a background job, as the moving instance still responds on the old domain.

Note that before the individual object move occurs, independent copies may exist in the new and old location simultaneously, in particular the Actor. As such, the migration is not a pure update but can require merging relations in a database transaction. Where conflicts happen (duplicate likes, …), the new location's data SHOULD always take precedence. The deduplication process does not broadcast activities, for example no Undo is sent when a Like is deduplicated (und the assumption that the moving instance has already done the same).

This can largely be mitigated by breadcrumbs as in LOLA Portability (§7.1.8, §7.1.9), but possibly not entirely especially in cases where support for them is added later.

  1. The receiving instance SHOULD eventually accept objects located on the old path prefixes while treating them as independent from those that were moved. Reliably mismatched cryptographic keys or the old instance being unreachable for some time could be used as cue for this behaviour.

    Objects that are not cryptographically or otherwise reliably attributed to the moved Actor MUST NOT be associated with them.

When receiving the Accept from 9.2.

  1. The moving instance can now assume that the alias/rewrite is in place, so it starts interacting as the new location, if applicable.

Open questions

How does the moving instance determine which inboxes have accepted the move, especially in context inboxes that are shared between multiple Actors?

Must the change be accepted individually by each associated Actor? This may be prohibitively expensive on large observing instances with a shared inbox.

Maybe the moving instance should deliver an activity as both its old and new identity if unsure. Maybe the key-ID can be unified in a backwards-compatible way to partially avoid this issue.

Footnotes

  1. There may be ways around this, but I'm not sure they wouldn't have tradeoffs.
    Additionally, testing individual moves with a single actor first is likely helpful to detect problems.

  2. This is not a hard requirement, but it helps with making the move gradual and backwards-compatible.

@silverpill
Copy link

FEP-ef61 solves this problem.

@qazmlp
Copy link

qazmlp commented Oct 11, 2024

FEP-ef61 solves this problem.

I don't see how that's applicable to existing instances.
(The FEP does point out that the scheme isn't backwards-compatible.)

@silverpill
Copy link

Existing instances?
FEP-ef61 solves the problem of attaching identity and data to a domain name, and it can be implemented in existing software. Implementers can use compatible IDs, this is covered in Compatibility section.

@TallTed

This comment was marked as resolved.

@ThisIsMissEm ThisIsMissEm changed the title Support for moving the domain of an entire server (and all it's hosted actors, activities, and objects) Support for moving the domain of an entire server (and all its hosted actors, activities, and objects) Oct 16, 2024
@tesaguri
Copy link

tesaguri commented Oct 17, 2024

The process of retiring a ccTLD has a transition period of 5 to 10 years (https://www.iana.org/help/cctld-retirement), so we have plenty of time to deploy the solution and migrate existing actors. On that premise, a generic solution like nomadic identity sounds preferable to me. Given that the solution needs to be implemented by remote servers as well, I guess an ad-hoc solution would have trouble motivating remote implementers.

@ThisIsMissEm
Copy link
Author

My thinking is that 5-10 years isn't that long in terms of authoring specifications and getting implementation support, hence raising this now

@evanp
Copy link
Collaborator

evanp commented Oct 25, 2024

One way for this to work, and the way most Web servers handle this in 2024, is using a permanent redirect for all objects on the old domain to the new domain. So, when someone requests https://example.io/note/1, they get a 301 or 308 HTTP code that gives the new Location at https://example.social/note/1. Ideally, the client that receives this redirect does two things: 1) follows the redirect and 2) updates its link to use that new value. Unfortunately, that would also require updating any known references to that ID; for example, attributedTo or following or other places IDs are used.

This process would be slow; would be subject to pretty aggressive caching on the part of remote servers, and would probably require some careful maintenance of IDs and relationships in the remote server database.

This wouldn't work at all for a server going offline without warning. It might be possible to keep a directory or list of mappings for servers that go offline this way, but they'd have to be maintained by someone trusted.

We have some other ideas in issue triage, like using a Move activity or LOLA to announce a move for every single user. That seems like a big step with a lot of processing, especially for big instances.

Another option is just sending a Move activity from the server actor, but it's not actually clear what makes a server actor represent the server. We think this is pretty reasonable for O(10^6) or even O(10^7) servers (so, biggest Mastodon servers).

As a last resort, there are some cases where control of the actor's private key could be used to assert identity. There's not any easy way to do this; we'd need a lot of infrastructure for it. It's a lot easier to just use a social structure, like, "hey, everybody, example.io is now at example.social" and patch it up at the implementation level.

I think at least we need to open up some conversation in a primer page about this.

@evanp evanp added the Needs Primer Page Needs a page in the ActivityPub primer label Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Primer Page Needs a page in the ActivityPub primer
Projects
None yet
Development

No branches or pull requests

6 participants