Skip to content

Instantly share code, notes, and snippets.

@leo60228
Last active December 7, 2024 13:32
Show Gist options
  • Save leo60228/2535bc781abcbca76c99cb489c1d960b to your computer and use it in GitHub Desktop.
Save leo60228/2535bc781abcbca76c99cb489c1d960b to your computer and use it in GitHub Desktop.
  1. have a pds and invite code ready (the bsky.social sharding code will break in exciting ways if you try to use it as the PDS)
  2. install openssl, jwt-cli, and goat
  3. generate a NIST P-256 keypair (K-256 is the default for atproto, but jwt-cli doesn't support it):
$ openssl ecparam -name prime256v1 -genkey -noout -out private.key

$ openssl pkcs8 -topk8 -nocrypt -in private.key -out private.pem

$ openssl ec -in private.pem -pubout -out public.pem
read EC key
writing EC key
  1. convert it to multibase encoding. can't find a cli tool that does this, so, uh:
$ npm i --silent @atproto/crypto

$ node -e 'console.log(require("@atproto/crypto").formatMultikey("ES256", process.argv[1]))' "$(openssl ec -pubin -in public.pem -text 2>/dev/null | grep -Pzo '(?s)(?<=pub:\n    ).*(?=\nASN1)' | tr -d ':\n\0 ')"
zDnaeg9dgYJL3UUMHWcmNadNuEszJxjfBXJVWs2WsyMHjb89g
  1. make your did json at /.well-known/did.json:
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/multikey/v1",
    "https://w3id.org/security/suites/secp256k1-2019/v1"
  ],
  "id": "did:web:didweb.vriska.dev",
  "alsoKnownAs": [
    "at://vriska.dev"
  ],
  "verificationMethod": [
    {
      "id": "did:web:didweb.vriska.dev#atproto",
      "type": "Multikey",
      "controller": "did:web:didweb.vriska.dev",
      "publicKeyMultibase": "zDnaeg9dgYJL3UUMHWcmNadNuEszJxjfBXJVWs2WsyMHjb89g"
    }
  ],
  "service": [
    {
      "id": "#atproto_pds",
      "type": "AtprotoPersonalDataServer",
      "serviceEndpoint": "https://pds.vriska.dev"
    }
  ]
}
  1. point your handle to the did (it can be the same domain but doesn't have to be)
  2. make sure it resolves properly
$ goat resolve vriska.dev | head -n2
{
  "id": "did:web:didweb.vriska.dev",
  1. generate a service auth token to assert ownership of the did
$ ACCESS_TOKEN="$(jwt encode -A ES256 --exp=5m -i 'did:web:didweb.vriska.dev' -a 'did:web:pds.vriska.dev' -P "lxm=com.atproto.server.createAccount" -S @private.pem)"
  1. make the account
$ goat account create --pds-host https://pds.vriska.dev --handle vriska.dev --password "$PASSWORD" --invite-code "$INVITE_CODE" --email "$EMAIL" --existing-did 'did:web:didweb.vriska.dev' --service-auth "$ACCESS_TOKEN"
Success!
DID: did:web:didweb.vriska.dev
Handle: vriska.dev
  1. get the newly generated key
$ goat account login -u vriska.dev -p "$PASSWORD"

$ goat account plc recommended
{
  "alsoKnownAs": [
    "at://vriska.dev"
  ],
  "verificationMethods": {
    "atproto": "did:key:zQ3shjCZuawhGX55NqAAfCqTBaNfnPDLGRTKtpMvss1xa7Ayd"
  },
  "rotationKeys": [
    "did:key:zQ3shqh6WnxZp5Tm3zNrwQVb68mAJA2Zqh3CH3cm1p8MzMsrR"
  ],
  "services": {
    "atproto_pds": {
      "type": "AtprotoPersonalDataServer",
      "endpoint": "https://pds.vriska.dev"
    }
  }
}
  1. update the did.json with it (just change the publicKeyMultibase field, don't include the did:key: prefix)
  2. activate the account
$ goat account activate
  1. you should be able to sign in like normal
@wiidotmom
Copy link

I had to add -P "lxm=com.atproto.server.createAccount" to step 8 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment