Skip to content

Remote @contexts considered harmful April 19, 2026

Problem

A JSON-LD document with a remote context does not fully define its own meaning. Its semantics depend on bytes fetched later from another URL.

The front page of json-ld.org presents us with an example statement about John Lennon, a famous British rock musician. For the sake of brevity and readability, let's rewrite this example in YAML-LD and render it as a graph.

"@context":
  - https://json-ld.org/contexts/person.jsonld
  - https://json-ld.org/contexts/dollar-convenience.jsonld
  - dbr: http://dbpedia.org/resource/
$id: dbr:John_Lennon
name: John Lennon
born: 1940-10-09
spouse: ["dbr:Yoko_Ono", "dbr:Cynthia_Lennon"]
graph LR
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  Literal-4649fa93775b9ab0c7a5e1bd15b6744a[["๐Ÿ“… 1940-10-09"]]
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Yoko_Ono("Yoko Ono")
  click http___dbpedia_org_resource_Yoko_Ono "http://dbpedia.org/resource/Yoko_Ono"
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Cynthia_Lennon("Cynthia Lennon")
  click http___dbpedia_org_resource_Cynthia_Lennon "http://dbpedia.org/resource/Cynthia_Lennon"
  http___dbpedia_org_resource_John_Lennon --- 1759f753de49b9a729174a0162121fbc(["birthDate"])--> Literal-4649fa93775b9ab0c7a5e1bd15b6744a
  click 1759f753de49b9a729174a0162121fbc "http://schema.org/birthDate"
  class 1759f753de49b9a729174a0162121fbc predicate
  http___dbpedia_org_resource_John_Lennon --- 203e23da021cfaec8fe3608f1809cc89(["spouse"])--> http___dbpedia_org_resource_Yoko_Ono
  click 203e23da021cfaec8fe3608f1809cc89 "http://schema.org/spouse"
  class 203e23da021cfaec8fe3608f1809cc89 predicate
  http___dbpedia_org_resource_John_Lennon --- 5467d103f69601bbafb5c89daa6ba9e2(["spouse"])--> http___dbpedia_org_resource_Cynthia_Lennon
  click 5467d103f69601bbafb5c89daa6ba9e2 "http://schema.org/spouse"
  class 5467d103f69601bbafb5c89daa6ba9e2 predicate
  classDef predicate fill:#1f2233,stroke:transparent,color:#f8fafc,stroke-width:0px;
  classDef hidden fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;
  classDef label fill:transparent,stroke:transparent,color:#e5e7eb,stroke-width:0px;
  classDef nanopubdot fill:#0f172a,stroke:#0f172a,color:transparent,stroke-width:2px;
  classDef transparent fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;

The machine responsible for rendering the graph was able to discern that the born: property maps to machine-readable http://schema.org/birthDate. That was possible thanks to the remote context that we referenced from https://json-ld.org/contexts/person.jsonld, here is the relevant excerpt:

person.jsonld
โ€ฆ
      "born":
      {
         "@id": "http://schema.org/birthDate",
         "@type": "xsd:date"
      },
โ€ฆ

What could go wrong?

What if the same context URL โ€” https://json-ld.org/contexts/person.jsonld โ€” returns different JSON than authors and readers expect? Nothing in your repository needs to change; only the bytes served at that URL change.

For instance, (json-ld.org)[https://json-ld.org] has been hacked, and now it returns a hostile response which keeps the same keys yet remaps born โ†’ schema:deathDate and spouse โ†’ schema:parent.

This would alter the meaning of the document about John Lennon:

Spoofed person.jsonld (excerpt)
โ€ฆ
    "born": {
      "@id": "http://schema.org/deathDate",
      "@type": "xsd:date"
    },
โ€ฆ
    "spouse": {
      "@id": "http://schema.org/parent",
      "@type": "@id"
    },
โ€ฆ
graph LR
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Cynthia_Lennon("Cynthia Lennon")
  click http___dbpedia_org_resource_Cynthia_Lennon "http://dbpedia.org/resource/Cynthia_Lennon"
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Yoko_Ono("Yoko Ono")
  click http___dbpedia_org_resource_Yoko_Ono "http://dbpedia.org/resource/Yoko_Ono"
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  Literal-4649fa93775b9ab0c7a5e1bd15b6744a[["๐Ÿ“… 1940-10-09"]]
  http___dbpedia_org_resource_John_Lennon --- c3901357678ef1c49a4162cad338d75e(["parent"])--> http___dbpedia_org_resource_Cynthia_Lennon
  click c3901357678ef1c49a4162cad338d75e "http://schema.org/parent"
  class c3901357678ef1c49a4162cad338d75e predicate
  http___dbpedia_org_resource_John_Lennon --- c2555ff910625a04bf52e27e8091f553(["parent"])--> http___dbpedia_org_resource_Yoko_Ono
  click c2555ff910625a04bf52e27e8091f553 "http://schema.org/parent"
  class c2555ff910625a04bf52e27e8091f553 predicate
  http___dbpedia_org_resource_John_Lennon --- ae61ca3c25efd04a58be6557347dced6(["deathDate"])--> Literal-4649fa93775b9ab0c7a5e1bd15b6744a
  click ae61ca3c25efd04a58be6557347dced6 "http://schema.org/deathDate"
  class ae61ca3c25efd04a58be6557347dced6 predicate
  classDef predicate fill:#1f2233,stroke:transparent,color:#f8fafc,stroke-width:0px;
  classDef hidden fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;
  classDef label fill:transparent,stroke:transparent,color:#e5e7eb,stroke-width:0px;
  classDef nanopubdot fill:#0f172a,stroke:#0f172a,color:transparent,stroke-width:2px;
  classDef transparent fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;

JSON-LD 1.1 specification ยง Security Considerations warns:

JSON-LD contexts that are loaded from the Web over non-secure connections, such as HTTP, run the risk of being altered by an attacker such that they may modify the JSON-LD active context in a way that could compromise security.

Being hacked is not the only risk associated with remote contexts.

Risks

  • Context Changed


    The context publisher does not need to be malicious for old documents to change meaning. A maintainer can revise a term mapping, publish an incompatible new version at the same URL, or make an ordinary mistake while editing the context. Existing documents keep pointing at the same URL, but now expand to different IRIs than they did when they were written.

  • Context Spoofed


    The context URL resolves, but returns attacker-controlled content instead of the legitimate context. This can happen through fairly ordinary failures of Internet infrastructure and ownership:

    ActivityPub implementations resolve JSON-LD over the wire when handling remote actors and objects; that has produced both shipped vulnerabilities and long-running design discussion about attacker-controlled contexts:

  • Context Unavailable


    The context URL stops resolving entirely. A processor that cannot retrieve a context cannot expand any of the terms it defines, so the document becomes unprocessable regardless of whether its own bytes are intact. Remote URLs are inherently fragile over time: link rot, server shutdowns, and deleted documents are ordinary events on a long enough horizon.

  • Client Offline


    Many JSON-LD and YAML-LD workflows need documents to remain processable without any network access at all: air-gapped deployments, archival workflows, reproducible builds, local analysis, privacy-sensitive processing, or simply working offline on a laptop. This is separate from server failure: a context server may be healthy and reachable in principle, yet the document still fails in any environment that forbids or lacks network access.

  • Privacy Exposure


    Each remote context fetch tells the context publisher which document is being processed and by whom โ€” a timing and correlation signal. The JSON-LD WG addresses this under privacy considerations for remote contexts ( w3c/json-ld-syntax#430).

  • Server Overloaded


    A context URL shared across millions of documents generates a fetch every time any processor encounters any of those documents. High-volume deployments such as ActivityPub federation, Verifiable Credential issuers, and bulk RDF pipelines can produce enormous request rates against a handful of context servers. This is precisely why the JSON-LD Best Practices recommend liberal cache-control headers and why implementations such as mastodon/mastodon#9412 rather than fetching them on demand.

The specification itself points toward one mitigation direction for semantic instability, which brings us to the first alternative.

Alternatives

The matrix below summarizes how each alternative addresses the six risks above. Each alternative name links to its tab for details.

Legend: โœ… mitigates, โš  partially or conditionally mitigates, โŒ does not mitigate.

Context Changed Context Spoofed Context Unavailable Client Offline Privacy Exposure Server Overloaded
@sri โœ… โœ… โŒ โŒ โš  โš 
@protected โš  โš  โŒ โŒ โŒ โŒ
Inline Contexts โœ… โœ… โœ… โœ… โœ… โœ…
Hash Fragment in application/ld+json โŒ โŒ โŒ โŒ โŒ โŒ
Content-Addressed Context URIs โœ… โœ… โš  โš  โš  โš 
Permanently Cache Vetted Contexts โœ… โœ… โœ… โœ… โœ… โœ…
Origin-Based Policy โŒ โŒ โŒ โŒ โŒ โŒ

The tabs below provide the example and the implementation tradeoffs for each alternative.

Future versions of this specification may incorporate subresource integrity [SRI] as a means of ensuring that cached and retrieved content matches data retrieved from remote servers; see w3c/json-ld-syntax#86.

โ€” JSON-LD 1.1 ยง Security Considerations

One concrete proposal is w3c/json-ld-syntax#108 (see also w3c/json-ld-syntax#422):

john-lennon-sri.jsonld
{
  "@context": {
    "@value": "https://json-ld.org/contexts/person.jsonld",
    "@sri": "sha256-abc123..."
  },
  "@id": "http://dbpedia.org/resource/John_Lennon",
  "name": "John Lennon",
  "born": "1940-10-09",
  "spouse": [
    "http://dbpedia.org/resource/Yoko_Ono",
    "http://dbpedia.org/resource/Cynthia_Lennon"
  ]
}
Result
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ('Invalid JSON-LD syntax; keywords cannot be overridden.',) Type:            โ”‚
โ”‚ jsonld.SyntaxError Code: keyword redefinition Details: {'context':           โ”‚
โ”‚ {'@value': 'https://json-ld.org/contexts/person.jsonld', '@sri':             โ”‚
โ”‚ 'sha256-abc123...'}, 'term': '@value'}                                       โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

โœ… Pro

  • Familiar model: Direct analogy to a proven browser standard, HTML SRI
  • Self-contained reference: The hash travels with the reference, with no separate lockfile

โŒ Contra

  • Awkward object form: A plain URL reference turns into a structured object, making the simplest @context case heavier and less readable
  • Syntax ambiguity: It is unclear how to distinguish metadata objects from inline context-by-value objects
  • Incomplete coverage: Does not yet cover @import chains

Used to prevent term definitions of a context to be overridden by other contexts.

โ€” JSON-LD 1.1 ยง Syntax Tokens and Keywords

For example, the John Lennon document could protect born and spouse before a later spoofed context is loaded. Instead of producing the spoofed graph, the processor rejects the document:

That only helps when terms are protected before the later context is loaded; it does not authenticate the fetched context.

john-lennon-protected.yamlld
"@context":
  - born:
      "@id": http://schema.org/birthDate
      "@type": xsd:date
      "@protected": true
    spouse:
      "@id": http://schema.org/spouse
      "@type": "@id"
      "@protected": true
    dbr: http://dbpedia.org/resource/
    xsd: http://www.w3.org/2001/XMLSchema#
  - person-spoofed.jsonld  # Spoofed, https://json-ld.org/contexts/person.jsonld was here originally
  - https://json-ld.org/contexts/dollar-convenience.jsonld
$id: dbr:John_Lennon
name: John Lennon
born: 1940-10-09
spouse: ["dbr:Yoko_Ono", "dbr:Cynthia_Lennon"]
Result
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ('Invalid JSON-LD syntax; tried to redefine a protected term.',) Type:       โ”‚
โ”‚ jsonld.SyntaxError Code: protected term redefinition Details: {'context':    โ”‚
โ”‚ {'Person': 'http://xmlns.com/foaf/0.1/Person', 'xsd':                        โ”‚
โ”‚ 'http://www.w3.org/2001/XMLSchema#', 'name':                                 โ”‚
โ€ฆ

โœ… Pro

  • Already in JSON-LD 1.1: No new syntax or future revision is required

โŒ Contra

  • Messy inline setup: Meaningful protection requires declaring key terms inline before loading remote contexts, which reduces the value of loading them remotely at all
  • Limited scope: It protects named term definitions, not terms resolved through @vocab or @base
  • No fetch integrity: It does not authenticate the remote context or pin its bytes
  • No @import fix: Imported contexts still extend the same remote trust boundary

In JSON-LD documents, contexts may also be specified inline. This has the advantage that documents can be processed even in the absence of a connection to the Web.

โ€” JSON-LD 1.1 ยง The Context

Instead of URL references in the John Lennon document, embed the needed term definitions directly in the document itself.

john-lennon-inline-context.yamlld
"@context":
  born:
    "@id": http://schema.org/birthDate
    "@type": xsd:date
  spouse:
    "@id": http://schema.org/spouse
    "@type": "@id"
  name: http://xmlns.com/foaf/0.1/name
  dbr: http://dbpedia.org/resource/
  xsd: http://www.w3.org/2001/XMLSchema#
$id: dbr:John_Lennon
name: John Lennon
born: 1940-10-09
spouse: ["dbr:Yoko_Ono", "dbr:Cynthia_Lennon"]
graph LR
  5f101372727c98c91391212c3a17d5ea_b0("John Lennon")
  Literal-4649fa93775b9ab0c7a5e1bd15b6744a[["๐Ÿ“… 1940-10-09"]]
  5f101372727c98c91391212c3a17d5ea_b0("John Lennon")
  http___dbpedia_org_resource_Cynthia_Lennon("Cynthia Lennon")
  click http___dbpedia_org_resource_Cynthia_Lennon "http://dbpedia.org/resource/Cynthia_Lennon"
  5f101372727c98c91391212c3a17d5ea_b0("John Lennon")
  http___dbpedia_org_resource_Yoko_Ono("Yoko Ono")
  click http___dbpedia_org_resource_Yoko_Ono "http://dbpedia.org/resource/Yoko_Ono"
  5f101372727c98c91391212c3a17d5ea_b0 --- c61fa04ee4bc149ca544908066fc5320(["birthDate"])--> Literal-4649fa93775b9ab0c7a5e1bd15b6744a
  click c61fa04ee4bc149ca544908066fc5320 "http://schema.org/birthDate"
  class c61fa04ee4bc149ca544908066fc5320 predicate
  5f101372727c98c91391212c3a17d5ea_b0 --- 9a4226e685e7907b94de856d2f6fbda5(["spouse"])--> http___dbpedia_org_resource_Cynthia_Lennon
  click 9a4226e685e7907b94de856d2f6fbda5 "http://schema.org/spouse"
  class 9a4226e685e7907b94de856d2f6fbda5 predicate
  5f101372727c98c91391212c3a17d5ea_b0 --- 6c450ce6fb06a569581c81cc5107d4b3(["spouse"])--> http___dbpedia_org_resource_Yoko_Ono
  click 6c450ce6fb06a569581c81cc5107d4b3 "http://schema.org/spouse"
  class 6c450ce6fb06a569581c81cc5107d4b3 predicate
  classDef predicate fill:#1f2233,stroke:transparent,color:#f8fafc,stroke-width:0px;
  classDef hidden fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;
  classDef label fill:transparent,stroke:transparent,color:#e5e7eb,stroke-width:0px;
  classDef nanopubdot fill:#0f172a,stroke:#0f172a,color:transparent,stroke-width:2px;
  classDef transparent fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;

โœ… Pro

  • Single-file semantics: The document fully carries the term definitions it depends on
  • No loader policy: Correct processing does not depend on cache or document-loader configuration

โŒ Contra

  • Verbose: Large shared contexts such as schema.org are repeated in every document
  • No deduplication: Context updates require re-issuing all documents

The Working Group intends to address this problem through more explanatory specification text, but also through the exploration of options such as the addition of a hash fragment to be used with the application/ld+json media type responses. This fragment conveys a content hash which may be used by implementations to further confirm and handle the intentions of the original document author.

โ€” JSON-LD Working Group Charter ยง Scope

For the John Lennon context, this would look like:

This does not mitigate the risks above because the hash is supplied by the response server, not by the document that references the context.

john-lennon-context-response.http
Content-Type: application/ld+json; hash="sha256-abc123..."
graph LR
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Yoko_Ono("Yoko Ono")
  click http___dbpedia_org_resource_Yoko_Ono "http://dbpedia.org/resource/Yoko_Ono"
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  Literal-4649fa93775b9ab0c7a5e1bd15b6744a[["๐Ÿ“… 1940-10-09"]]
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Cynthia_Lennon("Cynthia Lennon")
  click http___dbpedia_org_resource_Cynthia_Lennon "http://dbpedia.org/resource/Cynthia_Lennon"
  http___dbpedia_org_resource_John_Lennon --- 203e23da021cfaec8fe3608f1809cc89(["spouse"])--> http___dbpedia_org_resource_Yoko_Ono
  click 203e23da021cfaec8fe3608f1809cc89 "http://schema.org/spouse"
  class 203e23da021cfaec8fe3608f1809cc89 predicate
  http___dbpedia_org_resource_John_Lennon --- 1759f753de49b9a729174a0162121fbc(["birthDate"])--> Literal-4649fa93775b9ab0c7a5e1bd15b6744a
  click 1759f753de49b9a729174a0162121fbc "http://schema.org/birthDate"
  class 1759f753de49b9a729174a0162121fbc predicate
  http___dbpedia_org_resource_John_Lennon --- 5467d103f69601bbafb5c89daa6ba9e2(["spouse"])--> http___dbpedia_org_resource_Cynthia_Lennon
  click 5467d103f69601bbafb5c89daa6ba9e2 "http://schema.org/spouse"
  class 5467d103f69601bbafb5c89daa6ba9e2 predicate
  classDef predicate fill:#1f2233,stroke:transparent,color:#f8fafc,stroke-width:0px;
  classDef hidden fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;
  classDef label fill:transparent,stroke:transparent,color:#e5e7eb,stroke-width:0px;
  classDef nanopubdot fill:#0f172a,stroke:#0f172a,color:transparent,stroke-width:2px;
  classDef transparent fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;

โœ… Pro

  • Transport-level enforcement: Analogous to how SRI works in browsers
  • Transparent to authors: No syntax change required

โŒ Contra

  • Server adoption required: Existing context servers such as schema.org and w3id.org would need to emit the header
  • HTTP-only scope: It only helps when contexts are fetched through cooperating HTTP servers, not when they are copied, mirrored, or embedded elsewhere

This document defines the "Named Information" identifier, which provides a set of standard ways to use hash function outputs in names.

โ€” RFC 6920 ยง 1: Introduction

Replace location-based context URLs with content-hash-based URIs: IPFS CIDs, ni: URIs, or Trusty URIs. For the John Lennon example, that means replacing the location-based person context with a content-addressed one:

john-lennon-content-addressed.yamlld
"@context":
  - ni:///sha-256;abc123...?ct=application/ld+json
  - https://json-ld.org/contexts/dollar-convenience.jsonld
  - dbr: http://dbpedia.org/resource/
$id: dbr:John_Lennon
name: John Lennon
born: 1940-10-09
spouse: ["dbr:Yoko_Ono", "dbr:Cynthia_Lennon"]
Result
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ Failed to load the context.                                                  โ”‚
โ”‚                                                                              โ”‚
โ”‚ URL of the context: ni:///sha-256;abc123...?ct=application/ld+json Reason:   โ”‚
โ”‚ Cannot choose the loader by URL protocol.                                    โ”‚
โ”‚                                                                              โ”‚
โ”‚  โ€ข URL: ni:/sha-256;abc123...?ct=application/ld+json                         โ”‚
โ”‚  โ€ข Scheme: ni                                                                โ”‚
โ”‚  โ€ข Available schemes: file, http, https                                      โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

โœ… Pro

  • Built-in integrity: The URI itself is the integrity check, so mutation produces a different URI by construction
  • Architectural fit: Consistent with broader Linked Data trust literature, including Trusty URIs and nanopublications

โŒ Contra

  • Migration cost: All existing context URLs such as schema.org and w3id.org would need to be replaced or aliased
  • Weak adoption: The ni: scheme has no mainstream adoption, and IPFS adds infrastructure dependency
  • Version churn: Context versioning becomes explicit URI changes, which may complicate backwards compatibility

Services providing a JSON-LD Context SHOULD set HTTP cache-control headers to allow liberal caching of such contexts, and clients SHOULD attempt to use a locally cached version of these documents.

โ€” JSON-LD Best Practices: Cache JSON-LD Contexts

For the John Lennon example, that means preloading the two remote contexts it uses:

john-lennon-cached-loader.py
from pathlib import Path
import json
import pyld.jsonld as jsonld

VETTED_CONTEXTS = {
    "https://json-ld.org/contexts/person.jsonld": (
        Path(__file__).parent / "person.jsonld"
    ),
    "https://json-ld.org/contexts/dollar-convenience.jsonld": (
        Path(__file__).parent / "dollar-convenience.jsonld"
    ),
}


def cached_loader(url, options):
    if url in VETTED_CONTEXTS:
        path = VETTED_CONTEXTS[url]
        return {
            "contentType": "application/ld+json",
            "contextUrl": None,
            "documentUrl": url,
            "document": json.loads(path.read_text()),
        }
    raise ValueError(f"Refusing to fetch un-vetted context: {url}")


jsonld.set_document_loader(cached_loader)
graph LR
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Yoko_Ono("Yoko Ono")
  click http___dbpedia_org_resource_Yoko_Ono "http://dbpedia.org/resource/Yoko_Ono"
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  Literal-4649fa93775b9ab0c7a5e1bd15b6744a[["๐Ÿ“… 1940-10-09"]]
  http___dbpedia_org_resource_John_Lennon("John Lennon")
  click http___dbpedia_org_resource_John_Lennon "http://dbpedia.org/resource/John_Lennon"
  http___dbpedia_org_resource_Cynthia_Lennon("Cynthia Lennon")
  click http___dbpedia_org_resource_Cynthia_Lennon "http://dbpedia.org/resource/Cynthia_Lennon"
  http___dbpedia_org_resource_John_Lennon --- 203e23da021cfaec8fe3608f1809cc89(["spouse"])--> http___dbpedia_org_resource_Yoko_Ono
  click 203e23da021cfaec8fe3608f1809cc89 "http://schema.org/spouse"
  class 203e23da021cfaec8fe3608f1809cc89 predicate
  http___dbpedia_org_resource_John_Lennon --- 1759f753de49b9a729174a0162121fbc(["birthDate"])--> Literal-4649fa93775b9ab0c7a5e1bd15b6744a
  click 1759f753de49b9a729174a0162121fbc "http://schema.org/birthDate"
  class 1759f753de49b9a729174a0162121fbc predicate
  http___dbpedia_org_resource_John_Lennon --- 5467d103f69601bbafb5c89daa6ba9e2(["spouse"])--> http___dbpedia_org_resource_Cynthia_Lennon
  click 5467d103f69601bbafb5c89daa6ba9e2 "http://schema.org/spouse"
  class 5467d103f69601bbafb5c89daa6ba9e2 predicate
  classDef predicate fill:#1f2233,stroke:transparent,color:#f8fafc,stroke-width:0px;
  classDef hidden fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;
  classDef label fill:transparent,stroke:transparent,color:#e5e7eb,stroke-width:0px;
  classDef nanopubdot fill:#0f172a,stroke:#0f172a,color:transparent,stroke-width:2px;
  classDef transparent fill:transparent,stroke:transparent,color:transparent,stroke-width:0px;

โœ… Pro

  • Available today: Implementable with any JSON-LD processor via a custom document loader
  • Fits controlled deployments: Works well for archival, reproducible, and air-gapped processing

โŒ Contra

  • Operational burden: Requires an organizational process to update and re-vet cached copies
  • Policy portability gap: A document does not carry its own trust policy, so another deployment may resolve the same contexts differently

The same-origin policy uses URIs to designate trust relationships.

โ€” RFC 6454 ยง 3.5: Conclusion

Applied to JSON-LD context loading: a document from https://example.org would load same-origin contexts by default; cross-origin contexts would require explicit CORS permission. This is a rejected non-solution: it controls origin access, not context bytes or durability.

โœ… Pro

  • Self-describing policy: No external configuration or allowlist is needed
  • Mature model: It is already implemented in every web browser

โŒ Contra

  • Impractical default: Most real JSON-LD usage is cross-origin by design, so shared vocabularies such as schema.org and w3id.org would be blocked without a cross-origin permission mechanism
  • Wrong layer: It restricts who can serve contexts, not what they contain; a same-origin server can still change, spoof, or lose its context