{
"path": "/3mjx3u2sq4c25",
"site": "at://did:plc:lmftezsq52hi53taz762s7pc/site.standard.publication/3miesyulmok22",
"tags": [
"atproto",
"bluesky"
],
"$type": "site.standard.document",
"title": "PLCに間違ったverificatonMethodsを書き込んでしまったら",
"updatedAt": "2026-04-20T18:51:50.990Z",
"description": "自爆しただけです",
"publishedAt": "2026-04-20T18:27:38.237Z",
"textContent": "\n\n上記で書いたようにセルフホストPDSからBluesky公式PDSに戻る過程でPLC Directoryに間違ったverificationMethodsを書き込んでしまい(まずよく分かっていなかった)、Blueskyにログインはできてもまったく操作不能なうえにgoatコマンドによるPLC操作も https://boat.kelinci.net/plc-applicator での操作も全てBadJwtSignature > jwt signature does not match jwt issuer になってしまうようになりどうしようもなくなっていました。(通常のPDSではなんとかなるものがBluesky公式だとこうなってしまうらしい)\n\n偶然過去に作って本体が行方不明だった rotation key を旧PDSに残っていたファイル(/pds/actors/2文字の数字かアルファベット/自分のDID/key というファイル)から復元してもらいここからなんとか verificatonMethodsを書き換えることに。\n\nまずplc operationのためのトークンを取得しなければいけないのですがこれがgoat account plc request-tokenコマンドはjwt signatureなんとかなエラーになってしまいます。\n\nそんなわけでgoat account service-auth-offlineで上記の鍵を使いBearerトークンを生成しそこからplc operationのためのトークンを取得します。ここではBearerトークンとしてtokenに出力しそのトークンを使ってplc operationのコードを要求します。\n\ngoat account service-auth-offline\\\n --atproto-signing-key {MULTIKEY}\\\n --iss {自分のDID}\\\n --lxm com.atproto.identity.requestPlcOperationSignature\\\n --aud did:web:bsky.social > token\n\ncurl -X POST https://bsky.social/xrpc/com.atproto.identity.requestPlcOperationSignature \\\n -H \"Authorization: Bearer $(cat token)\"\n\nこの後登録されていたメールアドレスにSign in to Blueskyという件名のメールが届きXXXXX-XXXXX という形式のコードを得られました。\n\n署名されたDID documentを作るために accessJwt が必要なのでcurlでログインしその出力から得ます。\n\ncurl -X POST https://bsky.social/xrpc/com.atproto.server.createSession \\\n-H \"Content-Type: application/json\" \\\n-d '{\n\"identifier\": \"ハンドル名\",\n\"password\": \"パスワード\"\n}' > jwt.json\n\n\n出力されたjwt.jsonファイルからaccessJwt の項目を見つけそれを access として保存しました。\nこの accessと先ほどのメールのコードを使い署名されたDID Documentを作成します。\n\n各項目は goat account login -u ubanis.com -p パスワード --pds-host Blueskyでの所属PDSのURL してから goat account plc recommended で表示された内容に合わせます。\n\nおかしくなっていた verificatonMethods ではないことを確認し、curlコマンドからの出力を ope.json として保存しました。\n\ncurl -X POST https://bsky.social/xrpc/com.atproto.identity.signPlcOperation \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer $(cat access)\" \\\n -d '{\n \"token\": \"メールに届いたコード\",\n \"alsoKnownAs\": [\n \"at://ハンドル名\"\n ],\n \"rotationKeys\": [\n \"did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg\",\n \"did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK\"\n ],\n \"verificationMethods\": {\n \"atproto\": \"did:key:zQ3shekatj4YwJqyUpWKqmjrYvCsxCMCfS56yXHXhPxKeFTgj\"\n },\n \"services\": {\n \"atproto_pds\": {\n \"type\": \"AtprotoPersonalDataServer\",\n \"endpoint\": \"https://shimeji.us-east.host.bsky.network\"\n }\n }\n}' > ope.json\n\n\n最後に accessトークンを使いPLC Directoryに書き込みます。\n\ncurl -X POST https://bsky.social/xrpc/com.atproto.identity.submitPlcOperation \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer $(cat access)\" \\\n -d @ope.json\n\n特になんの応答もないので正しく書き込まれたのか確認します。\n\ncurl https://plc.directory/自分のDID | jq .\n\n出力です。\n\n{\n \"@context\": [\n \"https://www.w3.org/ns/did/v1\",\n \"https://w3id.org/security/multikey/v1\",\n \"https://w3id.org/security/suites/secp256k1-2019/v1\"\n ],\n \"id\": \"did:plc:lmftezsq52hi53taz762s7pc\",\n \"alsoKnownAs\": [\n \"at://ubanis.com\"\n ],\n \"verificationMethod\": [\n {\n \"id\": \"did:plc:lmftezsq52hi53taz762s7pc#atproto\",\n \"type\": \"Multikey\",\n \"controller\": \"did:plc:lmftezsq52hi53taz762s7pc\",\n \"publicKeyMultibase\": \"zQ3shekatj4YwJqyUpWKqmjrYvCsxCMCfS56yXHXhPxKeFTgj\"\n }\n ],\n \"service\": [\n {\n \"id\": \"#atproto_pds\",\n \"type\": \"AtprotoPersonalDataServer\",\n \"serviceEndpoint\": \"https://shimeji.us-east.host.bsky.network\"\n }\n ]\n}\n\nこうして復旧が完了しました。\n\n\n\n\n\nこのお二人の親身なご協力のおかげです。本当にありがとうございました。BaileyさんはPDSを簡単に移動できるPDS Mooverの作者の方です。多分これで普通に公式PDSに戻っていればこのような事故はなかったでしょう。\n\n\n\n"
}