Closed JaceHensley closed 3 years ago
Please provide a json example of what you would like to see.
cc @glcohen
Before:
"input_descriptors": [
{
"id": "banking_input_1",
"name": "Bank Account Information",
"purpose": "We can only remit payment to a currently-valid bank account.",
"group": [
"A"
],
"schema": [
{
"uri": "https://bank-schemas.org/1.0.0/accounts.json"
},
{
"uri": "https://bank-schemas.org/2.0.0/accounts.json"
}
],
"constraints": {
// ...
}
}
]
Afters:
just type
"constraints": {
"fields": [
{
"path": [
"$.type",
"$.vc.type"
],
"purpose": "We need a credential that conforms to a bank account structure",
"filter": {
"type": "array",
"contains": {
"type": "string",
"pattern": "(BankAccountCredentailV1)|(BankAccountCredentailV2)"
}
}
}
]
}
just credentialSchema
"constraints": {
"fields": [
{
"path": [
"$.credentialSchema",
"$.vc.credentialSchema"
],
"purpose": "We need a credential that conforms to a bank account structure",
"filter": {
"type": "array",
"contains": {
"type": "string",
"pattern": "(https://bank-schemas.org/1.0.0/accounts.json)%7C(https://bank-schemas.org/2.0.0/accounts.json)"
}
}
}
]
}
both credentialSchema and type
"constraints": {
"fields": [
{
"path": [
"$.type",
"$.vc.type"
],
"purpose": "We need a credential that conforms to a bank account structure",
"filter": {
"type": "array",
"contains": {
"type": "string",
"pattern": "(BankAccountCredentailV1)|(BankAccountCredentailV2)"
}
}
},
{
"path": [
"$.credentialSchema",
"$.vc.credentialSchema"
],
"purpose": "We need a credential that conforms to a bank account structure",
"filter": {
"type": "array",
"contains": {
"type": "string",
"pattern": "(https://bank-schemas.org/1.0.0/accounts.json)%7C(https://bank-schemas.org/2.0.0/accounts.json)"
}
}
}
]
}
The schema property on Input Descriptors is essentially just a special field constraint and what exactly it refers to is confusing. So instead of having a special field constraint verifiers can explicitly specify the fields they want to filter by (can be the type array or credentialSchema object)
I see what you're saying. There is ambiguity in what exact portion of the credential a given schema, or set of schemas, point to -- it could be just the credentialSubject
, and it could be the entire credential, or any other set of fields. The main thing is to say "this schema applies to this credential in some way" -- the specific way is vague.
I still see value in noting that you're accepting credentials of a schema type. How to process the schema for the credential is kind of a different question.
This kind of opens a can of worms in forcing PE to take a stance on how to process / validate schemas against certain input descriptor's requests. Perhaps a compromise could be to do something like...
"input_descriptors": [
{
"id": "banking_input_1",
"name": "Bank Account Information",
"purpose": "We can only remit payment to a currently-valid bank account.",
"group": [
"A"
],
"schema": [
{
"uri": "https://bank-schemas.org/1.0.0/accounts.json",
"path": ".credentialSubject"
},
{
"uri": "https://bank-schemas.org/2.0.0/accounts.json"
"path": ".credentialSubject"
}
],
"constraints": {
// ...
}
}
]
This would state that a given schema is applied to a specific piece of the expected data. This does have the benefit of reducing verification failures by giving the client more information on what the verifier is expecting.
There is ambiguity in what exact portion of the credential a given schema, or set of schemas, point to -- it could be just the credentialSubject, and it could be the entire credential, or any other set of fields
Right now schema
refers to the type
array (valid LD or not) OR the credentialSchema
property OR some other way of determining the "schema" (in quotes cause it's not just JSON schema)
I still see value in noting that you're accepting credentials of a schema type. How to process the schema for the credential is kind of a different question.
That's true but a verifier can already give the user insight into why something failed/isn't going to be accepted with the purpose
property
something like..
Actually what you are describing here is more what the constraints.fields[]
objects do, the specify a path and then a filter
(JSON schema) for that property
It seems much cleaner, simpler and less ambiguous to simply remove the schema object altogether and to rely on the constraints object to tell the wallet exactly what the verifier is looking for
That's true but a verifier can already give the user insight into why something failed/isn't going to be accepted with the
purpose
property
Purpose is a human readable descriptor. Schema intends to be machine processable, as is done in this library: https://github.com/workdaycredentials/ledger-common/blob/master/credential/presexchange/submission.go#L371
Actually what you are describing here is more what the constraints.fields[] objects do, the specify a path and then a filter (JSON schema) for that property
This is true, though the schema property is not intended to simply be JSON Schemas. It is to be applied before a credential is accepted for processing. Credentials always reference schemas -- whether in an LD type, or using JSON Schema (as per https://w3c-ccg.github.io/vc-json-schemas/v1/index.html).
For example, a digital wallet is able to filter by credentials according to their schema (LD, JSON, or otherwise) and respond to a Presentation Request accordingly. Once the Request is received, it is up to the verifier to (1) assert that the credential matches the shape of that given schema, (2) does any additional validations required.
Purpose is a human readable descriptor. Schema intends to be machine processable, as is done in this library:
why does the machine need to know intent if it know how to process it?
though the schema property is not intended to simply be JSON Schemas
yup and that's why I want to remove it, it's confusing and puts more work on PE implementations. The implementation would have to know where to check the schema
property against (is it in the type
array? is it the credentialSchema.id
property? etc.). If we remove the property then the verifier details exactly where to look for a value, and the PE implementation just looks for that property/value just like every other field constraint because that's all it is.
digital wallet is able to filter by credentials according to their schema (LD, JSON, or otherwise) and respond to a Presentation Request accordingly
the wallet should also be filtering based on the rest of the field constraints before responding with a Presentation Submission
yup and that's why I want to remove it, it's confusing and puts more work on PE implementations
I think your complaint is with the complications of the VC spec, not PE! In that case I agree 😄 . The fact is there are multiple types of schemas that apply to VCs.
the wallet should also be filtering based on the rest of the field constraints before responding with a Presentation Submission
Correct...I think of it as a depth traversal, but the highest node in the tree is the schema. I shouldn't need to check all other properties if the schema doesn't match.
Put differently I see credentials in categorized "buckets" - this is done by schema. After that, you can request specific properties from those credentials.
A schema describes the shape, and properties that you can select for in input descriptors. In PE you are saying given this data shape (schema) I am requesting the following properties (constraints).
I do see what you are saying here, that you can quickly/cheaply check the schema first and know right away if it's valid. But it'd say it'd be pretty similar with just using the field constraints. The field constraints have an AND
relationship so if the first entry in fields
doesn't have it's path
and filter
properties satisfied then you would know that the Claim you are testing won't work. So the verifier could just put their "schema" field constraint first in the list.
In PE you are saying given this data shape (schema) I am requesting the following properties (constraints).
Kinda but only if you enable "limit_disclosure" otherwise what you're saying is: "I want a claim in this shape ("schema") and it must have at least these properties"
limit_disclosure
is simply a tool for reducing data liability for requesters. The fields that are exposed in the constraints are a language made possible by the schema -- which could apply to any part of the credential (subject, whole thing, etc.)
Proposal from today:
schema
to data_model
or some such. The data model provides the language that is accessible for constraints, and also allows another type of validation (e.g. this path must validate against a given JSON schema).data_model
an optional property{
"presentation_definition": {
"id": "32f54163-7166-48f1-93d8-ff217bdb0653",
"input_descriptors": [
{
"id": "ca_vaccination",
"name": "CA State Vaccination Record",
"purpose": "We can only allow vaccinated individuals who have received vaccinations in CA.",
"data_model": [
// each element here is a set of ANDs
{
// path is a set of "ORs"
"path": [
"$.context"
"$.vc.context"
],
// filter is always a regex
"filter": "https://www.w3.org/2018/credentials/v1"
},
{
"path": [
"$.credentialSubject"
"$.vc.credentialSubject"
],
// two possible vaccine json schemas that apply to the credentialSubject property
"filter": "https://w3id.org/vaccination/v1.json|https://w3id.org/vaccination/v2.json"
}
],
"constraints": {
"fields": [
{
"path": [
"$.credentialSubject.name",
"$.vc.credentialSubject.name",
],
"purpose": "Only people named Bob can be allowed in",
"filter": {
"type": "string",
"pattern": "bob"
}
}
]
},
}
]
}
}
Yeah so after our little sync call today I'm more in favor of keeping something like this. It behaves the same as fields
but has different semantic meaning which wallets/verifiers could use to their advantage
fields
In addition to the things you listed one thing I didn't bring up on the call is maybe data_model
should be moved inside constraints
or removing the nested constraints
entirely (https://github.com/decentralized-identity/presentation-exchange/issues/212). Personally I like the nesting but I don't have a strong opinion either way
I like the name data_model
and really like that the verifier can specify where in the credential it is located.
Having it as an optional property also makes sense.
I agree with keeping data_model
at the top level (or moving data_model
inside of constraints
).
(fwiw, I also prefer keeping constraints
nested)
The only thing I'm not sure of is in the example @glcohen gave, it says the filter
property value should always be a regex.
I think it makes more sense to base the definition on the filter
property in the fields
object.
For example:
The `data_model` object MUST contain a filter property, and its value MUST be a JSON Schema descriptor.
Yeah I agree data_model
should be functionally the same as fields
it would just have different semantics
agreed!
I agree with the overall proposal, but would like to see us choose a different name for the prop than data_model
. Perhaps type
or class
?
I also agree with @JaceHensley that this prop, whatever it is called, should be moved into constraints
.
I agree with the overall proposal, but would like to see us choose a different name for the prop than
data_model
. Perhapstype
orclass
?
type sounds fine to me
I'll probably use type
in the PR to add this and if people want it changed we can bikeshed in the PR 🙂
The
schema
property on Input Descriptors is essentially just a special field constraint and what exactly it refers to is confusing. So instead of having a special field constraint verifiers can explicitly specify the fields they want to filter by (can be thetype
array orcredentialSchema
object)