Specify signing requests / interface with wallets
Closed this issue · 6 comments
In cases where a DID Registrar interacts with an external wallet (see External Secret Mode) or a client-managed wallet (see Client-Managed Secret Mode), we should specify those interfaces.
Existing work that is related to this:
- Traditional Certificate Signing Requests (CSRs) as used by Let's Encrypt etc.
- Universal Wallet in CCG
- WebKMS in CCG
In the experimental client-managed secret flow with did:sov, the registrar currently returns a signing request like this:
{
"jobId": "12345",
"didState": {
"state": "action",
"action": "signPayload",
"kid": null,
"alg": "EdDsa"
"payload": "6964656e7469666965723a56345347525538365a353864365456375042556536667c6f7065726174696f6e3a646573743a42527850353836484270474850706861517152374d767c747970653a317c7665726b65793a366769704764676f795a4c7745794b66326b61727a634d70316a50487843553236624b4336574a75364a4e6b7c70726f746f636f6c56657273696f6e3a327c72657149643a31363330353032333436323337393433303030",
},
"didRegistrarMetadata": { .. },
"didDocumentMetadata": { .. }
}
I.e. it is asking the client to sign the value in payload
.
But instead of a single payload, maybe multiple named "signing requests" in the form of a map should be supported, e.g.:
{
"jobId": "1234",
"didState": {
"state": "action",
"action": "signPayload",
"signingRequest": {
"signingRequest1": {
"payload": {
...
},
"serializedPayload": "<-multibase->",
"kid": null,
"alg": "EdDsa",
"verificationMethod": "..." // could point to a verificationMethod, incl. VerifiableConditions with threshold, etc.
"proofPurpose": ".." // ??
},
"signingRequest2": {
"payload": "8784566",
"kid": null,
"alg": "ES256K"
}
}
},
"didRegistrationMetadata": {
},
"didDocumentMetadata": { }
}
Additional notes:
- Maybe both a
payload
(in JSON) and a "serializedPayload" (bytes) should be included, so that the payload can be displayed to a human before signing; could be necessary for legal reasons, i.e. you can only sign what you understand - Maybe
verificationMethod
and/orproofPurpose
could be re-used in such signing requests
This way, the next request would include a set of signing results matching the signing requests, e.g.:
{
"jobId": "1234",
"options": {
"network": "danube", // not really needed because of jobId
"clientSecretMode": true, // not really needed because of jobId
"signingResult": {
"signingRequest1": "<-multibase->",
"signingRequest2": "<-multibase->"
}
},
"secret": { },
"didDocument": { }
}
Additional notes:
- Since
network
andclientSecretMode
were already included in the first request, they can now be remembered as part of thejobId
and don't have to be included again.
Signing requests could include an optional timeout that tells the client how long the driver will wait for the signature.
Just a thought on this, what if we built around the WebCrypto Sign API in order to make this work? This would enable the ability to implement these features within the browser as a standard API while also using a standardized interface that could be wrapped around things like propritary KMS services or utilize implementations that are made for like node.js.
Great idea @kdenhartog , I thought only about Universal Wallet and WebKMS, but not WebCrypto API. I just added a quick commit to mention that too in a number of places: 71a5f17
Great idea @kdenhartog , I thought only about Universal Wallet and WebKMS, but not WebCrypto API. I just added a quick commit to mention that too in a number of places: 71a5f17
The referenced commit looks good to me
I think the specification now sufficiently describes how signing requests and responses work:
- https://identity.foundation/did-registration/#signing-request-set
- https://identity.foundation/did-registration/#signing-response-set
Also, the section on "external secret mode" has been expanded a bit to explain the possible interface with wallets, including Universal Wallet, WebKMS, WebCrypto API:
So I'm closing this issue.