w3c-ccg / security-vocab

The Linked Data Security Vocabulary
https://w3id.org/security
Other
21 stars 21 forks source link

Establish best practices for using protected term #75

Closed kdenhartog closed 3 years ago

kdenhartog commented 4 years ago

Figured out the issue and playing around with a few ways to fix it at the moment.

What I've discovered is that the new terms (except the one's defined in the VC context) are encountering issues where the terms are being redefined within the V3 context itself.

For example, when using the "@protected": true at the top of the context document it's effectively adding the term to each property. So for nonce it's going from "nonce": "https://w3id.org/security#nonce"

to now being defined like so:

"nonce": { 
  "@id": "https://w3id.org/security#nonce", 
  "@protected": true  
},

So the problem is that the way that we originally defined terms like BbsBlsSignatureProof2020 means that we're defining terms in the property contexts and then redefining them at the top level context in a way that conflicts.

Related to issues discovered during this PR: https://github.com/w3c-ccg/security-vocab/pull/70/#issuecomment-724385975

kdenhartog commented 4 years ago

I've been digging into this further and have found the problem is that proofPurpose property at the top level context is defined like so:

"proofPurpose": { 
   "@id": "https://w3id.org/security#proofPurpose",
   "@type": "@id"
},

However the property-scoped context that redefines proofPurpose inside the BbsBlsSignaturesProof2020, BbsBlsSignatures2020, and a few other similar LDS suites define the property as such:

"proofPurpose": {
  "@id": "https://w3id.org/security#proofPurpose",
  "@type": "@vocab",
  "@context": {
      "id": "@id",
      "type": "@type",
      "assertionMethod": {
        "@id": "https://w3id.org/security#assertionMethod",
        "@type": "@id",
        "@container": "@set"
      },
      "authentication": {
        "@id": "https://w3id.org/security#authenticationMethod",
        "@type": "@id",
        "@container": "@set"
      }
   }
},

From what I can tell on this issue, https://github.com/digitalbazaar/jsonld.js/issues/404 this feature is not something that is supported in json-ld 1.1, so am I misunderstanding the solution @dlongley is proposing in that thread or is this something that won't work and I'm understanding correctly that this feature just isn't supported and we'll need to create a work around?

From what I can find playing around with this, the best answer to solving this is to just drop the proofPurpose property at the top level and then have each LDS suite define the supported proofPurpose context individually. Thoughts on taking this approach @peacekeeper @OR13

peacekeeper commented 4 years ago

I'm not as experienced as others with this, but I find it a bit surprising that it's considered best practice to repeat "proofPurpose" with the exact same definitions 8 times throughout the document, instead of defining it once and then re-using it....

OR13 commented 4 years ago

@peacekeeper yes I agree... I think the repetition comes from the idea of "scoping" in JSON-LD.... unlike JSON Schema, you can't reference an other schema easily, which causes this repetition....

kdenhartog commented 4 years ago

The only reason I could come up with this was because the proofPurpose property is being limited to a subset of terms that can be used with it. For example, if I add keyAgreement in there I think it may change how the JSON-LD signatures library processes the acceptable VM that can be used. I'm not certain of this though and will have to wait for @dlongley to respond.

dlongley commented 4 years ago

yes I agree... I think the repetition comes from the idea of "scoping" in JSON-LD.... unlike JSON Schema, you can't reference an other schema easily, which causes this repetition....

You could do it partially:

"proofPurpose": {
  "@id": "https://w3id.org/security#proofPurpose",
  "@context": "<url to shared scoped context for proofPurpose>"
}

But, yes, this ultimately comes down to a feature we tried to get into JSON-LD 1.1 but it didn't make the cut: Allow adding a scoped context to an already defined term.

We really have two clear options here:

  1. Do what @kdenhartog suggests and define proofPurpose within each proof suite so it is type-scoped. There would be a requirement that it use the same identifier in the core spec for LD suites. This approach allows suites to have some discretion around the scoped context associated with it, but requires them to use the correct @id. This approach would lend itself better to customization in suites, but would be harmful to writing generic code.
  2. Define proofPurpose a specific way for the security-v3 context and all suites that use it must use that definition. This would mean locking in the definition at each version -- all suites built against that version would need to be compatible with that definition. When a need arises to change it, we'd go to v4. This would presume that all suites could easily share the definition. This approach would lend itself better to writing more generic code but would require new versions and agreement to support new features.
OR13 commented 4 years ago

I would be in favor of 3 assuming it would work for suites like bbs+ / merkleproof which are a bit unique in the space.

kdenhartog commented 4 years ago
2. Define `proofPurpose` a specific way for the security-v3 context and all suites that use it must use that definition. This would mean locking in the definition at each version -- all suites built against that version would need to be compatible with that definition. When a need arises to change it, we'd go to v4. This would presume that all suites could easily share the definition. This approach would lend itself better to writing more generic code but would require new versions and agreement to support new features.

@dlongley I'm good with this path. The thing I haven't figured out about yet is why these verificationMethods are defined within the proofPurpose. From what I could tell jsonld-signatures may be relying upon this to develop the set of potential values that can be contained in a proof of a document. In the case of digital signatures, using only assertionMethod and authentication are the only ones we used. If this is the case (I'm still confirming at the moment), then what would we do in the instance where it's a ZCAP-LD where capabilityInvocation or capabilityDelegation would be used would that not work? I assume we could get it working by including the superset of all proofPurposes (such as the 4 mentioned plus keyAgreement) and then limit the options available through the issuance process rather than the LDS suite type.

So this leads me to two questions for likely @dlongley or potentially @OR13:

  1. Is jsonld-signatures actually behaving in this way?
  2. Is the option of providing the superset and relying on the issuer/signer to handle it an acceptable path forward?
OR13 commented 4 years ago

IMO, the concept of "knowing the verification relationship up front" concerns me... what happens when we add "authorization" or "foo"...