Version 1.0 · SHA-256 · Ed25519 · Canonical JSON · Append-only event chain
EPX/1 is an open format for recording the provenance of digital image files. A manifest is a JSON document that accompanies an image, recording its origin, cryptographic hash, edit history, and a digital signature from the signing entity.
Manifests are stored as sidecar files alongside the image. The preferred filename is <image_filename>.epx.json.
While EPX/1 is an open format that any implementor may adopt, the VeriChain Directory — which confirms signer identity — is a curated ecosystem. Registration is available only through VeriChain-authorised applications, ensuring the integrity of the identity layer.
| Field | Type | Description |
|---|---|---|
| format_id | string | Must be "EPX/1" |
| manifest_version | string | Must be "1.0" |
| object_uuid | string | Lowercase UUID v4. Stable for the lifetime of the image. |
| parent_manifest_hash | string | null | SHA-256 hex of the previous manifest. null for genesis. |
| content_hash_alg | string | Must be "sha-256" |
| content_hash | string | Lowercase hex SHA-256 of the raw image file bytes. |
| metadata_hash_alg | string | Must be "sha-256" |
| signature_alg | string | Must be "ed25519" |
| canonicalization_profile | string | Must be "epx1-canonical-json-v1" |
| signer_key_id | string | Identifies the signing key and the ecosystem app that created it. Format: {app_id}:{uuid} — e.g. verilens:550e8400-…. The app_id is a short lowercase identifier for the VeriChain ecosystem app (e.g. verilens). The UUID is the user's permanent VeriChain identity. |
| capture | object | Capture metadata. Must include timestamp. |
| events | array | Ordered list of edit events. Empty for genesis manifests. |
| manifest_hash | string | Lowercase hex SHA-256 of the canonical manifest (excluding signature and manifest_hash). |
| signature | string | Lowercase hex Ed25519 signature over the manifest_hash bytes (UTF-8). |
The manifest hash is computed from a canonical serialisation of the manifest object. The following rules apply:
signature and manifest_hash fields are excluded before hashingsignature and manifest_hash fields from the manifest objectmanifest_hashmanifest_hash string using Ed25519 → this is the signature| Type | Description |
|---|---|
| crop | Spatial crop. Params: x, y, w, h (normalised 0–1) |
| rotate | Rotation. Params: degrees |
| brightness | Tonal adjustment. Params: brightness, contrast, saturation (–100 to +100) |
| contrast | Contrast adjustment. Params: contrast |
| resize | Resize. Params: width_pct, height_pct |
| denoise | Noise reduction. Params: amount (0–100) |
| color_adjust | Colour grading. Params: saturation, warmth |
| ai_generate | AI-generated content introduced. Must be declared explicitly. |
| other | Arbitrary edit. Params: note (string) |
| Field | Required | Description |
|---|---|---|
| type | Yes | One of the event types above |
| timestamp | Yes | RFC 3339 UTC timestamp, e.g. 2026-04-11T09:41:00Z |
| params | No | Key/value pairs specific to the event type |
| tool | No | Identifier of the tool that performed the edit |
A conforming verifier must perform all of the following checks in order:
format_id must equal "EPX/1" and manifest_version must equal "1.0"content_hashmanifest_hashparent_manifest_hash must equal the manifest_hash of the previous revisionEPX/1 supports three storage models in order of preference:
<filename>.epx.json alongside the image (recommended)Unknown non-critical fields must be preserved when reading and rewriting a manifest. Implementations must not drop fields they do not recognise. Use a vendor prefix (e.g. x_acme_gps) for custom fields to avoid future collisions with reserved EPX/1 names.
{
"canonicalization_profile": "epx1-canonical-json-v1",
"capture": {
"device": "iPhone 17 Pro",
"software": "VeriLens/1.0",
"timestamp": "2026-04-11T09:41:00Z"
},
"content_hash": "cf56017fda1e2c63ba6003984985bbd7b2e023ae6dc6122388f819c8654cd776",
"content_hash_alg": "sha-256",
"events": [],
"format_id": "EPX/1",
"manifest_hash": "57cd22156c2ad5a7f50615dbe0cc899eb431703cc19c264b5f9ae95a57987091",
"manifest_version": "1.0",
"metadata_hash_alg": "sha-256",
"object_uuid": "96541304-b68e-4de7-91f1-96ff731a5c9d",
"parent_manifest_hash": null,
"signature": "aabb...ccdd",
"signature_alg": "ed25519",
"signer_key_id": "verilens:550e8400-e29b-41d4-a716-446655440000"
}