Names and Schemas
A POD is a cryptographic record with no enforced schema. A POD is made up of entries consisting of a name (always a string) and a value (of a supported type). Values are scalars with no nested objects, meaning the POD structure is flat.
Apps can represent their data however they like. Entry names and values are hashed and cryptographically verified in a POD. The issuer of a POD decides what the expected set of names and values should be for their use case. The definition order of entries is not important since entries area always sorted by name before hashing.
- Names: The cryptography behind PODs will accept any name or value which can be validly hashed. The POD library enforces the legal characters in names described below.
- Value schemas: There is no formal notion of a schema for POD entries, but there are some recommended best-practices apps should follow, most particularly the use of the
pod_type
and Zupass Display entries described below.
The rest of this page describes the requirements and recommendations about POD names and schemas.
Legal Names
POD names (represented by the PODName
type) are limited to a character set which matches variable identifiers in most languages. They allow alphanumeric characters and underscores, and cannot begin with a digit. This allows PODEntries
to be conveniently accessed as TypeScript objects without quoting their names:
This limited character set is restrictive today, but may expand in future versions to support new features. This also leaves special characters to be used for special purposes outside of PODs themselves, such as in GPC proof configuration (see below).
Use of Names in GPCs
The PODName
specification is also used in GPC configuration when a name is needed to refer to a whole POD, or a list of values, etc. These names follow the same PODName
rules for convenience, but this detail is not cryptographically relevant. These names exist only for the GPC compiler to correlate different parts of the config and inputs, and do not appear in the ZK circuit.
The GPC compiler also uses some special characters when naming things in constraints, for example:
idPOD.idNumber
names a POD and an entry of that POD. In this caseidPOD
is an arbitrary name assigned to a POD, whileidNumber
is the name of an entry which must be in the POD.idPOD.$signerPublicKey
names the public key of a POD. The name$signerPublicKey
never appears in the POD itself, but the config compiler treats it as a virtual entry when defining constraints.
Reserved Names
Apps should avoid defining their own entry names with the prefixes pod_
or zupass_
as these are reserved for special uses in the SDK, or in Zupass. Some of these have defined uses described below, which apps are encouraged to use accordingly. Remaining names with those prefixes are reserved for future use.
pod_type
The pod_type
entry is the a recommended way for apps to tag their PODs to let their contents be understood across apps. It should be used by apps to identify the purpose or schema of their PODs using some unique identifier. In future, this might be used to index into a library of published schema identifiers. For now, the pod_type
is not enforced, but is helpful to avoid mixing PODs with common names. For instance, pod.name
means something different on a driver’s license than it does on a collectible frog.
There is no required format for pod_type
, but it is recommended to contain the name or identifier of your app so as to be unique. Reverse domain name notation is a good way to ensure that.
Zupass Display
Zupass is a generic POD store able to hold any type of POD, and show the user its entries. It’s easier for a user if that POD can display in a friendlier format than a JSON dump. If you anticipate your POD being stored in Zupass, you should set one or more of the following fields:
zupass_display
(string): the preferred display format for your POD. Accepted values are:collectable
displays the other fields described below in a card. Requires at least one of title, description, or image URL to be set.pod
explicitly chooses the default JSON display
zupass_title
(string): a short title for your POD, used in folder listings and/or the top of the display card.zupass_description
(string): a text description of your PODzupass_image_url
(string): the URL to fetch an embedded image to display with your POD.
Outside of Zupass, how you display your PODs is entirely up to you. You can use the JSON format defined by pod.toJSON()
which is intended to be human-readable, but you can also invent your own formats more specific to your app.
Suggested Best Practices
Here are some remaining suggestions about naming and using POD entries, which don’t depend on reserved characters or names.
Ownership
PODs can be marked with a user’s identity in a way which allows a GPC to prove ownership. There is no fixed entry name for this purpose, since it can be selected in the GPC configuration. Thus you could name your ownership entry attendee
or citizen
as befits your use case. However if you want a recommended default, you can use an entry named owner
of type eddsa_pubkey
.
Example POD
Here is an example POD which follows all the requirements and best-practices described in this page. This is the Meerkat app’s proof of attendance from a talk at Devcon 7 SEA.