Skip to content

Proposal for new query language #178

@danielfett

Description

@danielfett

Related to #160, #161, #162 and #157.

This is a proposal for a new query language fulfilling the requirements discussed in the issues linked above. I can create a PR once we are sure that this is the direction we want to go.

Note: This proposal for now does not cover restricting/querying values of claims. See examples 6 and 7 here for a proposal, but that is out of scope for this issue.

Example 1a - Request one Credential (SD-JWT VC)

Just one credential is requested. It must contain the claims last_name, first_name, and address/street_address.

{
  "credentials": {
    "my_cred_1": {
      "format": "vc+sd-jwt",
      "vc+sd-jwt": {  # format-specific requirements
          "vct": "https://credentials.example.com/identity_credential",
          "alg_values": ["ES256", "ES384"],
          "hash_alg_values": ["SHA-256"]
      },
      "claims":[
        { "path": ["last_name"] },
        {
          "path": ["first_name"],
          "intent_to_retain": false  # might be defined as an add-on, not in this PR
        },
        {  "path": ["address", "street_address"]  }
      ]
    }
  }
}

Note the identifier my_cred_1. It will show up in the VP Token, which is restructured to be an object mapping the identifiers in the request to the presentation (string or object depending on a credential format):

vp_token={
    "my_cred_1": "eY..."
}

Example 1b - Request one Credential (mdoc)

The syntax for the claims is slightly different due to the structure of mdocs:

{
  "credentials": {
  {
     "my_mdoc_credential": {
        "format": "mso_mdoc",
        "mso_mdoc": {  # format-specific requirements
            "doctype": "org.iso.7367.1.mVR",
            "alg_values": [ "EdDSA" ],
            "hash_algorithm_values": [ "SHA-384" ],
        },
        "claims": [
          {
            "namespace": "org.iso.7367.1",
            "claim_name": "vehicle_holder",
            "intent_to_retain": false
          },
          {
            "namespace": "org.iso.18013.5.1",
            "claim_name": "first_name",
            "intent_to_retain": false
          }      
        ]
      }
    }
  }
}

Response:

vp_token={
    "my_mdoc_credential": "<mdoc string>"
}

Example 2 - Request multiple Credentials (all of the requested credentials needs to be returned)

All three credentials have to be delivered:

{
  "credentials": {
    "my_cred_1": {
      "format": "vc+sd-jwt",
      "vc+sd-jwt": {
          "vct": "https://credentials.example.com/identity_credential",
          "alg_values": ["ES256", "ES384"],
          "hash_alg_values": ["SHA-256"]
      },
      "purpose": "give me the credential",  # we might pull this to the top
      "claims":[
        { "path": ["last_name"] }
      ]
    },
    "my_cred_2": {
      "format": "vc+sd-jwt",
      "vc+sd-jwt": {
          "vct": "https://credentials.example.com/identity_credential/2",
          "alg_values": ["ES256", "ES384"],
          "hash_alg_values": ["SHA-256"]
      },
      "claims": [
          { "path": ["addresses"] }
      ]
    },
    "my_cred_3": {
      "format": "vc+sd-jwt",
      "vc+sd-jwt": {
          "vct": "https://credentials.example.com/identity_credential/3",
          "alg_values": ["ES256", "ES384"],
          "hash_alg_values": ["SHA-256"]
      },
      "claims": [
        { "path": ["addresses"] }
      ]
    }
  }
}

All three credentials will show up in the VP Token:

vp_token={
    "my_cred_1": "eY...",
    "my_cred_2": "eY...",
    "my_cred_3": "eY..."
}

Note: If there is a requirement on sending multiple credentials fulfilling one request, this should be turned into an array.

Example 3 - Request alternative claims (one rule)

Require age_over_18 or birth_date or age_birth_year by grouping them in an object with the properties require and from. The order of the claims in the from list implies a preference by the verifier.

{
  "credentials": {
    "my_cred_1": {
      "format": "vc+sd-jwt",
      "vc+sd-jwt": {
          "vct": "https://credentials.example.com/identity_credential",
          "alg_values": ["ES256", "ES384"],
          "hash_alg_values": ["SHA-256"]
      },
      "purpose": "give me the credential",
      "claims":[
        { "path": ["last_name"] },
        {
          "required": 1,
          "from": [
            { "path": ["age_over_18"] },
            { "path": ["birth_date"]  },
            { "path": ["age_birth_year"] }
          ]
        },
      ]
    }
  }
}

Note: the expectation is for the wallet to check which of the alternative claims are present and render a user screen based on that - not for the wallet to display to the user all alternative claims (age_over_18 or birth_date or age_birth_year in this case).

Example 4 - Request alternative claims (multiple rules)

By nesting groups, complex queries can be expressed; here, either "zip_code" or both "city" and "state" are required.

{
  "credentials": {
    "my_cred_1": {
      "format": "vc+sd-jwt",
      "vc+sd-jwt": {
          "vct": "https://credentials.example.com/identity_credential",
          "alg_values": ["ES256", "ES384"],
          "hash_alg_values": ["SHA-256"]
      },
      "purpose": "give me the credential",
      "claims":[
        { "path": ["last_name"] }, 
        { 
          "required": 1, 
          "from": [ 
            { "path": [ "zip_code" ] }, 
            {
              "required": 2,
              "from": [
                { "path": [ "city" ] },
                { "path": [ "state" ] }
              ]
            }
          ] 
        } 
      ]
    }
  }
}

Example 5 - Credentials Alternatives

The same logic to requesting alternative claims can be applied to requesting alternative credentials as well. The "rules" for credentials are separated from the credentials to make the processing easier and the syntax more clean. The following example requests "mycred_1" and either "my_cred_2" or "my_cred_3":

{
  "rules": {
    "required": 2,
    "from": [
      { "ref": "my_cred_1" },
      {
        "required": 1,
        "from": [
          { "ref": "my_cred_2" },
          { "ref": "my_cred_3" }
        ]
      }
    ]
  },
  "credentials": { # each object follows the syntax described above
    "my_cred_1": {...}, 
    "my_cred_2": {...},
    "my_cred_3": {...}
  }
}

As shown in the examples further up, if rules is omitted, all credentials have to be delivered.

If the verifier just wants the user's claim (like street address/age), it would express it as "give me one of these credentials and outline any number of credentials whose schema includes a desired claim" - the verifier still needs to specify the format/type of the credential to indicate what it can understand.

Only the available/selected credential will show up in the VP Token:

vp_token={
    "my_cred_1": "eY..."
    "my_cred_2": "eY..."
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions