Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIF Presentation Issue: Credential Not Identified Despite Matching Schema Context #3441

Open
Sshovon opened this issue Jan 13, 2025 · 7 comments

Comments

@Sshovon
Copy link

Sshovon commented Jan 13, 2025

I am using acapy-v1.2.0 and issuing a json-ld credential. Following is the payload for credential issuance.

{
  "connection_id": "8d6571c3-f738-458a-a57b-0c45ef8e3050",
  "comment": "",
  "auto_remove": false,
  "filter": {
    "ld_proof": {
      "credential": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld"
        ],
        "type": [
          "VerifiableCredential",
          "Person"
        ],
        "issuer": "did:key:z6MkoNaEEqvz3k1RmVbxbnN5vxjuXrf9bv6UHbwdwWYW2e6L",
        "issuanceDate": "2025-01-13T18:37:13.298Z",
        "credentialSubject": {
          "birthDate": "1958-07-17",
          "familyName": "SMITH",
          "gender": "female",
          "givenName": "ALICE",
          "type": [
            "Person"
          ]
        }
      },
      "options": {
        "proofType": "Ed25519Signature2018"
      }
    }
  }
}

If I call /credentials/w3c/, I get following output for the received credential.

{
  "results": [
    {
      "contexts": [
        "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld",
        "https://www.w3.org/2018/credentials/v1"
      ],
      "expanded_types": [
        "https://www.w3.org/2018/credentials#VerifiableCredential",
        "https://schema.org/Person"
      ],
      "schema_ids": [],
      "issuer_id": "did:key:z6MkoNaEEqvz3k1RmVbxbnN5vxjuXrf9bv6UHbwdwWYW2e6L",
      "subject_ids": [
        "did:key:z6Mknu7uS59C94C1zHq5mnWhpCfZcfZGEFmPsWFYYQMrWH6g"
      ],
      "proof_types": [
        "Ed25519Signature2018"
      ],
      "cred_value": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld"
        ],
        "type": [
          "VerifiableCredential",
          "Person"
        ],
        "issuer": "did:key:z6MkoNaEEqvz3k1RmVbxbnN5vxjuXrf9bv6UHbwdwWYW2e6L",
        "issuanceDate": "2025-01-13T18:37:13.298Z",
        "credentialSubject": {
          "birthDate": "1958-07-17",
          "familyName": "SMITH",
          "gender": "female",
          "givenName": "ALICE",
          "type": [
            "Person"
          ],
          "id": "did:key:z6Mknu7uS59C94C1zHq5mnWhpCfZcfZGEFmPsWFYYQMrWH6g"
        },
        "proof": {
          "type": "Ed25519Signature2018",
          "proofPurpose": "assertionMethod",
          "verificationMethod": "did:key:z6MkoNaEEqvz3k1RmVbxbnN5vxjuXrf9bv6UHbwdwWYW2e6L#z6MkoNaEEqvz3k1RmVbxbnN5vxjuXrf9bv6UHbwdwWYW2e6L",
          "created": "2025-01-13T18:37:37+00:00",
          "jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..ElIQ--tE7WFWTN-8zRvWqi6v2vSJ37zVcg3xYLtxRUZWnY8-ZSjUXEKHb1YVkUwUQ38s7_euD5q58RxBTNkhCg"
        }
      },
      "cred_tags": {},
      "record_id": "1683a4095dd842669e65dfe10eb31bcd"
    }
    
  ]
}

Now I want to verify this credential. To do so from verifier I send a proof request using following payload.

{
  "connection_id": "8d6571c3-f738-458a-a57b-0c45ef8e3050",
  "presentation_request": {
    "dif": {
      "options": {
        "challenge": "4af538f3-26ed-4064-90f6-78ef150b778d",
        "domain": "wEYJDTwvop1G"
      },
      "presentation_definition": {
        "id": "ceb9b176-dd1c-4f51-9e76-fe386f4fc72c",
        "name": "proof-request",
        "purpose": "authentication",
        "input_descriptors": [
          {
            "id": "5ca22614-2931-4234-8841-11f8141e4c43",
            "name": "proof-request",
            "schema": [
              {
                "uri": "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld"
              }
            ],
            "constraints": {
              "fields": [
                {
                  "path": [
                    "$.credentialSubject.familyName"
                  ],
                  "purpose": "authentication"
                }
              ]
            }
          }
        ]
      }
    }
  }
}

But when I run /present-proof-2.0/records/{pres_ex_id}/credentials on holder it is not able to find the credential for presentation.
But if I change the schema uri to https://schema.org/Person (which is technically the @id of Person in https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld and also present in the expanded_type in w3c credential record) then it is able to find the credential for presentation. . I am a little bit confused here..shouldn't the schema uri be as same as the one used in context during issuance ? Please let me know if I am missing out something.

@swcurran
Copy link
Contributor

@PatStLouis @dbluhm — can either of you help here?

@Sshovon
Copy link
Author

Sshovon commented Jan 13, 2025

@

def credential_match_schema(self, credential: VCRecord, schema_id: str) -> bool:

here in this function, it's trying to find the id in expanded_types.
adding a find in context might help..

@dbluhm
Copy link
Contributor

dbluhm commented Jan 13, 2025

Try adding #Person onto the end of the uri in the presentation definition:

            "schema": [
              {
                "uri": "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld#Person"
              }
            ]

I haven't questioned this or looked deeply into it but I've discovered that, in order to request a presentation with a schema uri, the implementation expects the type to be on the end of the uri as a fragment. As another example, to match the root VerifiableCredential type, you have to use the following URI:

https://www.w3.org/2018/credentials#VerifiableCredential

@Sshovon
Copy link
Author

Sshovon commented Jan 13, 2025

@dbluhm, You are absolutely correct about the root one. But the other one doesn't work if I add #Person. This is the payload.

{
  "created_at": "2025-01-13T21:19:27.466103Z",
  "state": "request-received",
  "proof_id": "c042b929-39e9-492d-9a01-6bc9e29cbffa",
  "connection_id": "2e3dbe84-2c6a-4e8a-aced-ae0f04dd1788",
  "presentation_request": {
    "json": {
      "options": {
        "challenge": "c5494c67-3c3d-44a6-92fc-f2d4110640e4",
        "domain": "Zr22cEpmHfrG"
      },
      "presentation_definition": {
        "id": "d395e550-4fa2-4ea1-9475-7a56c0acecc7",
        "name": "proof-request",
        "purpose": "authentication",
        "input_descriptors": [
          {
            "id": "26951b81-055b-4d9e-a023-58e230d574ca",
            "name": "proof-request",
            "schema": [
              {
                "uri": "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld#Person"
              }
            ],
            "constraints": {
              "fields": [
                {
                  "path": [
                    "$.credentialSubject.familyName"
                  ],
                  "purpose": "authentication"
                }
              ]
            }
          }
        ]
      }
    }
  }
}

I can give you another example.. If I try to issue similar credential with context https://w3id.org/citizenship/v1 and and type PermanentResident then /present-proof-2.0/record/id/credential returns me credentials for presentation if i use https://w3id.org/citizenship#PermanentResident as schema uri. In both cases, if we observe the context and expanded_types values then we can see some similarities. That contexts are somehow resolved into the values that is being stored in the expanded_types. Even for the root , https://www.w3.org/2018/credentials/v1 is being stored as https://www.w3.org/2018/credentials#VerifiableCredential
For the latest issuance,

"contexts": [
        "https://www.w3.org/2018/credentials/v1",
        "https://w3id.org/citizenship/v1"
      ],
  "expanded_types": [
    "https://w3id.org/citizenship#PermanentResident",
    "https://www.w3.org/2018/credentials#VerifiableCredential"
],

And this is for the initial issuance,

"contexts": [
        "https://www.w3.org/2018/credentials/v1",
        "https://w3c-ccg.github.io/citizenship-vocab/contexts/citizenship-v2.jsonld"
      ],
"expanded_types": [
  "https://www.w3.org/2018/credentials#VerifiableCredential",
  "https://schema.org/Person"
],

If I am not wrong then it seems schema uri directly trying to match the stored value in the expanded_types.

Example issuance payload,

{
  "connection_id": "a5014870-ae94-4ffe-bded-39fe682a4d31",
  "comment": "",
  "auto_remove": false,
  "filter": {
    "ld_proof": {
      "credential": {
        "@context": [
          "https://www.w3.org/2018/credentials/v1",
          "https://w3id.org/citizenship/v1"
        ],
        "type": [
          "VerifiableCredential",
          "PermanentResident"
        ],
        "issuer": "did:key:z6Mkj2Fu8R8UsT4FDzgeSR1wAMGKHMVLWbBf7P5CXLwmSj3y",
        "issuanceDate": "2025-01-13T21:24:19.444Z",
        "credentialSubject": {
          "givenName": "ALICE",
          "familyName": "SMITH",
          "gender": "Female",
          "birthCountry": "Bahamas",
          "birthDate": "1958-07-17",
          "type": [
            "PermanentResident"
          ]
        }
      },
      "options": {
        "proofType": "Ed25519Signature2018"
      }
    }
  }
}

Example verification payload,

{
  "connection_id": "a5014870-ae94-4ffe-bded-39fe682a4d31",
  "presentation_request": {
    "dif": {
      "options": {
        "challenge": "205cd470-ab7b-44b6-966b-eba94667a3f0",
        "domain": "7ZzrrXpzarXP"
      },
      "presentation_definition": {
        "id": "45b4806d-1cd4-4509-b230-8520459dfbfe",
        "name": "proof-request",
        "purpose": "authentication",
        "input_descriptors": [
          {
            "id": "fe8b17b1-7605-4d01-ac52-26ffe9d0111b",
            "name": "proof-request",
            "schema": [
              {
                "uri": "https://w3id.org/citizenship#PermanentResident"
              }
            ],
            "constraints": {
              "fields": [
                {
                  "path": [
                    "$.credentialSubject.familyName"
                  ],
                  "purpose": "authentication"
                }
              ]
            }
          }
        ]
      }
    }
  }
}

@dbluhm
Copy link
Contributor

dbluhm commented Jan 14, 2025

I did some exploration with your examples and have recreated the scenario you described. ACA-Py is indeed "expanding" the type of the credential and using the @id from the json-ld context for the type as the expanded_type. Not being the original implementer of this bit of ACA-Py, I can't speak to the motivations of that exact approach. At the same time, it seems a fair choice.

I think what we're seeing is a result of the Presentation Exchange Spec not having precise text for using presentation definitions to request JSON-LD based credentials. The schema[].uri, at least from the examples in the spec, seems to be intended for pointing to a JSON Schema uri, but the description of the attribute does not specify exactly what is expected. In later versions of the PEx spec, the schema[].uri input descriptor value is replaced by just a field descriptor for a credentialSchema.id with an exact match to a schema uri:

...
           "fields": [
            {
              "path": ["$.credentialSchema.id", "$.vc.credentialSchema.id"],
              "filter": {
                "type": "string",
                "const": "hub://did:foo:123/Collections/schema.us.gov/passport.json"
              }
            },
...

So I agree that this seems an odd process but it seems a technically valid way to use the PEx 1.0 spec with JSON-LD credentials. Notably, this is the way agents ACA-Py interops with (e.g. Credo) expect to have JSON-LD credentials requested so it aligns with how this is conventionally used. Modifying this behavior would constitute a breaking change that would extend beyond the sphere of ACA-Py.

@dbluhm
Copy link
Contributor

dbluhm commented Jan 14, 2025

I'm curious if @PatStLouis has any additional insights

@Sshovon
Copy link
Author

Sshovon commented Jan 14, 2025

Thanks a lot for the brief explanation @dbluhm .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants