公式PDSから外部PDSに引っ越して、また戻ってみるまで
この記事は Bluesky / ATProtocol Advent Calendar 2025 の5日目です。
Blueskyでは、公式のPDS(bsky.social)からサードパーティのPDSへアカウントを移行できるようになっています。さらに、最近のアップデートで「過去に公式PDSにいたことがあるアカウントなら、再び公式PDSへ戻れる」ようになりました。
この記事では、テスト用アカウント tmp-account-62bf44.momoiro.me を使って、
- 公式PDSから外部PDSへの移行
- 外部PDSから公式PDSへの帰還
という2パターンを、実際に叩いたコマンドとその出力を追いながら確認していきます。
ちなみに、最終的な実際のDIDやログなどは、次のようなURLからも確認できます(この記事の検証用アカウントのリンクです)
- https://plc.directory/did:plc:plxvnjvuulpk3kydpgkmczwg (DID Document)
- https://plc.directory/did:plc:plxvnjvuulpk3kydpgkmczwg/log/audit (Operation Log)
- https://atproto.at/viewer?uri=did:plc:plxvnjvuulpk3kydpgkmczwg (atproto.at)
- https://bsky.app/profile/did:plc:plxvnjvuulpk3kydpgkmczwg (bsky.app)
(検証用PDSがクローラーに繋がっておらず、bsky.appだと自鯖からの投稿が表示されない...)
前提と準備
今回の検証環境は次の通りです。
- 移行するアカウント:
tmp-account-62bf44.momoiro.me - CLIツール:
goat - 移行先PDS:
https://tmp-pds-62bf44.momoiro.me - 招待コード:
tmp-pds-62bf44-momoiro-me-y5gfu-n2ufl
また、DIDやPLCの挙動を理解するために、DID Document と Operation Log も適宜確認しながら進めていきます。
初期状態の確認
まずは公式PDSにいる状態で、DIDまわりの情報を確認しておきます。
$ goat resolve tmp-account-62bf44.momoiro.me
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
"https://w3id.org/security/suites/secp256k1-2019/v1"
],
"id": "did:plc:plxvnjvuulpk3kydpgkmczwg",
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"verificationMethod": [
{
"id": "did:plc:plxvnjvuulpk3kydpgkmczwg#atproto",
"type": "Multikey",
"controller": "did:plc:plxvnjvuulpk3kydpgkmczwg",
"publicKeyMultibase": "zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
}
],
"service": [
{
"id": "#atproto_pds",
"type": "AtprotoPersonalDataServer",
"serviceEndpoint": "https://phellinus.us-west.host.bsky.network"
}
]
}
同じDIDについて、PLC Operation Logも確認します。
$ goat plc history tmp-account-62bf44.momoiro.me
{
"alsoKnownAs": [
"at://tmp-momoiro-62bf44.bsky.social"
],
"prev": null,
"rotationKeys": [
"did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg",
"did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK"
],
"services": {
"atproto_pds": {
"endpoint": "https://phellinus.us-west.host.bsky.network",
"type": "AtprotoPersonalDataServer"
}
},
"sig": "f-XpwyRk5tDhHSi1cOO_WD3xE0Jl0YmHSLHzkSVbKz1_joqnVxx1r1iQ6iQo3yFWS6aoSZrYFZ-h9bczT2j-8w",
"type": "plc_operation",
"verificationMethods": {
"atproto": "did:key:zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
}
}
{
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"prev": "bafyreid255lknnfc32w2wa3zstawnrvxczpb6vqabvu37kolrmvhyfuxty",
"rotationKeys": [
"did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg",
"did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK"
],
"services": {
"atproto_pds": {
"endpoint": "https://phellinus.us-west.host.bsky.network",
"type": "AtprotoPersonalDataServer"
}
},
"sig": "BBux8NqfTtyBT3KsQv98gmWTCs7DjpMSkGbDibRCoDB16lK2F5q8EemyF6SjhhC1nUyUww5-rCxsRDOYIr7iwg",
"type": "plc_operation",
"verificationMethods": {
"atproto": "did:key:zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
}
}
1. Rotation Keyを追加する
外部PDSへの移行やDIDの書き換えには、Rotation Key と呼ばれる管理用の鍵を使用します。ここでは、公式PDSにログインし、Rotation Keyを追加するところから始めます。
1-1. 公式PDSにログイン
まずは移行元となる公式PDSにログインし、現在の状態を確認します。
$ goat account login -u tmp-account-62bf44.momoiro.me -p password
$ goat account check-auth
DID: did:plc:plxvnjvuulpk3kydpgkmczwg
Host: https://phellinus.us-west.host.bsky.network
{
"activated": true,
"expectedBlobs": 1,
"importedBlobs": 1,
"indexedRecords": 2,
"privateStateValues": 0,
"repoBlocks": 5,
"repoCommit": "bafyreihdu6jf32lw5trvav77ma7dnwpp66u53cbmgtdxlw7alwupxcq67u",
"repoRev": "3m73qirlqww2s",
"validDid": true
}
1-2. 新しいRotation Keyを生成
続いて、今後のDID操作に使う新しいRotation Keyを生成します。
$ goat key generate
Key Type: P-256 / secp256r1 / ES256 private key
Secret Key (Multibase Syntax): save this securely (eg, add to password manager)
<secret key>
Public Key (DID Key Syntax): share or publish this (eg, in DID document)
did:key:zDnaeqaBDtbbs4GWaQMsufDbvyTL1hmi9cLbSakojcTimSRSi
秘密鍵は必ず秘匿して保管します。公開鍵はこのあとRotation Keyとして登録します。
1-3. メール認証を経てRotation Keyを追加
PLC操作にはメールによるトークン認証が必要になります。
$ goat account plc request-token
Success; check email for token.
$ goat account plc add-rotation-key --token XXXXX-XXXXX did:key:zDnaeqaBDtbbs4GWaQMsufDbvyTL1hmi9cLbSakojcTimSRSi
Success!
こんなメールが届きます
ちなみに、自鯖環境などでSMTP設定を持っていない場合はメールは送られてきませんが、PDSのログレベルを上げると送信されるはずだったメール本文を確認できるので、それをトークンとして利用できます。
1-4. Operation Logで反映を確認
追加したRotation Keyが正しく反映されているか、Operation Logを確認します。
$ goat plc history tmp-account-62bf44.momoiro.me
<すでに示した2つのoperationは省略>
{
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"prev": "bafyreicanpocuueys4heuft7leadvdr7rb6gr7v4nwhdftwndakarahdp4",
"rotationKeys": [
"did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg",
"did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK",
"did:key:zDnaeqaBDtbbs4GWaQMsufDbvyTL1hmi9cLbSakojcTimSRSi"
],
"services": {
"atproto_pds": {
"endpoint": "https://phellinus.us-west.host.bsky.network",
"type": "AtprotoPersonalDataServer"
}
},
"sig": "wRyjYV2E9G6NoP3tTPmg9J2G06gJmYfrnCp0mac7Oas1OA_ar04myj5ok_HvvGhNMhSu0a-UAMB7a4UCYFoZHw",
"type": "plc_operation",
"verificationMethods": {
"atproto": "did:key:zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
}
}
最新のエントリに新しい rotationKeys が追加されています。DID Document自体 (goat resolve) は、Rotation Keyの追加だけでは変わらず、Operation Logにだけ更新が現れます。
2. 外部PDSへ引っ越してみる
ここからは、公式PDSからサードパーティPDS (tmp-pds-62bf44.momoiro.me) へアカウントを移行していきます。
大きな流れはここを参考にしています。
https://github.com/bluesky-social/pds/blob/main/ACCOUNT_MIGRATION.md
2-1. リポジトリとBlobのバックアップ
PDSが突然落ちても復元できるよう、まずは現状のリポジトリをCARファイルとしてエクスポートしておきます。 移行元サーバーを失うとリポジトリデータも失われるため、普段からこのようにバックアップを取っておくことが重要です。
$ goat repo export tmp-account-62bf44.momoiro.me
downloading from https://phellinus.us-west.host.bsky.network to: tmp-account-62bf44.momoiro.me.20251204004838.car
$ goat repo ls ./tmp-account-62bf44.momoiro.me.20251204004838.car
app.bsky.actor.profile/self bafyreibwiu6gel5cnxeffijnejjh4pfe2iky7xokfmkwrgwmvs4lva4nia
app.bsky.feed.like/3m73shlqof423 bafyreifnmufpts5ik5j3clics5pjj3rvw4oyevbyv5ak74v6r6munhx6hi
app.bsky.feed.post/3m73se5ytpk2u bafyreidrrd4jsu7e7ajoziv7e3nfytts65ebu6mie3fxu7hqdfpoaoucsy
app.bsky.feed.post/3m73sep2zas2u bafyreiaqohcskxbfbw23wqumsvu4reqegwhmw7jdwmouikouw2fcf5kzka
app.bsky.graph.follow/3m73qiqkln32f bafyreiegj72lvev6kvyw3e3vygjxhqzwamdfmd6njn6norpvmesnrx3xry
$ goat repo inspect ./adbenter/tmp-account-62bf44.momoiro.me.2025120400
4838.car
ATProto Repo Spec Version: 3
DID: did:plc:plxvnjvuulpk3kydpgkmczwg
Data CID: bafyreifnrv6jm66yvejfhswtxq4w2vkgkd5ib5moogphvgyuiqkdv5rpmq
Prev CID: <nil>
Revision: 3m73shlqsc423
$ goat blob export tmp-account-62bf44.momoiro.me
repo ls で表示されるレコードは、goat ls <handle> と同等の内容で、プロフィールや投稿、フォローなどのレコードが確認できます。
2-2. 移行先PDSに招待コードを用意
多くのPDSでは、新規アカウント作成時に招待コードが必要です。自前PDSの場合は、管理者として次のように発行します。
$ goat pds admin create-invites --pds-host https://tmp-pds-62bf44.momoiro.me --admin-password admin_password
tmp-pds-62bf44-momoiro-me-y5gfu-n2ufl
2-3. 既存DIDでアカウントを作成
既存のDIDを持ったまま移行先PDSにアカウントを作るには、service-auth が必要です。
元のPDSが利用可能でservice-auth を発行できる場合は、次のようにします。
$ goat account service-auth \
--audience did:web:tmp-pds-62bf44.momoiro.me \
--endpoint com.atproto.server.createAccount
発行したservice-authを使って、移行先PDS上にアカウントを作成します。
$ goat account create \
--pds-host https://tmp-pds-62bf44.momoiro.me \
--handle tmp-account-62bf44.momoiro.me \
--password <new-password> \
--existing-did did:plc:plxvnjvuulpk3kydpgkmczwg \
--email tmp-momoiro-62bf44@momoiro.me \
--invite-code tmp-pds-62bf44-momoiro-me-y5gfu-n2ufl \
--service-auth <上で発行したJWT>
Success!
DID: did:plc:plxvnjvuulpk3kydpgkmczwg
Handle: tmp-account-62bf44.momoiro.me
元のPDSが協力的でない場合は、DID Documentの verificationMethod を一時的に切り替えて、自前で service-auth を発行する必要があります(詳しくは以下の英語記事などを参照)。
https://www.da.vidbuchanan.co.uk/blog/adversarial-pds-migration.html
2-4. 移行先PDSにログインし、状態を確認
移行先PDS上でアカウントにログインし、DIDまわりの状態を確認します。
$ goat account login \
--pds-host https://tmp-pds-62bf44.momoiro.me \
-u tmp-account-62bf44.momoiro.me \
-p <new-password>
$ goat account check-auth
DID: did:plc:plxvnjvuulpk3kydpgkmczwg
Host: https://tmp-pds-62bf44.momoiro.me
{
"activated": false,
"expectedBlobs": 0,
"importedBlobs": 0,
"indexedRecords": 0,
"privateStateValues": 0,
"repoBlocks": 2,
"repoCommit": "bafyreibkktzpueism7hzvwy7vsubjcttfjq4mqn3von3llv4v5tjl3nq5y",
"repoRev": "3m75cukommc2v",
"validDid": false
}
このタイミングでは、activated: false や validDid: false になっているはずです。これは、まだDID Documentの serviceEndpoint などを移行先PDSに向けていないためです。
2-5. 推奨DID設定を確認
移行先PDSにとって「こうなっていてほしい」DID Document案を goat で取得できます。
$ goat account plc recommended
{
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"verificationMethods": {
"atproto": "did:key:zQ3shWBNGVmve23tsVW7jJQ813AyzdeEepnWTGtvMtxAxewRU"
},
"rotationKeys": [
"did:key:zQ3shrXPCcUo1nM1eJah4WftobfqmNtscAff7G6cTBHQBjNi6"
],
"services": {
"atproto_pds": {
"type": "AtprotoPersonalDataServer",
"endpoint": "https://tmp-pds-62bf44.momoiro.me"
}
}
}
ここに含まれる services.atproto_pds.endpoint や verificationMethods.atproto、rotationKeys などを元に、次のステップで実際のDIDを書き換えていきます。
2-6. DID Documentを書き換える
まず、現在のDIDのデータを確認するには goat plc data tmp-account-62bf44.momoiro.me などが使えます。
今回の例では、次のように goat plc update で新しいOperationを生成しています。
$ goat plc update --pds https://tmp-pds-62bf44.momoiro.me \
--remove-rotation-key did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg \
--remove-rotation-key did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK \
--add-rotation-key did:key:zQ3shrXPCcUo1nM1eJah4WftobfqmNtscAff7G6cTBHQBjNi6 \
--atproto-key did:key:zQ3shWBNGVmve23tsVW7jJQ813AyzdeEepnWTGtvMtxAxewRU \
did:plc:plxvnjvuulpk3kydpgkmczwg > ./new-plc-operation.json
生成されたOperationのJSON:
{
"type": "plc_operation",
"rotationKeys": [
"did:key:zQ3shrXPCcUo1nM1eJah4WftobfqmNtscAff7G6cTBHQBjNi6",
"did:key:zDnaeqaBDtbbs4GWaQMsufDbvyTL1hmi9cLbSakojcTimSRSi"
],
"verificationMethods": {
"atproto": "did:key:zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
},
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"services": {
"atproto_pds": {
"type": "AtprotoPersonalDataServer",
"endpoint": "https://tmp-pds-62bf44.momoiro.me"
}
},
"prev": "bafyreiegrc4dqqxbb2jgrofo6tkb7xogpwypdhch5ugaoekcabey34xtgy"
}
これを先ほど用意したRotation Keyで署名し、PLC Directoryに提出します。
$ goat plc sign --plc-signing-key <secret key> ./new-plc-operation.json > signed-plc-operation.json
$ goat plc submit --did did:plc:plxvnjvuulpk3kydpgkmczwg ./signed-plc-operation.json
success
2-7. リポジトリをインポートし、新PDSをactivate
続いて、バックアップしておいたCARファイルを新しいPDSにインポートし、アカウントを有効化します。
$ goat repo import ./tmp-account-62bf44.momoiro.me.20251204004838.car \
--pds-host https://tmp-pds-62bf44.momoiro.me
$ goat account activate --pds-host https://tmp-pds-62bf44.momoiro.me
インポートとactivateが完了すると、goat account check-auth の activated や indexedRecords などが、移行元と同じになるはずです
2-8. 古いPDSをDeactivate
公式PDS側のアカウントを無効化しておきます。
$ goat account login \
--pds-host https://phellinus.us-west.host.bsky.network \
-u tmp-account-62bf44.momoiro.me \
-p <old-password>
$ goat account deactivate
2-9. 移行結果の確認
ここまでの操作によってDID DocumentとOperation Logが意図どおり更新されているか確認します。
$ goat resolve tmp-account-62bf44.momoiro.me
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
"https://w3id.org/security/suites/secp256k1-2019/v1"
],
"id": "did:plc:plxvnjvuulpk3kydpgkmczwg",
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"verificationMethod": [
{
"id": "did:plc:plxvnjvuulpk3kydpgkmczwg#atproto",
"type": "Multikey",
"controller": "did:plc:plxvnjvuulpk3kydpgkmczwg",
"publicKeyMultibase": "zQ3shWBNGVmve23tsVW7jJQ813AyzdeEepnWTGtvMtxAxewRU"
}
],
"service": [
{
"id": "#atproto_pds",
"type": "AtprotoPersonalDataServer",
"serviceEndpoint": "https://tmp-pds-62bf44.momoiro.me"
}
]
}
DID Documentの serviceEndpoint が移行先PDSに変わり、verificationMethod も更新されていれば成功です。
$ goat plc history tmp-account-62bf44.momoiro.me
<すでに示した3つのoperationは省略>
{
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"prev": "bafyreiegrc4dqqxbb2jgrofo6tkb7xogpwypdhch5ugaoekcabey34xtgy",
"rotationKeys": [
"did:key:zQ3shrXPCcUo1nM1eJah4WftobfqmNtscAff7G6cTBHQBjNi6",
"did:key:zDnaeqaBDtbbs4GWaQMsufDbvyTL1hmi9cLbSakojcTimSRSi"
],
"services": {
"atproto_pds": {
"endpoint": "https://tmp-pds-62bf44.momoiro.me",
"type": "AtprotoPersonalDataServer"
}
},
"sig": "HT-7E-8VrZI13MBKWVHILEbyIo2AzP35v8jGKlpAa8RGart4obzBRmK_Oekut-kw2Xmh1qeVCdZN5nqw0P6kPA",
"type": "plc_operation",
"verificationMethods": {
"atproto": "did:key:zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
}
}
{
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"prev": "bafyreidrapxotpbrwp6zlgmchmlilfx7xmpab7bq56bciidegww6wqwala",
"rotationKeys": [
"did:key:zQ3shrXPCcUo1nM1eJah4WftobfqmNtscAff7G6cTBHQBjNi6",
"did:key:zDnaeqaBDtbbs4GWaQMsufDbvyTL1hmi9cLbSakojcTimSRSi"
],
"services": {
"atproto_pds": {
"endpoint": "https://tmp-pds-62bf44.momoiro.me",
"type": "AtprotoPersonalDataServer"
}
},
"sig": "7lh1HSppoggpE7PsGzX8-RmLQRhba7vRwVTJGxS_-npdDfuQwmxvQZ0g8uXr8QXwNifpCZy8yyygYtPIVlv_yA",
"type": "plc_operation",
"verificationMethods": {
"atproto": "did:key:zQ3shWBNGVmve23tsVW7jJQ813AyzdeEepnWTGtvMtxAxewRU"
}
}
Operation Logにも新しい内容が反映されています。
(今回は一度verificationMethodsを変更し忘れために余分なoperationが入ってしまった)
プロフィールや投稿などはハンドルとDIDが変わっていないため、クライアント上から見ると「そのまま別PDSに引っ越した」ように見えます。
2-10. migrateコマンドの補足
補足として、ここまでの一連の処理(+α)は goat account migrate コマンドで一括して実行することも可能です。
$ goat account plc request-token
$ goat account migrate --pds-host <new pds> --new-handle <handle> --new-password <password> --plc-token <token>
ただしこの場合も、元PDSが service-auth を発行できる状態にある必要があります。
3. 外部PDSから公式PDSに戻る
今度は逆方向に、外部PDSから公式PDSへ「帰還」してみます。
基本的な流れは、先ほどとほぼ同じです。
- 外部PDS側でリポジトリをバックアップ
- 公式PDSにログインできるようにする
- DID Documentの
serviceEndpointを公式PDSに戻す - リポジトリをインポートし直し、公式PDSのアカウントをactivate
- 外部PDS側のアカウントをdeactivate
3-1. 外部PDSからリポジトリをエクスポート
まずは現在の外部PDS上のリポジトリをCARファイルとしてバックアップします。
$ goat repo export tmp-account-62bf44.momoiro.me
ここでも実際には前章と同じようにCARファイルが生成されるだけなので、詳細な出力は省略します。
3-2. 公式PDSにログイン
もし過去に公式PDSで使っていたパスワードを忘れてしまった場合は、bsky.appのログイン画面でプロバイダーを公式にした状態でパスワードリセットを行えば、再設定できます。
$ goat account login \
--pds-host https://bsky.social \
-u tmp-account-62bf44.momoiro.me \
-p <password>
3-3. 推奨DID設定を確認し、公式PDSを指すOperationを作成
公式PDSに戻すために、推奨されるDID設定を確認し、それに沿ったOperationを作成します。
$ goat account plc recommended
<省略>
$ goat plc update --pds https://phellinus.us-west.host.bsky.network \
--remove-rotation-key did:key:zQ3shrXPCcUo1nM1eJah4WftobfqmNtscAff7G6cTBHQBjNi6 \
--add-rotation-key did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg \
--add-rotation-key did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK \
--atproto-key did:key:zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR \
did:plc:plxvnjvuulpk3kydpgkmczwg > ./back-plc-operation.json
$ goat plc sign --plc-signing-key z42trJ8zcV9bqndGiVFhzJPSidZUPAFs7kAzzT5jY3yNyhJh ./back-plc-operation.json > signed-back-plc-operation.json
$ goat plc submit --did did:plc:plxvnjvuulpk3kydpgkmczwg ./signed-back-plc-operation.json
3-4. リポジトリをインポートし、公式PDSをactivate
バックアップしておいたCARファイルを公式PDSにインポートし、アカウントを有効化します。
$ goat repo import tmp-account-62bf44.momoiro.me.20251204004838.car
$ goat account activate
その後、外部PDS側にログインし、アカウントをdeactivateしておきます。
$ goat account login -u tmp-account-62bf44.momoiro.me -p somepasswords --pds-host https://tmp-pds-62bf44.momoiro.me
$ goat account deactivate
$ goat account logout
3-5. 戻ってこられたか確認
最後に、DID DocumentとOperation Logを確認して、公式PDSに正しく戻れているかを確認します。
$ goat resolve tmp-account-62bf44.momoiro.me
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
"https://w3id.org/security/suites/secp256k1-2019/v1"
],
"id": "did:plc:plxvnjvuulpk3kydpgkmczwg",
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"verificationMethod": [
{
"id": "did:plc:plxvnjvuulpk3kydpgkmczwg#atproto",
"type": "Multikey",
"controller": "did:plc:plxvnjvuulpk3kydpgkmczwg",
"publicKeyMultibase": "zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
}
],
"service": [
{
"id": "#atproto_pds",
"type": "AtprotoPersonalDataServer",
"serviceEndpoint": "https://phellinus.us-west.host.bsky.network"
}
]
}
$ goat plc history tmp-account-62bf44.momoiro.me
<すでに示した5つのoperationは省略>
{
"alsoKnownAs": [
"at://tmp-account-62bf44.momoiro.me"
],
"prev": "bafyreidys2lik3piedenelboxk24cwckzlm6jig6cif25q6lffkiezhp64",
"rotationKeys": [
"did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK",
"did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg",
"did:key:zDnaeqaBDtbbs4GWaQMsufDbvyTL1hmi9cLbSakojcTimSRSi"
],
"services": {
"atproto_pds": {
"endpoint": "https://phellinus.us-west.host.bsky.network",
"type": "AtprotoPersonalDataServer"
}
},
"sig": "yxqr5flfzg5bz9sJPoODlFSJA9N-Fjz9Jpgmc8syykIRMPzJhBsPCZ40wGZCtJ12M875nj56KqpYRKvL2Pqixg",
"type": "plc_operation",
"verificationMethods": {
"atproto": "did:key:zQ3shVUwMKmSDj8Cw3hkreDJVC3a68YMqKiY3EvcWLXCTRMtR"
}
}
これで、1章の終わりとほとんど同じ状態に戻りました。
4. おわりに
1日目とはだいぶ毛色の違う内容になりましたが、今回はテスト用アカウントを使って
- 公式PDSから外部PDSへ移行し、
- さらに外部PDSから公式PDSへ戻る
という往復を、goatコマンドを使って試してみました
実際の運用では goat account migrate のような高レベルコマンドに頼ることも多いと思いますが、
- Rotation Keyがどのように追加・利用されているのか
- DID Documentの
serviceEndpointがどのタイミングで切り替わるのか - PLC Operation Logがどんな単位で積み上がっていくのか
を一度でも手で追っておくと、「アカウントポータビリティ」がどのように実現されているのかを、より具体的にイメージできるようになると思います。
今回はBlobのエクスポート/インポート周りは軽く触れるだけにしましたが、実際に本番アカウントを移行する際は、必ず事前に全件バックアップを取ってから作業することを強くおすすめします。
また、協力的でない(あるいは落ちてしまった)PDSからの移行についても、今後あらためて実際に試してまとめてみたいと思っています。