Fork of github.com/did-method-plc/did-method-plc
1openapi: 3.0.0 2info: 3 title: "did:plc Directory Server API" 4 version: 0.1 5 contact: 6 name: "Protocol Team at Bluesky" 7 email: "protocol@blueskyweb.xyz" 8 url: "https://web.plc.directory" 9 description: | 10 DID PLC is a self-authenticating [DID](https://www.w3.org/TR/did-core/) which is strongly-consistent, recoverable, and allows for key rotation. 11 12 The central directory server receives and persists self-signed operation logs for each DID, starting with a "genesis operation" which defined the DID identifier itself. This document describes the HTTP API for interacting with the directory server to resolve DID Document, fetch audit logs, and submit signed operations. 13 14 The HTTP API is permissionless, but only valid (correctly signed) operations are accepted. Reasonable rate-limits are applied, but they should not interfer with account recovery in most situations. 15servers: 16 - url: https://plc.directory 17 18paths: 19 /{did}: 20 get: 21 description: "Resolve DID Document for the indicated DID" 22 operationId: ResolveDid 23 parameters: 24 - name: did 25 in: path 26 required: true 27 schema: 28 type: string 29 responses: 30 '200': 31 description: "Success, returned DID Document" 32 content: 33 application/did+ld+json: 34 schema: 35 $ref: '#/components/schemas/DidDocument' 36 '404': 37 $ref: '#/components/responses/404DidNotFound' 38 '410': 39 $ref: '#/components/responses/410DidNotAvailable' 40 x-codeSamples: 41 - lang: Shell 42 label: curl 43 source: | 44 curl -s https://plc.directory/did:plc:pyc2ihzpelxtg4cdkfzbhcv4 | jq . 45 - lang: Python 46 label: Python 47 source: | 48 import requests 49 50 did = "did:plc:pyc2ihzpelxtg4cdkfzbhcv4" 51 resp = requests.get(f"https://plc.directory/{did}") 52 resp.raise_for_status() 53 print(resp.json()) 54 post: 55 description: "Create new PLC Operation for the indicated DID" 56 operationId: CreatePlcOp 57 parameters: 58 - name: did 59 in: path 60 required: true 61 schema: 62 type: string 63 requestBody: 64 required: true 65 content: 66 application/json: 67 schema: 68 $ref: '#/components/schemas/Operation' 69 responses: 70 '200': 71 description: "Success, operation validated and persisted" 72 # TODO: what is returned here? 73 '400': 74 $ref: '#/components/responses/400BadOperation' 75 '404': 76 $ref: '#/components/responses/404DidNotFound' 77 '410': 78 $ref: '#/components/responses/410DidNotAvailable' 79 /{did}/log: 80 get: 81 description: "Get Current PLC Operation Chain" 82 operationId: GetPlcOpLog 83 parameters: 84 - name: did 85 in: path 86 required: true 87 schema: 88 type: string 89 responses: 90 '200': 91 description: "Success, retured operation log" 92 content: 93 application/json: 94 schema: 95 type: array 96 items: 97 $ref: '#/components/schemas/Operation' 98 '404': 99 $ref: '#/components/responses/404DidNotFound' 100 /{did}/log/audit: 101 get: 102 description: "Get PLC Operation Audit Log" 103 operationId: GetPlcAuditLog 104 parameters: 105 - name: did 106 in: path 107 required: true 108 schema: 109 type: string 110 responses: 111 '200': 112 description: "Success, retured audit log" 113 content: 114 application/json: 115 schema: 116 type: array 117 items: 118 $ref: '#/components/schemas/LogEntry' 119 '404': 120 $ref: '#/components/responses/404DidNotFound' 121 /{did}/log/last: 122 get: 123 description: "Get Latest PLC Operation" 124 operationId: GetLastOp 125 parameters: 126 - name: did 127 in: path 128 required: true 129 schema: 130 type: string 131 responses: 132 '200': 133 description: "Success, returned latest operation" 134 content: 135 application/json: 136 schema: 137 $ref: '#/components/schemas/LogEntry' 138 '404': 139 $ref: '#/components/responses/404DidNotFound' 140 /{did}/data: 141 get: 142 description: "Get Current PLC Data for the indicated DID" 143 operationId: GetPlcData 144 parameters: 145 - name: did 146 in: path 147 required: true 148 schema: 149 type: string 150 responses: 151 '200': 152 description: "Success, retured current PLC data" 153 # TODO: basically just an op, but missing some fields? sigh. 154 '404': 155 $ref: '#/components/responses/404DidNotFound' 156 '410': 157 $ref: '#/components/responses/410DidNotAvailable' 158 /export: 159 get: 160 description: "Bulk fetch PLC Operations for all DIDs, with pagination, in JSON Lines format" 161 operationId: Export 162 parameters: 163 - name: count 164 in: query 165 schema: 166 type: integer 167 default: 10 168 maximum: 1000 169 - name: after 170 in: query 171 schema: 172 type: string 173 format: date-time 174 description: "Return only operations after this indexed timestamp" 175 responses: 176 '200': 177 description: "Success, returned batch of operations" 178 content: 179 application/jsonlines: 180 description: "Newline-delimited JSON file, with a separate JSON object on each line" 181 schema: 182 $ref: '#/components/schemas/LogEntry' 183 '400': 184 $ref: '#/components/responses/400BadRequest' 185 186components: 187 responses: 188 404DidNotFound: 189 description: "DID Not Found" 190 content: 191 application/json: 192 schema: 193 type: object 194 properties: 195 message: 196 type: string 197 example: 198 message: "DID not registered: did:plc:ewvi7nxzyoun6zhxrhs64oiz" 199 410DidNotAvailable: 200 description: "DID Not Available (Tombstone)" 201 content: 202 application/json: 203 schema: 204 type: object 205 properties: 206 message: 207 type: string 208 example: 209 message: "DID not available: did:plc:ewvi7nxzyoun6zhxrhs64oiz" 210 400BadOperation: 211 description: "Invalid PLC Operation" 212 content: 213 application/json: 214 schema: 215 type: object 216 properties: 217 message: 218 type: string 219 example: 220 message: "Invalid Signature" 221 400BadRequest: 222 description: "Bad Request" 223 content: 224 application/json: 225 schema: 226 type: object 227 properties: 228 message: 229 type: string 230 example: 231 message: "Invalid Query Parameter" 232 schemas: 233 Operation: 234 oneOf: 235 - $ref: '#/components/schemas/PlcOp' 236 - $ref: '#/components/schemas/TombstoneOp' 237 - $ref: '#/components/schemas/LegacyCreateOp' 238 discriminator: 239 propertyName: type 240 mapping: 241 plc_operation: '#/components/schemas/PlcOp' 242 plc_tombstone: '#/components/schemas/TombstoneOp' 243 create: '#/components/schemas/LegacyCreateOp' 244 PlcOp: 245 type: object 246 description: "Regular PLC operation. Can be a genesis operation (create DID, no 'prev' field), or a data update." 247 required: 248 - type 249 - rotationKeys 250 - verificationMethods 251 - alsoKnownAs 252 - services 253 - prev 254 - sig 255 properties: 256 type: 257 type: string 258 rotationKeys: 259 type: array 260 items: 261 type: string 262 description: "Ordered set (no duplicates) of cryptographic public keys in did:key format" 263 verificationMethods: 264 type: object 265 description: "Map (object) of application-specific cryptographic public keys in did:key format" 266 alsoKnownAs: 267 type: array 268 items: 269 type: string 270 description: "Ordered set (no duplicates) of aliases and names for this account, in the form of URIs" 271 services: 272 type: object 273 description: "Map (object) of application-specific service endpoints for this account" 274 prev: 275 type: string 276 nullable: true 277 description: "Strong reference (hash) of preceeding operation for this DID, in string CID format. Null for genesis operation" 278 sig: 279 type: string 280 description: "Cryptographic signature of this object, with base64 string encoding" 281 example: 282 type: "plc_operation" 283 services: 284 atproto_pds: 285 type: "AtprotoPersonalDataServer" 286 endpoint: "https://bsky.social" 287 alsoKnownAs: 288 - "at://atproto.com" 289 rotationKeys: 290 - "did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg" 291 - "did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK" 292 verificationMethods: 293 atproto: "did:key:zQ3shXjHeiBuRCKmM36cuYnm7YEMzhGnCmCyW92sRJ9pribSF" 294 295 TombstoneOp: 296 type: object 297 description: "Special operation which deactives (revokes) the DID. This is permanent once the recovery window expires." 298 required: 299 - type 300 - prev 301 - sig 302 properties: 303 type: 304 type: string 305 prev: 306 type: string 307 description: "Strong reference (hash) of preceeding operation for this DID, in string CID format" 308 sig: 309 type: string 310 description: "Cryptographic signature of this object, with base64 string encoding" 311 example: 312 type: "plc_tombstone" 313 prev: "bafyreid6awsb6lzc54zxaq2roijyvpbjp5d6mii2xyztn55yli7htyjgqy" 314 sig: "41iJmrPRUTIi24HBduzgoavjOibAx2yFJ2p1d7zTN6ZmMgjSaTF8dJf0HtdU4EBNUBTWq33PZyh5tyb1bJq3Fw" 315 316 LegacyCreateOp: 317 type: object 318 description: "Obsolete PLC genesis operations, which must still be supported to ensure all did:plc identifiers can be resolved correctly." 319 required: 320 - type 321 - signingKey 322 - recoveryKey 323 - handle 324 - service 325 - prev 326 - sig 327 properties: 328 type: 329 type: string 330 signingKey: 331 type: string 332 description: "atproto cryptographic public key in did:key format" 333 recoveryKey: 334 type: string 335 description: "PLC recovery cryptographic public key in did:key format" 336 handle: 337 type: string 338 description: "atproto handle as AT-URI (at://)" 339 service: 340 type: string 341 description: "atproto_pds service endpoint URL" 342 prev: 343 type: string 344 nullable: true 345 description: "Strong reference (hash) of preceeding operation for this DID, in string CID format" 346 sig: 347 type: string 348 description: "Cryptographic signature of this object, with base64 string encoding" 349 example: 350 type: "create" 351 signingKey: "did:key:zQ3shP5TBe1sQfSttXty15FAEHV1DZgcxRZNxvEWnPfLFwLxJ" 352 recoveryKey: "did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg" 353 handle: "first-post.bsky.social" 354 service: "https://bsky.social" 355 prev: null 356 sig: "yvN4nQYWTZTDl9nKSSyC5EC3nsF5g4S56OmRg9G6_-pM6FCItV2U2u14riiMGyHiCD86l6O-1xC5MPwf8vVsRw" 357 358 LogEntry: 359 type: object 360 required: 361 - did 362 - operation 363 - cid 364 - nullified 365 - createdAt 366 properties: 367 did: 368 type: string 369 description: "DID that this operation applies to" 370 operation: 371 $ref: "#/components/schemas/Operation" 372 cid: 373 type: cid 374 description: "Hash of the operation, in string CID format" 375 nullified: 376 type: bool 377 description: "Whether this operation is included in the current operation chain, or has been overridden" 378 createdAt: 379 type: string 380 format: date-time 381 description: "Timestamp when this operation was received by the directory server" 382 example: 383 did: "did:plc:ewvi7nxzyoun6zhxrhs64oiz" 384 operation: 385 sig: "lza4at_jCtGo_TYgL5PC1ZNP7lhF4DV8H50LWHhvdHcB143x1wEwqZ43xvV36Pws6OOnJLJrkibEUFDFqkhIhg" 386 prev: null 387 type: "plc_operation" 388 services: 389 atproto_pds: 390 type: "AtprotoPersonalDataServer" 391 endpoint: "https://bsky.social" 392 alsoKnownAs: 393 - "at://atprotocol.bsky.social" 394 rotationKeys: 395 - "did:key:zQ3shhCGUqDKjStzuDxPkTxN6ujddP4RkEKJJouJGRRkaLGbg" 396 - "did:key:zQ3shpKnbdPx3g3CmPf5cRVTPe1HtSwVn5ish3wSnDPQCbLJK" 397 verificationMethods: 398 atproto: "did:key:zQ3shXjHeiBuRCKmM36cuYnm7YEMzhGnCmCyW92sRJ9pribSF" 399 cid: "bafyreibfvkh3n6odvdpwj54j4xxdsgnn4zo5utbyf7z7nfbyikhtygzjcq" 400 nullified: false 401 createdAt: "2023-04-26T06:19:25.508Z" 402 403 DidDocument: 404 type: object 405 required: 406 - id 407 properties: 408 id: 409 type: string 410 example: "did:plc:ewvi7nxzyoun6zhxrhs64oiz" 411 alsoKnownAs: 412 type: array 413 description: "Ordered set (no duplicates) of aliases and names for this account, in the form of URIs" 414 items: 415 type: string 416 example: "at://atproto.com" 417 verificationMethods: 418 type: array 419 items: 420 type: object 421 required: 422 - id 423 - type 424 - controller 425 - publicKeyMultibase 426 properties: 427 id: 428 type: string 429 type: 430 type: string 431 controller: 432 type: string 433 publicKeyMultibase: 434 type: string 435 example: 436 id: "#atproto" 437 type: "EcdsaSecp256k1VerificationKey2019" 438 controller: "did:plc:ewvi7nxzyoun6zhxrhs64oiz" 439 publicKeyMultibase: "zQYEBzXeuTM9UR3rfvNag6L3RNAs5pQZyYPsomTsgQhsxLdEgCrPTLgFna8yqCnxPpNT7DBk6Ym3dgPKNu86vt9GR" 440 service: 441 type: array 442 items: 443 type: object 444 required: 445 - id 446 - type 447 - serviceEndpoint 448 properties: 449 id: 450 type: string 451 type: 452 type: string 453 serviceEndpoint: 454 type: string 455 example: 456 id: "#atproto_pds" 457 type: "AtprotoPersonalDataServer" 458 serviceEndpoint: "https://bsky.social"