quartzjer / did-jwk

DID JWK Method Spec
Creative Commons Zero v1.0 Universal
7 stars 6 forks source link

resolver extensions #5

Closed OR13 closed 2 years ago

OR13 commented 2 years ago

one hack around did methods like this has been "resolver middleware", or... modifying a did document to contain values other than what the method author intended (for example adding service endpoints or @context or other json values to an existing did document.

It is possible to make did:jwk look like a did web by exploiting the ability to encode arbitrary JSON in the encoded JWK.

For example:

const jwk = {
    kid,
    '@context': options.didDocument['@context'],
    service: options.didDocument.service,
    ...publicKeyJwk,
  };
  const did = `did:jwk:${base64url.encode(JSON.stringify(jwk))}`;

This will then yield a did document that contains nested data which can be pulled up the correct level by "post resolution middleware"....

example:

{
      "keys": [
        {
          "id": "did:key:z6MkpFJxUgQgYKK68fmokaCWwpRYoWdG3LzZR6dLFXvdJvAT#z6MkpFJxUgQgYKK68fmokaCWwpRYoWdG3LzZR6dLFXvdJvAT",
          "controller": "did:key:z6MkpFJxUgQgYKK68fmokaCWwpRYoWdG3LzZR6dLFXvdJvAT",
          "type": "JsonWebKey2020",
          "publicKeyJwk": {
            "kty": "OKP",
            "crv": "Ed25519",
            "x": "kYUxJdxcqoKbfJKjTPEmbifNrDBvuQuoGynhwmr4BSA"
          },
          "privateKeyJwk": {
            "kty": "OKP",
            "crv": "Ed25519",
            "x": "kYUxJdxcqoKbfJKjTPEmbifNrDBvuQuoGynhwmr4BSA",
            "d": "TmG8GRjqakeuMwczG-d5gZahqOfP5Lbo98ml82AX2Sk"
          }
        }
      ],
      "didDocument": {
      // note that a resolver could inject this value
        "@context": [
          "https://www.w3.org/ns/did/v1",
          "https://w3id.org/security/suites/jws-2020/v1"
        ],
        "id": "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ",
        "verificationMethod": [
          {
            "id": "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ",
            "type": "JsonWebKey2020",
            "controller": "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ",
            "publicKeyJwk": {
              "kid": "key-0",
              // note that a resolver could remove this value
              "@context": [
                "https://www.w3.org/ns/did/v1",
                "https://w3id.org/security/suites/jws-2020/v1"
              ],
              // note that a resolver could remove this value
              "service": [
                {
                  "id": "#agent",
                  "serviceEndpoint": "https://api.example.com"
                }
              ],
              "kty": "OKP",
              "crv": "Ed25519",
              "x": "kYUxJdxcqoKbfJKjTPEmbifNrDBvuQuoGynhwmr4BSA"
            }
          }
        ],
        "authentication": [
          "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ"
        ],
        "capabilityInvocation": [
          "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ"
        ],
        "capabilityDelegation": [
          "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ"
        ],
        "keyAgreement": [
          "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ"
        ],
        // note that a resolver could inject this value
        "service": [
          {
            "id": "did:jwk:eyJraWQiOiJrZXktMCIsIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSJdLCJzZXJ2aWNlIjpbeyJpZCI6IiNhZ2VudCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vYXBpLmV4YW1wbGUuY29tIn1dLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6ImtZVXhKZHhjcW9LYmZKS2pUUEVtYmlmTnJEQnZ1UXVvR3luaHdtcjRCU0EifQ#agent",
            "serviceEndpoint": "https://api.example.com"
          }
        ]
      }
    }
OR13 commented 2 years ago

Such middleware seems very necessary to allow for did:jwk to interop with did methods that support JSON-LD or that use DIDComm.

quartzjer commented 2 years ago

What you're describing is definitely interesting, but I would consider that a different method.

If I were to go this way I might consider it being a did:jwt method so that it is also protected and can be updated by using canonicalId to the contained JWK thumbprint. I could even imagine supporting rotation by embedding a JWS attesting to the next key (though it would balloon in size quickly).

OR13 commented 2 years ago

The current spec text does not forbid stuffing JSON in the JWK, should it be:

  1. forbidden?
  2. allowed?
  3. recommended?
  4. required?

Prime examples of things we expect to see in a JWK which would show up in a did document:

kid, use, alg.

given adding JSON to the JWK is the main extension point, I think more guidance on this is required to prevent folks from putting database queries or results in the JWK.

quartzjer commented 2 years ago

Completely agree, I'll work on some language with specific guidance.