Skip to content

0015 repo migration pds - #91

Open
afbase wants to merge 5 commits into
bluesky-social:mainfrom
afbase:0014-repo-migration-pds
Open

afbase wants to merge 5 commits into
bluesky-social:mainfrom
afbase:0014-repo-migration-pds

Conversation

@afbase

@afbase afbase commented Mar 20, 2026

Copy link
Copy Markdown

Summary

Adds proposal 0014: a destination-initiated, encrypted account transfer protocol for AT Protocol that replaces the current client-orchestrated migration model.

  • User navigates to the destination PDS's migration UI, authorizes via OAuth, and the destination PDS pulls all account data directly from the source
    PDS
  • Account data (repo CAR, blobs, preferences, private state) is delivered in a single streaming HTTP response encrypted with HPKE (RFC 9180)
  • Three new XRPC endpoints: exportAccount, completeTransfer, getTransferStatus
  • A /.well-known/atproto-transfer discovery document for source PDS capability advertisement

Motivation

The current migration flow requires 14+ individual XRPC calls orchestrated by the client (user's device), with no resume capability, blob upload rate limits that can make large migrations impossible (1,000/day), and PLC tokens that expire mid-process. This proposal moves data directly between PDS servers, eliminating the client bottleneck and improving UX to a single OAuth-confirm-and-wait interaction.

 1. Sequence diagram (line 104-108): Added opt Missing blobs recovery block between "all chunks confirmed" and finalizeTransfer
  2. Implementation note (line 318): Manifest sizing guidance inserted between receiveAccount behavior and pushChunk section
  3. finalizeTransfer reference (line 414): Updated to mention listMissingBlobs as the recovery path
  4. New listMissingBlobs endpoint (lines 422-452): Full endpoint spec with auth, input/output, and behavior
  5. Error table (line 466): Added TransferNotReady error code

  - Added a normative requirement (MUST) for at least two non-expired keys at all times
  - Added a SHOULD for staggered expiration with overlap exceeding the cache max-age
  - Explained the rationale (rotation continuity + compromise fallback)
  - Updated step 3 of the rotation procedure to include the "provided at least two non-expired keys remain" guard

update to hpke over http/3

update to make it dead simple

update repo migration for oauth clarity

update language on repo construction from the blob content-type

update tls language

get rid of source PDS data retention

remove the transition:transfer scope for strict rpc: fine grained
scoping; this would mean rpc: scope work to be done for the cocoon pds
implementation.

change may to should

change private state and preferences to required for implementations
@afbase
afbase force-pushed the 0014-repo-migration-pds branch from 7052009 to 7992f76 Compare March 20, 2026 04:47
@DavidBuchanan314

Copy link
Copy Markdown

I think direct PDS-to-PDS migrations are a great idea, but I'm not sure any new protocol-level features are required to make it work well.

What is the threat model that adding HPKE defends against? In my view, if there's a TLS-intercepting adversary then you have other problems (in particular, they could tamper with the advertised HPKE keypair!)

@afbase

afbase commented Mar 20, 2026

Copy link
Copy Markdown
Author

What is the threat model that adding HPKE defends against? In my view, if there's a TLS-intercepting adversary then you have other problems (in particular, they could tamper with the advertised HPKE keypair!)

Yes that was the idea to protect against. @DavidBuchanan314 that makes sense - i.e. a TLS intercepting attack could also tamper with the HPKE values.

@surfdude29

Copy link
Copy Markdown
Contributor

This looks like a great idea!

FYI two links in the Adversarial Migration section are broken for me:

the David Buchanan one I think should be:
https://www.da.vidbuchanan.co.uk/blog/adversarial-pds-migration.html

and the Bryan Newbold one I think (but not completely sure) should be:
https://whtwnd.com/bnewbold.net/3lj7jmt2ct72r

@Tamschi

Tamschi commented Mar 20, 2026

Copy link
Copy Markdown

I like this a lot, but I'm concerned that making migration too convenient could make some people unnecessarily vulnerable to tech-support-scams that steal accounts (as mentioned here).

In my opinion, this proposal here should also mandate a clear, easy-to-use adversarial rollback flow on the source PDS and, ideally, should include some practical guidelines to make the relative danger of the initial flow clear without resorting to scare tactics. Google just published something similar for sideloading untrusted apps from untrusted sources, though I think ATProto can do this without long waits like this.
(Maybe having people wait a minute to get them to actually read the warning label would be a good idea, though.)

@mcprostar205

Copy link
Copy Markdown

This proposal makes "credible exit" so much more a reality and available to the masses. However, this capability should be a feature accessed from user's account page (ie. {pds}/account").

@bnewbold bnewbold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(commenting only on the proposal as an artifact, not the contents)

Thanks for the contribution! I think this is a relevant and well written proposal, and we should merge it to this proposals repo. There are meta process and governance questions about who decides which proposals are relevant and get merged, but I don't think we need to block this until that is figure out.

A couple things before merging:

  • please add some context at the top: authors/contributors (just Clinton?), the date, and maybe a bit of informal context about "epistemic confidence" and state of consensus/implementation. See some examples in proposal 0010 and 0008, in quotes/italics at the top. we can/should go over all the earlier proposals and add that sort of thing when missing
  • sounds like there are some broken links reported by @surfdude29
  • add a link to some discussion form. eg, it looks like there is a thread on discourse (https://discourse.atprotocol.community/t/proposal-0014-pds-to-pds-repository-migration/686), or you could open a github discussion thread, or an issue in this repo. I don't think the PR thread is a good place for substantial discussion

@bnewbold

Copy link
Copy Markdown
Contributor

I left some comments over on discourse here: https://discourse.atprotocol.community/t/proposal-0014-pds-to-pds-repository-migration/686

…transfer Remove the HPKE encryption layer, blobpack format, and `/.well-known/atproto-transfer` discovery endpoint entirely. Replace the single encrypted streaming response from `exportAccount` with individual calls to existing ATProto sync endpoints (`getRepo`, `listBlobs`, `getBlob`, `getPreferences`). Simplify `exportAccount` to return only private account state (email, invite codes) as plain JSON. Delay the PLC verification code request until after all data is safely transferred. Add a detailed step-by-step transfer flow with explicit PAR OAuth requirements and a `signPlcOperation` field mapping table.
@afbase
afbase force-pushed the 0014-repo-migration-pds branch from 0841686 to b1bfb06 Compare March 27, 2026 19:52
@Ashex

Ashex commented Apr 22, 2026

Copy link
Copy Markdown

I want to chime in with my own two cents on this from the perspective of Stratos as it's intent is to be as on protocol as possible and allow some form of credible exit and this proposal fills a gap it has.

As it stands the PLC directory isn't used because the current barrier to update a doc is too high with too many risks (all or nothing) so instead it works by attestations which introduces a level of complexity when a user chooses to migrate their data to another stratos service. It's easy to get your data but then once imported elsewhere, we need to be able to recognize that the user has migrated which is where a service-to-service mechanism is desirable since the third-party PLC is expected to be the authority for on protocol "data stores".

The working idea I had is to do some form of signature verification on the target service, and the target can validate by querying the source service. Once this verification passes an import occurs and then blobs can be migrated before the target confirms migration and the source recognizes it. But we still need to solve the question of what to do in the case of a hostile source.

So if this is implemented we could utilise a similar process built on these methods.

@bnewbold

Copy link
Copy Markdown
Contributor

(oh shoot, I just realized that a separate recent proposal clobbered this proposal number. that wasn't intentional, sorry about that!)

@afbase

afbase commented Apr 24, 2026

Copy link
Copy Markdown
Author

all good @bnewbold! Just motivation for me to get back to this one!

@afbase afbase changed the title 0014 repo migration pds 0015 repo migration pds May 28, 2026
@afbase
afbase requested a review from bnewbold May 28, 2026 04:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants