Skip to content

Update the formal vocabulary files #920

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

Merged
merged 12 commits into from
Sep 3, 2022
Merged
3 changes: 3 additions & 0 deletions vocab/credentials/v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Updating vocabulary

Vocabulary definitions are managed in `vocab.csv`. Add or change entries within this file. Regenerate `credentials.ttl`, `credentials.jsonld`, and `credentials.html` by running `mk_vocab.rb`.
463 changes: 463 additions & 0 deletions vocab/credentials/v2/credentials.html

Large diffs are not rendered by default.

382 changes: 382 additions & 0 deletions vocab/credentials/v2/credentials.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,382 @@
{
"@context": [
"https://w3id.org/security/v2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm... prefer to not do this... this will trigger an entire 2 other network requests, since v2 relies on v1... thats 3 network requests to load the complete v2 context...

Copy link
Contributor

@OR13 OR13 Aug 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be avoided by simply copying the terms required by the vc data model... instead of copying everything...for example:

{
  "@context": [{
    "@version": 1.1
  }, "https://w3id.org/security/v1", {
    "AesKeyWrappingKey2019": "sec:AesKeyWrappingKey2019",
    "DeleteKeyOperation": "sec:DeleteKeyOperation",
    "DeriveSecretOperation": "sec:DeriveSecretOperation",
    "EcdsaSecp256k1Signature2019": "sec:EcdsaSecp256k1Signature2019",
    "EcdsaSecp256r1Signature2019": "sec:EcdsaSecp256r1Signature2019",
    "EcdsaSecp256k1VerificationKey2019": "sec:EcdsaSecp256k1VerificationKey2019",
    "EcdsaSecp256r1VerificationKey2019": "sec:EcdsaSecp256r1VerificationKey2019",
    "Ed25519Signature2018": "sec:Ed25519Signature2018",
    "Ed25519VerificationKey2018": "sec:Ed25519VerificationKey2018",
    "EquihashProof2018": "sec:EquihashProof2018",
    "ExportKeyOperation": "sec:ExportKeyOperation",
    "GenerateKeyOperation": "sec:GenerateKeyOperation",
    "KmsOperation": "sec:KmsOperation",
    "RevokeKeyOperation": "sec:RevokeKeyOperation",
    "RsaSignature2018": "sec:RsaSignature2018",
    "RsaVerificationKey2018": "sec:RsaVerificationKey2018",
    "Sha256HmacKey2019": "sec:Sha256HmacKey2019",
    "SignOperation": "sec:SignOperation",
    "UnwrapKeyOperation": "sec:UnwrapKeyOperation",
    "VerifyOperation": "sec:VerifyOperation",
    "WrapKeyOperation": "sec:WrapKeyOperation",
    "X25519KeyAgreementKey2019": "sec:X25519KeyAgreementKey2019",

    "allowedAction": "sec:allowedAction",
    "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"},
    "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"},
    "capability": {"@id": "sec:capability", "@type": "@id"},
    "capabilityAction": "sec:capabilityAction",
    "capabilityChain": {"@id": "sec:capabilityChain", "@type": "@id", "@container": "@list"},
    "capabilityDelegation": {"@id": "sec:capabilityDelegationMethod", "@type": "@id", "@container": "@set"},
    "capabilityInvocation": {"@id": "sec:capabilityInvocationMethod", "@type": "@id", "@container": "@set"},
    "caveat": {"@id": "sec:caveat", "@type": "@id", "@container": "@set"},
    "challenge": "sec:challenge",
    "ciphertext": "sec:ciphertext",
    "controller": {"@id": "sec:controller", "@type": "@id"},
    "delegator": {"@id": "sec:delegator", "@type": "@id"},
    "equihashParameterK": {"@id": "sec:equihashParameterK", "@type": "xsd:integer"},
    "equihashParameterN": {"@id": "sec:equihashParameterN", "@type": "xsd:integer"},
    "invocationTarget": {"@id": "sec:invocationTarget", "@type": "@id"},
    "invoker": {"@id": "sec:invoker", "@type": "@id"},
    "jws": "sec:jws",
    "keyAgreement": {"@id": "sec:keyAgreementMethod", "@type": "@id", "@container": "@set"},
    "kmsModule": {"@id": "sec:kmsModule"},
    "parentCapability": {"@id": "sec:parentCapability", "@type": "@id"},
    "plaintext": "sec:plaintext",
    "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"},
    "proofPurpose": {"@id": "sec:proofPurpose", "@type": "@vocab"},
    "proofValue": "sec:proofValue",
    "referenceId": "sec:referenceId",
    "unwrappedKey": "sec:unwrappedKey",
    "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"},
    "verifyData": "sec:verifyData",
    "wrappedKey": "sec:wrappedKey"
  }]
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which then loads v1:

{
  "@context": {
    "id": "@id",
    "type": "@type",

    "dc": "http://purl.org/dc/terms/",
    "sec": "https://w3id.org/security#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",

    "EcdsaKoblitzSignature2016": "sec:EcdsaKoblitzSignature2016",
    "Ed25519Signature2018": "sec:Ed25519Signature2018",
    "EncryptedMessage": "sec:EncryptedMessage",
    "GraphSignature2012": "sec:GraphSignature2012",
    "LinkedDataSignature2015": "sec:LinkedDataSignature2015",
    "LinkedDataSignature2016": "sec:LinkedDataSignature2016",
    "CryptographicKey": "sec:Key",

    "authenticationTag": "sec:authenticationTag",
    "canonicalizationAlgorithm": "sec:canonicalizationAlgorithm",
    "cipherAlgorithm": "sec:cipherAlgorithm",
    "cipherData": "sec:cipherData",
    "cipherKey": "sec:cipherKey",
    "created": {"@id": "dc:created", "@type": "xsd:dateTime"},
    "creator": {"@id": "dc:creator", "@type": "@id"},
    "digestAlgorithm": "sec:digestAlgorithm",
    "digestValue": "sec:digestValue",
    "domain": "sec:domain",
    "encryptionKey": "sec:encryptionKey",
    "expiration": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
    "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
    "initializationVector": "sec:initializationVector",
    "iterationCount": "sec:iterationCount",
    "nonce": "sec:nonce",
    "normalizationAlgorithm": "sec:normalizationAlgorithm",
    "owner": {"@id": "sec:owner", "@type": "@id"},
    "password": "sec:password",
    "privateKey": {"@id": "sec:privateKey", "@type": "@id"},
    "privateKeyPem": "sec:privateKeyPem",
    "publicKey": {"@id": "sec:publicKey", "@type": "@id"},
    "publicKeyBase58": "sec:publicKeyBase58",
    "publicKeyPem": "sec:publicKeyPem",
    "publicKeyWif": "sec:publicKeyWif",
    "publicKeyService": {"@id": "sec:publicKeyService", "@type": "@id"},
    "revoked": {"@id": "sec:revoked", "@type": "xsd:dateTime"},
    "salt": "sec:salt",
    "signature": "sec:signature",
    "signatureAlgorithm": "sec:signingAlgorithm",
    "signatureValue": "sec:signatureValue"
  }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better starting point would be:

{
 "@context": {
    "@version": 1.1,
    "@vocab": "https://w3id.org/security#"
  }
}

Since you can see that all the security concerns are actually mapped to w3id.org... not w3c.

Copy link
Member

@msporny msporny Aug 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-1 for cascaded loading of security/v2 and security/v1 -- we want to get away from that in this iteration of the work.
-1 for use of @vocab for any JSON-LD context that touches security, we want to be specific about the terms we use, especially when those things are going to be digitally signed. Using @vocab causes the new "undefined terms detected" safety features of jsonld.js to not fire, and we definitely don't want to silence those safeties.

We should try to start from here since its much simpler (though, I'm fine w/ doing all of this in another PR):

https://github.com/w3c/vc-data-model/blob/main/contexts/credentials/v2

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@msporny,

I think people are reacting to the fact that this PR re-defines the v2 JSON-LD Context...

Does it? I thought that was a totally different file that only the vocab used.

Re: throwing errors when using @vocab ...

Using @vocab is an explicit signal that the author does not want errors thrown for undefined terms, but instead wants them folded into some vocabulary without knowing what they are. So I don't expect safe mode to ever throw for those cases. Using @vocab is a sort of middle ground in the security space -- where unknown terms will be signed, but there will be no globally unambiguous definition for their meaning. The introduction of a new context could also "define them later" -- in ways that may contradict their previous (locally understood) meaning. This is the danger of using @vocab, but if that danger is understood, i.e., there is zero reliability with those terms at all, perhaps that's an acceptable compromise for allowing their use.

We should get a clear understanding for the potential advantage sought by using @vocab so it can be weighed transparently and appropriately against the disadvantages. Of course, if @vocab is only being used as a bad substitute for safe mode -- then it seems to me that safe mode is clearly better. I think there's more people are looking for though.

All that being said, the implementation of the new safe mode feature in jsonld.js (at least) actually uses a more comprehensive internal event system that is able to emit all kinds of events for debugging purposes (including ones around the use of @vocab). That feature hasn't been externalized yet with a clean API. But that feature will be a development / debugging tool as opposed to a data validation / protection feature like safe mode is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think people are reacting to the fact that this PR re-defines the v2 JSON-LD Context in a way that 1) we don't want, and 2) is in conflict with what's already agreed to as a baseline by the group:

https://github.com/w3c/vc-data-model/pull/920/files#diff-0457f943f5c5375c7aa4592b374df978608840ae0f0d3bd13cf3df4d21dda2b1

Everything else you said sounds fine, Ivan. :)

This PR does not re-defines the JSON-LD context (and it should not), it uses a (in my view, bloated) context within the vocabulary definition in JSON-LD.

See my comment elsewhere: #920 (comment). Should I take that branch and merge with this one, to get this issue completely out of the way?

Of course, once this PR is settled, we have to look at the differences between the vocabulary and the v2 context to bring them in line. That is the next step, for sure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think people are reacting to the fact that this PR re-defines the v2 JSON-LD Context...

Does it? I thought that was a totally different file that only the vocab used.

Exactly. And it uses it "internally", not for external usage.

Copy link
Member

@msporny msporny Sep 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dlongley wrote:

I thought that was a totally different file that only the vocab used.

Yes, I see that now... but it's not something the vocab uses, it's just a different representation of the human-readable vocabulary document. It took me a bit to remember what Gregg's ruby tool actually does (generates a human-readable and machine-readable vocabulary definition -- NOT a JSON-LD Context).

@iherman wrote:

And it uses it "internally", not for external usage.

Ah, I see now that the "JSON-LD Context" is just "the JSON-LD representation of the Vocabulary". I think both @OR13 and @mprorock were confused in the same way that I was.

Perhaps if we rename these files to vocabulary.(html|ttl|jsonld) it would lead to less confusion? Granted, actually reading the entirety of the file might have done that, but I do remember scanning down quite a ways... but not far enough to get to the vocabulary definitions at the bottom.

You can ignore all of my suggestions (except the one to rename the files) at this point. :P

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps if we rename these files to vocabulary.(html|ttl|jsonld) it would lead to less confusion? Granted, actually reading the entirety of the file might have done that, but I do remember scanning down quite a ways... but not far enough to get to the vocabulary definitions at the bottom.

You can ignore all of my suggestions (except the one to rename the files) at this point. :P

I am fine renaming the files; it is probably a good idea. I think I will also go ahead and simplify the json-ld file to the strict minimum to avoid any misunderstandings.

But... I have to call it a day, this will be done tomorrow...

{
"id": "@id",
"type": "@type",
"cred": "https://w3.org/2018/credentials#",
"odrl": "http://www.w3.org/ns/odrl/2/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"CredentialEvidence": "cred:CredentialEvidence",
"CredentialSchema": "cred:CredentialSchema",
"CredentialStatus": "cred:CredentialStatus",
"JsonSchemaValidator2018": "cred:JsonSchemaValidator2018",
"ManualRefreshService2018": "cred:ManualRefreshService2018",
"RefreshService": "cred:RefreshService",
"VerifiableCredential": "cred:VerifiableCredential",
"VerifiableCredentialGraph": "cred:VerifiableCredentialGraph",
"VerifiablePresentation": "cred:VerifiablePresentation",
"credentialSchema": {
"@id": "cred:credentialSchema",
"@type": "@id"
},
"credentialStatus": {
"@id": "cred:credentialStatus",
"@type": "@id"
},
"credentialSubject": {
"@id": "cred:credentialSubject",
"@type": "@id"
},
"evidence": {
"@id": "cred:evidence",
"@type": "@id"
},
"expirationDate": {
"@id": "cred:expirationDate",
"@type": "xsd:dateTime"
},
"issuanceDate": {
"@id": "cred:issuanceDate",
"@type": "xsd:dateTime"
},
"issuer": {
"@id": "cred:issuer",
"@type": "@id"
},
"refreshService": {
"@id": "cred:refreshService",
"@type": "@id"
},
"serviceEndpoint": {
"@id": "cred:serviceEndpoint",
"@type": "@id"
},
"termsOfUse": {
"@id": "cred:termsOfUse",
"@type": "@id"
},
"verifiableCredential": {
"@id": "cred:verifiableCredential",
"@type": "@id",
"@container": "@graph"
}
}
],
"@graph": {
"@context": {
"id": "@id",
"type": "@type",
"dc": "http://purl.org/dc/terms/",
"owl": "http://www.w3.org/2002/07/owl#",
"rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs": "http://www.w3.org/2000/01/rdf-schema#",
"dc:title": {
"@container": "@language"
},
"dc:description": {
"@container": "@language"
},
"dc:date": {
"@type": "xsd:date"
},
"rdfs:comment": {
"@container": "@language"
},
"rdfs:domain": {
"@type": "@id"
},
"rdfs:label": {
"@container": "@language"
},
"rdfs:range": {
"@type": "@id"
},
"rdfs:seeAlso": {
"@type": "@id"
},
"rdfs:subClassOf": {
"@type": "@id"
},
"rdfs:subPropertyOf": {
"@type": "@id"
},
"owl:equivalentClass": {
"@type": "@vocab"
},
"owl:equivalentProperty": {
"@type": "@vocab"
},
"owl:oneOf": {
"@container": "@list",
"@type": "@vocab"
},
"owl:imports": {
"@type": "@id"
},
"owl:versionInfo": {
"@type": "@id"
},
"owl:inverseOf": {
"@type": "@vocab"
},
"owl:unionOf": {
"@type": "@vocab",
"@container": "@list"
},
"rdfs_classes": {
"@reverse": "rdfs:isDefinedBy",
"@type": "@id"
},
"rdfs_properties": {
"@reverse": "rdfs:isDefinedBy",
"@type": "@id"
},
"rdfs_datatypes": {
"@reverse": "rdfs:isDefinedBy",
"@type": "@id"
},
"rdfs_instances": {
"@reverse": "rdfs:isDefinedBy",
"@type": "@id"
}
},
"@id": "https://w3.org/2018/credentials#",
"@type": "owl:Ontology",
"dc:title": {
"en": "Verifiable Credentials Vocabulary v2.0"
},
"dc:description": {
"en": "This document describes the RDFS vocabulary description used for Verifiable Credentials [[VC-DATA-MODEL]]."
},
"dc:date": "2022-08-30",
"rdfs:seeAlso": [
"https://www.w3.org/TR/vc-data-model-2.0/"
],
"rdfs_classes": [
{
"@id": "cred:CredentialEvidence",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Credential Evidence"
},
"rdfs:comment": {
"en": "A `Credential Evidence` scheme provides enough information to a verifier to determine whether the evidence gathered meets their requirements for issuing a credential. The precise content of each evidence scheme is determined by the specific evidence type definition."
}
},
{
"@id": "cred:CredentialSchema",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Credential Schema"
},
"rdfs:comment": {
"en": "A `Credential Schema` provides verifiers with enough information to determine if the provided data conforms to the provided schema."
}
},
{
"@id": "cred:CredentialStatus",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Credential Status"
},
"rdfs:comment": {
"en": "A `Credential Status` provides enough information to determine the current status of the credential (for example, suspended or revoked). It MUST include the `id` property, which MUST be a URL, and the `type` property, which expresses the credential status type (also referred to as the credential status scheme)"
}
},
{
"@id": "cred:JsonSchemaValidator2018",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Json Schema Validator 2018"
},
"rdfs:comment": {
"en": "A type of validator that can be used to syntactically validate JSON documents using the JSON Schema language."
},
"rdfs:subClassOf": "cred:CredentialSchema"
},
{
"@id": "cred:ManualRefreshService2018",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Manual Refresh Service 2018"
},
"rdfs:comment": {
"en": "A type of `Refresh Service` that must be interacted with in a manual fashion."
},
"rdfs:subClassOf": "cred:RefreshService"
},
{
"@id": "cred:RefreshService",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Refresh Service"
},
"rdfs:comment": {
"en": "A `Refresh Service` is a mechanism that can be utilized by software agents to retrieve an updated copy of a `Verifiable Credential`."
}
},
{
"@id": "cred:VerifiableCredential",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Verifiable Credential"
},
"rdfs:comment": {
"en": "A `Credential` is a set of one or more claims made by an issuer. A `Verifiable Credential` is a tamper-evident credential that has authorship that can be cryptographically verified. `Verifiable Credentials` can be used to build `Verifiable Presentations`, which can also be cryptographically verified."
}
},
{
"@id": "cred:VerifiableCredentialGraph",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Verifiable Credential Graph"
},
"rdfs:comment": {
"en": "Instances of this class are RDF Graphs, where each of these graphs must include exactly one `Verifiable Credential`"
}
},
{
"@id": "cred:VerifiablePresentation",
"@type": "rdfs:Class",
"rdfs:label": {
"en": "Verifiable Presentation"
},
"rdfs:comment": {
"en": "A `Presentation` is data derived from one or more Credentials, issued by one or more `issuers`, that is shared with a specific `verifier`. A `Verifiable Presentation` is a tamper-evident `Presentation` encoded in such a way that authorship of the data can be trusted after a process of cryptographic verification. Certain types of verifiable presentations might contain data that is synthesized from, but do not contain, the original verifiable credentials (for example, zero-knowledge proofs)."
}
}
],
"rdfs_properties": [
{
"@id": "cred:credentialSchema",
"@type": "rdf:Property",
"rdfs:label": {
"en": "credential schema"
},
"rdfs:comment": {
"en": "The value of the `credentialSchema` property MUST be one or more `Credential Schema` instances."
},
"rdfs:domain": "cred:VerifiableCredential",
"rdfs:range": "cred:CredentialSchema"
},
{
"@id": "cred:credentialStatus",
"@type": "rdf:Property",
"rdfs:label": {
"en": "credential status"
},
"rdfs:comment": {
"en": "The value of the `credentialStatus` property MUST be an instance of `Credential Status`."
},
"rdfs:domain": "cred:VerifiableCredential",
"rdfs:range": "cred:CredentialStatus"
},
{
"@id": "cred:credentialSubject",
"@type": "rdf:Property",
"rdfs:label": {
"en": "credential subject"
},
"rdfs:comment": {
"en": "An entity about which claims are made."
},
"rdfs:domain": "cred:VerifiableCredential"
},
{
"@id": "cred:evidence",
"@type": "rdf:Property",
"rdfs:label": {
"en": "evidence"
},
"rdfs:comment": {
"en": "The value of the `evidence` property MUST be one or more `Credential Evidence` instances."
},
"rdfs:domain": "cred:VerifiableCredential",
"rdfs:range": "cred:CredentialEvidence"
},
{
"@id": "cred:expirationDate",
"@type": "rdf:Property",
"rdfs:label": {
"en": "expiration date"
},
"rdfs:comment": {
"en": "The value of the `expirationDate` property MUST be a string value of an ISO8601 combined date and time string representing the date and time the credential ceases to be valid."
},
"rdfs:domain": "cred:VerifiableCredential",
"rdfs:range": "xsd:dateTime"
},
{
"@id": "cred:issuanceDate",
"@type": "rdf:Property",
"rdfs:label": {
"en": "issuance date"
},
"rdfs:comment": {
"en": "The value of the `issuanceDate` property MUST be a string value of an ISO8601 combined date and time string representing the date and time the credential was issued. Note that this date represents the earliest date when the information associated with the `credentialSubject` property became valid."
},
"rdfs:domain": "cred:VerifiableCredential",
"rdfs:range": "xsd:dateTime"
},
{
"@id": "cred:issuer",
"@type": "rdf:Property",
"rdfs:label": {
"en": "issuer"
},
"rdfs:comment": {
"en": "The value of the `issuer` property MUST be a URI. It is RECOMMENDED that dereferencing the URI results in a document containing machine-readable information about the issuer that can be used to verify the information expressed in the credential."
},
"rdfs:domain": "cred:VerifiableCredential"
},
{
"@id": "cred:refreshService",
"@type": "rdf:Property",
"rdfs:label": {
"en": "refresh service"
},
"rdfs:comment": {
"en": "The value of the `refreshService` property MUST be one or more `Refresh Service` instances such that the holder can refresh the credential."
},
"rdfs:domain": "cred:VerifiableCredential",
"rdfs:range": "cred:RefreshService"
},
{
"@id": "cred:serviceEndpoint",
"@type": "rdf:Property",
"rdfs:label": {
"en": "service endpoint"
},
"rdfs:comment": {
"en": "The value of the `serviceEndpoint` property MUST be a URL to the service endpoint associated with the subject."
},
"rdfs:domain": "cred:RefreshService"
},
{
"@id": "cred:termsOfUse",
"@type": "rdf:Property",
"rdfs:label": {
"en": "terms of use"
},
"rdfs:comment": {
"en": "If specified, the value of the `termsOfUse` property MUST specify one or more terms of use policies under which the creator issued the credential or presentation. If the recipient (a holder or verifier) is not willing to adhere to the specified terms of use, then they do so on their own responsibility and might incur legal liability if they violate the stated Terms of Use. Each `termsOfUse` MUST specify its type, for example, `IssuerPolicy`, and optionally, its instance `id`. The precise contents of each term of use is determined by the specific `TermsOfUse` type definition."
},
"rdfs:domain": "cred:VerifiableCredential",
"rdfs:range": "odrl:Policy"
},
{
"@id": "cred:verifiableCredential",
"@type": "rdf:Property",
"rdfs:label": {
"en": "verifiable credential"
},
"rdfs:comment": {
"en": "The value of the `verifiableCredential` property MUST identify a `Verifiable Credential Graph` (informally, it indirectly identifies a `Verifiable Credential` contained in a separate graph)."
},
"rdfs:domain": "cred:VerifiablePresentation",
"rdfs:range": "cred:VerifiableCredentialGraph"
}
]
}
}
Loading