openwallet-foundation / acapy

ACA-Py is a foundation for building decentralized identity applications and services running in non-mobile environments.
https://aca-py.org
Apache License 2.0
419 stars 511 forks source link

Question on having oneOf schema in a presentation request (or credential offer request) #1609

Closed stevendonline closed 2 years ago

stevendonline commented 2 years ago

If a Verifier can accept multiple Credentials with different schemas, is it possible to create an invitation with a presentation request that allows multiple schemas? Looking at the "presentation_request.dif.presentation_definition.input_describtors.schema" which accepts a "oneOf", I am wondering what the sematic of this is? Is there any reference material I can look for? Does that mean I can provide an array of schemas, so the Holder can choose one of them to present? I tried with

{
    "oneof_filter": [
        [{
                "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
            }, {
                "uri": "https://w3id.org/citizenship/v1"
            }
        ],
        [{
                "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
            }, {
                "uri": "https://ohstatic.azurewebsites.net/ohdi-vocab/contexts#OntarioHealthDigitalIdentifier"
            }
        ]
    ]
}

The Holder accepts the invitation but sends a presentation response without any presentation like below, see the "verifiableCredential": [], in the payload:

{
    "state": "presentation-received",
    "thread_id": "3201b870-3d0d-46ac-b24b-acfe84e56059",
    "pres_request": {
      "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/2.0/request-presentation",
      "@id": "3201b870-3d0d-46ac-b24b-acfe84e56059",
      "will_confirm": true,
      "comment": "POST ​/present-proof-2.0​/create-request Creates a presentation request not bound to any proposal or connection",
      "formats": [
        {
          "attach_id": "dif",
          "format": "dif/presentation-exchange/definitions@v1.0"
        }
      ],
      "request_presentations~attach": [
        {
          "@id": "dif",
          "mime-type": "application/json",
          "data": {
            "json": {
              "presentation_definition": {
                "id": "32f54163-7166-48f1-93d8-ff217bdb0655",
                "format": {
                  "ldp_vp": {
                    "proof_type": [
                      "BbsBlsSignature2020"
                    ]
                  }
                },
                "input_descriptors": [
                  {
                    "id": "id20220124-bbs+-2",
                    "name": "reverse HCN, or Drivers License?",
                    "schema": {
                      "oneof_filter": [
                        [
                          {
                            "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
                          },
                          {
                            "uri": "https://w3id.org/citizenship/v1"
                          }
                        ],
                        [
                          {
                            "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
                          },
                          {
                            "uri": "https://ohstatic.azurewebsites.net/ohdi-vocab/contexts#OntarioHealthDigitalIdentifier"
                          }
                        ]
                      ]
                    },
                    "constraints": {
                      "is_holder": [
                        {
                          "directive": "required",
                          "field_id": [
                            "1f44d55f-f161-4938-a659-f8026467f126"
                          ]
                        }
                      ],
                      "fields": [
                        {
                          "id": "1f44d55f-f161-4938-a659-f8026467f126",
                          "path": [
                            "$.credentialSubject.identifier"
                          ],
                          "purpose": "The claim must be from one of the specified issuers"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    },
    "pres": {
      "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/2.0/presentation",
      "@id": "53f5ad94-769f-48d2-8c26-1d9768fcb67b",
      "~thread": {
        "thid": "3201b870-3d0d-46ac-b24b-acfe84e56059"
      },
      "comment": "auto-presented for proof requests, pres_ex_record: 50e87217-79ce-4655-bee9-f2f6517f8b64",
      "presentations~attach": [
        {
          "@id": "dif",
          "mime-type": "application/json",
          "data": {
            "json": {
              "@context": [
                "https://www.w3.org/2018/credentials/v1",
                "https://w3id.org/security/bbs/v1"
              ],
              "type": [
                "VerifiablePresentation"
              ],
              "verifiableCredential": [],
              "presentation_submission": {
                "id": "1c2e9775-699a-418d-b357-fb71ac6e1a09",
                "definition_id": "32f54163-7166-48f1-93d8-ff217bdb0655",
                "descriptor_map": []
              }
            }
          }
        }
      ],
      "formats": [
        {
          "attach_id": "dif",
          "format": "dif/presentation-exchange/submission@v1.0"
        }
      ]
    },
    "role": "verifier",
    "initiator": "self",
    "pres_ex_id": "9a15901b-8c08-47b7-983b-6e969e54ceb0",
    "by_format": {
      "pres_request": {
        "dif": {
          "presentation_definition": {
            "id": "32f54163-7166-48f1-93d8-ff217bdb0655",
            "format": {
              "ldp_vp": {
                "proof_type": [
                  "BbsBlsSignature2020"
                ]
              }
            },
            "input_descriptors": [
              {
                "id": "id20220124-bbs+-2",
                "name": "reverse HCN, or Drivers License?",
                "schema": {
                  "oneof_filter": [
                    [
                      {
                        "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
                      },
                      {
                        "uri": "https://w3id.org/citizenship/v1"
                      }
                    ],
                    [
                      {
                        "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
                      },
                      {
                        "uri": "https://ohstatic.azurewebsites.net/ohdi-vocab/contexts#OntarioHealthDigitalIdentifier"
                      }
                    ]
                  ]
                },
                "constraints": {
                  "is_holder": [
                    {
                      "directive": "required",
                      "field_id": [
                        "1f44d55f-f161-4938-a659-f8026467f126"
                      ]
                    }
                  ],
                  "fields": [
                    {
                      "id": "1f44d55f-f161-4938-a659-f8026467f126",
                      "path": [
                        "$.credentialSubject.identifier"
                      ],
                      "purpose": "The claim must be from one of the specified issuers"
                    }
                  ]
                }
              }
            ]
          }
        }
      },
      "pres": {
        "dif": {
          "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://w3id.org/security/bbs/v1"
          ],
          "type": [
            "VerifiablePresentation"
          ],
          "verifiableCredential": [],
          "presentation_submission": {
            "id": "1c2e9775-699a-418d-b357-fb71ac6e1a09",
            "definition_id": "32f54163-7166-48f1-93d8-ff217bdb0655",
            "descriptor_map": []
          }
        }
      }
    },
    "auto_present": false,
    "created_at": "2022-01-24T16:12:03.01247Z",
    "trace": false,
    "updated_at": "2022-01-24T16:13:44.848344Z"
  }
swcurran commented 2 years ago

In AnonCreds that functionality is supported via the restrictions. on name or names.

I'm not sure about the DIF PE support, which is what you seems to be interested in. I think you should check the DIF PE spec. to see if it is supported and how. I'm not an expert on this, but AFAIK, if you can express it in a DIF PE request, then it should work in the ACA-Py implementation because ACA-Py (more or less) just accepts a DIF PE request from the controller and puts into the request-presentation message.

stevendonline commented 2 years ago

@swcurran Thanks, I will take a look at DIF PE in detail. Some more details are below, just leave it here and hope someone can get an answer. I use the command lines below to setup: *Issuer

PORTS="8000:8000 11000:11000" ./scripts/run_docker start --label "My Issuer" --inbound-transport http 0.0.0.0 8000 --outbound-transport http --admin 0.0.0.0 11000 --admin-insecure-mode --genesis-url http://test.bcovrin.vonx.io/genesis --seed OHIssuer000000000000000000000000 --wallet-type indy --wallet-name MyIssuer1 --wallet-key MyIssuerSecuret --endpoint http://host.docker.internal:8000/ --webhook-url https://acapygatewayfunc.azurewebsites.net/webhooks --public-invites --auto-provision --monitor-ping 

*Holder

PORTS="8200:8200 12000:12000" ./scripts/run_docker start --label "My Holder" --inbound-transport http 0.0.0.0 8200 --outbound-transport http --admin 0.0.0.0 12000 --admin-insecure-mode --genesis-url http://test.bcovrin.vonx.io/genesis --seed OHHolder000000000000000000000000 --wallet-type indy --wallet-name MyHolder1 --wallet-key MyHolderSecuret --endpoint http://host.docker.internal:8200/ --auto-provision --auto-accept-invites --auto-accept-requests --auto-respond-messages --auto-respond-credential-offer --auto-respond-presentation-request --auto-store-credential --auto-verify-presentation --monitor-ping

I didn't find direct mention of using 'oneOf' on schema, but did see DIF PE using 'oneOf' on "submission_requirements" and "field". I mainly reference info at: image Instead of 'oneof_filter' above, I also went on tied:

"schema": {
    "oneOf": [
        [{
                "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
            }, {
                "uri": "https://w3id.org/citizenship/v1"
            }
        ],
        [{
                "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
            }, {
                "uri": "https://ohstatic.azurewebsites.net/ohdi-vocab/contexts#OntarioHealthDigitalIdentifier"
            }
        ]
    ]
}

This time, the Holder throws error:

2022-01-30 20:53:20,475 aries_cloudagent.protocols.present_proof.v2_0.formats.dif.handler ERROR 'NoneType' object is not subscriptable
2022-01-30 20:53:20,874 aries_cloudagent.core.dispatcher ERROR Handler error: invitation_receive
Traceback (most recent call last):
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/routes.py", line 226, in invitation_receive
    mediation_id=mediation_id,
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/manager.py", line 602, in receive_invitation
    trace=(invitation._trace is not None),
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/manager.py", line 785, in _process_pres_request_v2
    f"auto-presented for proof requests"
  File "/home/indy/aries_cloudagent/protocols/present_proof/v2_0/manager.py", line 270, in create_pres
    "Unable to create presentation. ProblemReport message sent"
aries_cloudagent.protocols.present_proof.v2_0.manager.V20PresManagerError: Unable to create presentation. ProblemReport message sent
2022-01-30 20:53:21,277 aries_cloudagent.admin.server ERROR Handler error with exception: Unable to create presentation. ProblemReport message sent

=================
Traceback (most recent call last):
  File "/home/indy/aries_cloudagent/admin/server.py", line 163, in ready_middleware
    return await handler(request)
  File "/home/indy/aries_cloudagent/admin/server.py", line 200, in debug_middleware
    return await handler(request)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aiohttp_apispec/middlewares.py", line 45, in validation_middleware
    return await handler(request)
  File "/home/indy/aries_cloudagent/admin/server.py", line 383, in setup_context
    return await task
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/routes.py", line 226, in invitation_receive
    mediation_id=mediation_id,
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/manager.py", line 602, in receive_invitation
    trace=(invitation._trace is not None),
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/manager.py", line 785, in _process_pres_request_v2
    f"auto-presented for proof requests"
  File "/home/indy/aries_cloudagent/protocols/present_proof/v2_0/manager.py", line 270, in create_pres
    "Unable to create presentation. ProblemReport message sent"
aries_cloudagent.protocols.present_proof.v2_0.manager.V20PresManagerError: Unable to create presentation. ProblemReport message sent
2022-01-30 20:53:21,706 aiohttp.server ERROR Error handling request
Traceback (most recent call last):
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 422, in _handle_request
    resp = await self._request_handler(request)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aiohttp/web_app.py", line 499, in _handle
    resp = await handler(request)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aiohttp/web_middlewares.py", line 119, in impl
    return await handler(request)
  File "/home/indy/aries_cloudagent/admin/server.py", line 163, in ready_middleware
    return await handler(request)
  File "/home/indy/aries_cloudagent/admin/server.py", line 200, in debug_middleware
    return await handler(request)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aiohttp_apispec/middlewares.py", line 45, in validation_middleware
    return await handler(request)
  File "/home/indy/aries_cloudagent/admin/server.py", line 383, in setup_context
    return await task
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/routes.py", line 226, in invitation_receive
    mediation_id=mediation_id,
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/manager.py", line 602, in receive_invitation
    trace=(invitation._trace is not None),
  File "/home/indy/aries_cloudagent/protocols/out_of_band/v1_0/manager.py", line 785, in _process_pres_request_v2
    f"auto-presented for proof requests"
  File "/home/indy/aries_cloudagent/protocols/present_proof/v2_0/manager.py", line 270, in create_pres
    "Unable to create presentation. ProblemReport message sent"
aries_cloudagent.protocols.present_proof.v2_0.manager.V20PresManagerError: Unable to create presentation. ProblemReport message sent

The "problem_report/" event is recieved on the Issuer side as below:

{
    "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/problem-report",
    "@id": "90afacf3-edb0-4251-b1cb-467515c603fd",
    "~thread": {
        "thid": "943f280c-cfcf-4fae-b5ac-81eda6a879fa"
    },
    "description": {
        "en": "Presentation request not properly formatted, TypeError raised on Holder agent.",
        "code": "abandoned"
    }
}

What puzzles me is that I am using ACA-Py for both the Issuer and the Holder (the holder is set up to auto-accept all and auto-respond all). if the schema validation is successful (either using 'oneof_filter' or 'oneOf') and the presentation request is generated by the Issuer, why the Holder complains about the format :'(.

shaangill025 commented 2 years ago
"schema": {
    "oneof_filter": [
        [
            {
                "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
            },
            {
                "uri": ".....A...."
            }
        ],
        [
            {
                "uri": "https://www.w3.org/2018/credentials#VerifiableCredential"
            },
            {
                "uri": ".....B......"
            }
        ]
    ]
}

This means all credentials that match one of the schemas will be passed to pres_exch_handler for further processing around the requirement and constraint. With auto flags, all credentials of expanded_type A and B will be included in the presentation. Without auto flags, holder has the ability to decide which one to use, by using the record_id /present-proof-2.0/records/{pres_ex_id}/send-presentation

  "record_ids": {
      "input_desc_id": [ "credential_id" ]
    }

credential_id can be retrieved from /present-proof-2.0/records/{pres_ex_id}/credentials

shaangill025 commented 2 years ago

With presentation requests containing the following, make sure that the credentials that you are expecting to be included are also the same type.

"format": {
  "ldp_vp": {
    "proof_type": [
      "BbsBlsSignature2020"
    ]
  }
}