w3c / json-ld-syntax

JSON-LD 1.1 Specification
https://w3c.github.io/json-ld-syntax/
Other
111 stars 22 forks source link

Support non-propagating protected terms #361

Open Fak3 opened 4 years ago

Fak3 commented 4 years ago

I bumped into a practical limitation of json-ld with Verifiable credentials data model

VC context defines few protected terms at the top level of the json object - namely issuer and credentialSubject. According to the spec, ids of those properties must be protected, and the content that goes under them is left for the users of the spec to be changed (mostly) freely. But unfortunately json-ld 1.1 protected terms prevent users from modifying property-scoped context of protected term:

{
  "@context": [
   {
      "@protected": true,
      "issuer": { "@id": "https://www.w3.org/2018/credentials#issuer", "@type": "@id" }
   },
   {
      "issuer": {
        "@id": "https://www.w3.org/2018/credentials#issuer", "@type": "@id",
        "@context": { "name": "http://example.org/name" }  // This raises error - modifying protected `issuer` term is not allowed
      }
   }
  ],
  "type": ["VerifiableCredential"],
  "issuer": {
    "name": "My issuer"
  }
}

This ticked is moved from https://github.com/digitalbazaar/jsonld.js/issues/404

@dlongley wrote: this use case was something that was discussed in the JSON-LD WG, but we couldn't find a way to support it given the time constraints. I also wanted this use case supported. Something similar would have been very useful for "credentialSubject" as well.

The alternative here is to define a type instead -- and use a type-scoped context. Like this:

"issuer": {
   "type": "MyIssuerType",
}

The workaround suggested by @dlongley works, but I wonder if there might be better way to handle this usecase in the next version of json-ld spec.

Something that comes to mind is to use "@protected" keyword inside a property-scoped context of a protected term to allow its redefinition:

   {
      "@protected": true,
      "issuer": { 
         "@id": "https://www.w3.org/2018/credentials#issuer", "@type": "@id" ,
         "@context": { "@protected": false }  // Indicates that property-scoped context of this protected term can be overriden.
      }
   },
dlongley commented 4 years ago

So, allowing protection to be turned off like in the above suggestion would circumvent the protection feature -- so it's not a viable option. However, we could potentially allow for protection overrides for terms that were previously defined with no scoped context -- provided that their new definition is identical modulo the introduction of a scoped context. Another consideration is whether or not we would need the original definition to call out that it can be overwritten in this manner.

Fak3 commented 4 years ago

So, allowing protection to be turned off like in the above suggestion would circumvent the protection feature -- so it's not a viable option.

No, i suggested that @id, @type, @container for the protected terms still be protected from redefinition. Only the property-scoped @context can be modified.

dlongley commented 4 years ago

@Fak3,

No, i suggested that @id, @type, @container for the protected terms still be protected from redefinition. Only the property-scoped @context can be modified.

Ah, ok. I misunderstood how your proposal would work. I see now that you're suggesting that the original issuer definition could be modified to add a scoped context that included an "@protected": false flag -- as a signal that it could be overridden.

dlongley commented 4 years ago

Now that I better understand the proposal, I still think it would be problematic for at least a few reasons. I originally interpreted it the way I did because @protected would be processed within the scoped context (and generally when it is applied), not as part of the context where issuer itself is defined -- which is where the conflict is. Furthermore, "@protected": false already has meaning -- and is the default value for an @context; setting it doesn't mean that other term definitions within the context won't have @protected set to true. IOW, it is possible to have a context with a mix of @protected and unprotected terms.

I think any signal that a scoped context can be overridden needs to be at the top level of the term definition that calls it out as a scoped context. That's where the protection applies. Just consider if the scoped context had been referenced by URL. It would be odd to have whether or not a particular scoped context can be replaced on a term be set by that context itself as opposed to the term definition that establishes it as a scoped context for that term.

TallTed commented 3 years ago

I have no input for this issue at the moment, but noticed a typo in the issue title which deserves correction -- proteced should be protected.