3 HIP 012: Define and use JSON‐LD schemas
Andrew Gallagher edited this page 2025-07-04 00:07:16 +01:00

Motivation

We currently use JSON to represent certificates in both the database back end and the user-facing templating engine (jsonhkp). We also propose (#394) to merge all internal memory representations of certificates into the jsonhkp schema. Other OpenPGP implementations have also expressed an interest in a common JSON representation of arbitrary OpenPGP material. Updates to the existing jsonhkp schema may therefore be required, and a publicly available, versioned schema for JSON representations would be a natural way to unify these efforts.

In addition, compatibility with the upcoming Structured Mail specification would allow us to represent other events, such as email verification requests and responses, in a similar format.

Design

Structured Mail defines JSON-LD as its native message format. While JSON-LD is an extensive standard, it is possible to define schemas within it that use only a subset of its features. We can add the "@context" JSON field to existing structures and allow it to function as both a magic number and a domain separator. The schemas referenced by the context field would only define an object structure, and would not rely on any other JSON-LD features.

Examples of interactions

Versioning of jsonhkp schema

We should ensure that all schemas are explicitly versioned; if we wish to make changes to the schema(s) of data in long term storage (such as jsonhkp documents), we can use the version bump to gracefully upgrade.

{
  "@context": "https://hockeypuck.io/schemas/pgp-cert-v1",
  "fingerprint": "deadbeefdeadbeefdecafbad",
  "md5": "12354567890987654321",
  ...
}

Human-friendly dumps of PGP messages

{
  "@context": "https://hockeypuck.io/schemas/pgp-message-v1",
  "marker": {
    "data": "PGP"
  },
  "pkesk": {
    ...
  },
  "seipd": {
    ...
  }
}

OpenPGP signatures over arbitrary JSON objects

This could be used to authenticate administrative commands to a keyserver (#359), or sign an email proof over an arbitrary transport (#385).

{
  "@context": "https://hockeypuck.io/schemas/hkp-signed-v1",
  "body": {
    "@context": "https://hockeypuck.io/schemas/...",
    ...
  },
  "sig": "DEADBEEFDECAFBAD..."
}

sig would be calculated over a normalised representation of body, and encoded directly in base64 (not ASCII-armor). The dual @context fields are critical - the one in the outer part acts as a magic number that indicates the presence of signed data, and the one in the inner part acts as a domain separator for the signature.

Out of scope

Use of any JSON-LD features other than "@context" schema references.

Security considerations

Careful use of the "@context" parameter, particularly in signed bodies, should provide sufficient domain separation.

Compatibility

It should be possible to gracefully upgrade to proper schemas, if existing code ignores "@context" fields.

References