digitalbazaar / jsonld.js

A JSON-LD Processor and API implementation in JavaScript
https://json-ld.org/
Other
1.66k stars 195 forks source link

property-scoped context should not be protected #404

Closed Fak3 closed 4 years ago

Fak3 commented 4 years ago

JSON LD spec says:

a property-scoped context is not affected by protection, and can therefore override protected terms, either with a new term definition, or by clearing the context with "@context": null.

I tried this example in the json playground: https://tinyurl.com/y7wuexzb

{
  "@context": [
    {
        "@version": 1.1,
        "@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" }
      }
    }
  ],
  "type": ["VerifiableCredential"],
  "issuer": {
    "name": "My issuer"
  }
}

This resulted in error: jsonld.SyntaxError: Invalid JSON-LD syntax; tried to redefine a protected term.

The expected behavior according to the JSON-LD scpec is to allow redefenition of property-scoped context of a protect term.

The same error is thrown on attempt to use Verifiable Credentials context.

gkellogg commented 4 years ago

That is, actually, the purpose of protected contexts, to make it so that terms can't be overridden, except in some specific circumstances. When you define a context as part of a term used as a property (property-scoped), then that context can override things in a previous context. The thought is that you're entering a new part of the graph, where it's often the case that the vocabulary comes from some other place.

Type-scoped contexts, and embedded context can't override protected contexts. These are the pertinent lines from Protected Term Definitions:

While protected terms can in general not be overridden, there are two exceptions to this rule. The first exception is that a context is allowed to redefine a protected term if the new definition is identical to the protected term definition (modulo the @protected flag). The rationale is that the new definition does not violate the protection, as it does not change the semantics of the protected term. This is useful for widespread term definitions, such as aliasing @type to type, which may occur (including in a protected form) in several contexts.

The second exception is that a property-scoped context is not affected by protection, and can therefore override protected terms, either with a new term definition, or by clearing the context with "@context": null.

Your example doesn't fall into either of these two cases.

dlongley commented 4 years ago

The issue here is that issuer itself was redefined by adding a property-scoped context to it when there wasn't one previously. An attempt was made to enable precisely this targeted use case before JSON-LD 1.1 became a standard, but we ended up having to postpone considering enabling that case to a later revision.

You would able able to define a new term that has a property-scoped context that itself redefined "issuer" such that when "issuer" may have a new definition when nested underneath that new term, however, here you are directly redefining "issuer", which is forbidden.

dlongley commented 4 years ago

To give a concrete example based on your example above, this would be permitted:

{
  "@context": [
    {
        "@version": 1.1,
        "@protected": true,
        "issuer": {"@id": "https://www.w3.org/2018/credentials#issuer", "@type": "@id"}
    },
    {
      "myNewTerm": {
        "@id": "https://example.org/myNewTerm",
        "@context": {
          "issuer": {
            "@id": "https://www.w3.org/2018/credentials#issuer", "@type": "@id",
            "@context": { "name": "http://example.org/name" }
          }
        }
      }
    }
  ],
  "type": ["VerifiableCredential"],
  "myNewTerm": {
    "issuer": {
      "name": "My issuer"
    }
  }
}

Unfortunately, I know that this doesn't solve for your use case here. Clearly, you want to be able to define a targeted set of properties underneath "issuer" -- but "issuer" is already defined by the VC context in such a way that you can't do that sort of targeting. Being able to do exactly 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:

{
  "@context": [
    {
      "@version": 1.1,
      "@protected": true,
      "issuer": {"@id": "https://www.w3.org/2018/credentials#issuer", "@type": "@id"},
      "type": "@type"
    },
    {
      "MyIssuerType": {
        "@id": "https://example.org/MyIssuerType",
        "@context": { "name": "http://example.org/name" }
      }
    }
  ],
  "type": ["VerifiableCredential"],
  "issuer": {
    "type": "MyIssuerType",
    "name": "My issuer"
  }
}

It requires that the issuer be more strongly typed -- which can be considered either a plus or a minus. But this will accomplish what you're looking for where the only difference is in needing a type. You can do something similar with "credentialSubject".

Fak3 commented 4 years ago

Being able to do exactly 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.

Thanks for the information. Is there any github issue to track the progress on this?

dlongley commented 4 years ago

@Fak3,

Thanks for the information. Is there any github issue to track the progress on this?

Hmm, I don't think so. Please feel free to create one. @gkellogg, where should @Fak3 file this feature request issue... https://github.com/w3c/json-ld-syntax/issues, https://github.com/w3c/json-ld-api/issues, or https://github.com/json-ld/json-ld.org/issues ?

gkellogg commented 4 years ago

Probably the best place is on https://github.com/json-ld/json-ld.org/issues, but it could also go to https://github.com/w3c/json-ld-syntax, we'll look at both going forward.

Fak3 commented 4 years ago

Moved to https://github.com/w3c/json-ld-syntax/issues/361