← attestto.com  ·  All Specs  ·  Implementation Report

VCP — Verifiable Content Provenance

Specification version: 0.1 (Working Draft) Publication date: 2026-07-01 Canonical URL (planned): https://spec.attestto.com/vcp Editors: Eduardo Chongkan (Attestto) License: Specification text is licensed under Creative Commons Attribution 4.0 International (CC-BY 4.0). Reference code, JSON Schemas, and examples are licensed under Apache License 2.0. Reference implementation: github.com/Attestto-com/vcp-cli (@attestto/vcp on npm)


Abstract

This specification defines the Verifiable Content Provenance (VCP) container: a compact, embed-first metadata block that carries an issuer DID, a content-type declaration, a canonical content hash, an optional recipient DID, an optional profile identifier, and an EdDSA signature over the canonical JSON encoding of the block. The block is designed to travel inside host file formats (PDF, JPEG, ISOBMFF containers, and others) so that legacy readers ignore it and only VCP-aware tools verify or act on it.

VCP is deliberately narrow. It is not a rights-expression language, not a DRM system, and not a licensing framework. It answers a single question: for this file, who issued it, when, to whom, and has it been modified since?

VCP is the natural carrier for IEAL identity-evidence claims and for domain-specific profiles (legal-document, medical-record, ID-evidence, media). This v0.1 draft specifies only the base container. Profiles are separate documents.


Status of This Document

This is a Working Draft (v0.1) published for public review, peer critique, and standards-body engagement. It is not a final specification. Breaking changes may occur before v1.0.

Feedback is welcomed through:

Relationship to other Attestto specifications:


1. Introduction

1.1 Motivation

Content provenance is currently addressed by format-specific standards: PAdES for PDF, C2PA for images and video, XMP for photographic metadata, JOSE for JSON payloads. Each solves the provenance question inside one carrier. Cross-carrier tooling has to re-implement signing, verification, and metadata for every format, and profile-level concerns (what fields matter for a legal document versus a captured biometric versus a music track) get mixed into the base carrier spec.

VCP factors the container mechanics out from the profile concerns:

The result is that a legal document, a photograph of an ID, an audio recording, and a plain-text file can all carry the same shape of envelope with the same verification path, and that adding a new host format is a carrier-only change.

1.2 Terminology

The terms MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC 2119 and RFC 8174 when, and only when, they appear in all capitals.


2. Envelope structure

A VCP envelope is a JSON object with exactly two top-level fields: metadata and signature.

{
  "metadata": { ... },
  "signature": {
    "alg": "EdDSA",
    "value": "<base64url signature>"
  }
}

2.1 Metadata block

The metadata block MUST include the following fields:

Field Type Description
spec string (URI) MUST equal https://spec.attestto.com/vcp/.
spec_version string MUST equal 0.1 for envelopes conforming to this document.
issuer string (DID) The DID of the entity that signed this envelope.
content_type string The IANA Media Type of the host file (e.g. application/pdf, image/jpeg).
content_hash string The hexadecimal SHA-256 hash of the host file, computed per the hash_scope rule.
hash_scope string Either host-file-minus-vcp-block (embed carriers) or host-file-unmodified (sidecar carrier).
timestamp string RFC 3339 timestamp of signature creation.

The metadata block MAY include the following fields:

Field Type Description
subject string (DID) The DID of the intended recipient or subject of the content.
profile string (URI) Identifier of a profile that layers additional required fields on this envelope.
ieal object An IEAL v0.1 claim describing the assurance level of the identity evidence contained.

Implementations MUST reject envelopes containing unknown top-level metadata fields at the same time they reject unknown spec_version values. This forces additive changes into a new spec_version and prevents ambiguity.

2.2 Signature block

The signature block MUST include:

Field Type Description
alg string Signature algorithm identifier. For v0.1 the only permitted value is EdDSA.
value string The base64url-encoded raw signature output.

The signature is computed over the UTF-8 bytes of the canonical JSON serialization (JCS RFC 8785) of the metadata object. Verification recomputes the canonicalization and calls the signature algorithm’s verify primitive with the issuer’s resolved public key.

Post-quantum hybrid signature suites (e.g. ML-DSA + Ed25519) are out of scope for v0.1 and will be added in a future version with an expanded alg registry.


3. Canonicalization

Canonicalization has two layers.

3.1 Metadata canonicalization

The metadata block is serialized using JCS (RFC 8785) prior to signing. The signature is computed over the UTF-8 bytes of the JCS output.

3.2 Content canonicalization

The content_hash field commits to a canonical representation of the host file. Two hash_scope values are defined:

Each carrier specification MUST define precisely which byte range is treated as “the VCP-owned embed region” and how to remove it. The removal MUST be deterministic — two implementations MUST arrive at the same removed representation given the same input.


4. Carriers (v0.1)

This section specifies three carriers. Additional carriers are the subject of follow-on specifications.

4.1 Sidecar

4.2 PDF (v0.1 pattern)

4.3 JPEG


5. DID methods

The issuer and subject fields carry DIDs. Verifiers MUST support at least the did:key method for interoperability testing. Additional methods MAY be supported.

5.1 did:key (mandatory for verifiers)

The did:key method encodes an Ed25519 public key directly in the identifier. No external resolution is required. This is the minimum bar for VCP interoperability testing and is REQUIRED to be supported by all verifiers.

5.2 Other methods (optional)

Verifiers MAY support other DID methods including did:pki, did:sns, did:web, did:webvh, did:jwk. Resolution of these methods requires either a bundled resolver or the DIF Universal Resolver HTTP interface. If resolution fails, the verifier MUST report a resolution failure distinctly from a signature verification failure.


6. Profiles

A profile is a supplementary specification identified by URI in the profile metadata field. Profiles layer domain-specific required and optional fields on top of the base envelope. Profiles MUST NOT contradict the base specification.

Example profiles under discussion (each will be published as a separate document):

An envelope MAY omit the profile field, in which case it is a base envelope and any additional metadata fields are informational.


7. Conformance

7.1 Signer conformance

A conforming signer:

  1. MUST produce envelopes whose metadata object contains all required fields in §2.1.
  2. MUST canonicalize the metadata block per §3.1 before signing.
  3. MUST use one of the algorithms registered in §2.2.
  4. MUST embed the resulting envelope using one of the carriers specified in §4 or a carrier from a subsequent specification.
  5. SHOULD ensure that re-signing a previously-signed host file replaces the prior VCP envelope rather than compounding embed blocks.

7.2 Verifier conformance

A conforming verifier:

  1. MUST reject envelopes with unknown top-level metadata fields.
  2. MUST reject envelopes whose spec_version is not recognized.
  3. MUST recompute the content hash per the declared hash_scope and reject on mismatch.
  4. MUST support at least the did:key method (§5.1).
  5. MUST distinguish DID-resolution failure from signature verification failure in its output.
  6. MAY warn on the sidecar-separation risk per §4.1.

8. Security considerations

8.1 Threat model

VCP defends against:

VCP does NOT defend against:

8.2 Algorithm agility

VCP v0.1 supports exactly one signature algorithm (EdDSA). This is intentional for the working-draft phase. A future revision will introduce an algorithm registry with hybrid post-quantum options. Envelopes signed under v0.1 will be verifiable indefinitely under the algorithm they were signed with; the registry addition will not invalidate existing signatures.

8.3 Confidentiality

VCP v0.1 does not encrypt the host file. The envelope is a plaintext signed metadata block. Confidentiality of the content is out of scope for v0.1. A future revision will add a standalone .vcp envelope carrier with an encrypted payload for use cases where the content itself must be access-controlled.


9. Privacy considerations

VCP envelopes reveal:

Applications SHOULD NOT include personally identifiable information in the metadata block. Selective disclosure of subject attributes is a profile concern and SHOULD be handled by pointing to an SD-JWT or verifiable credential elsewhere rather than by embedding attribute values in the envelope.

Pairwise DIDs ([[pairwise-identifiers pattern from W3C VC-DATA-MODEL 2.0 §8.10]]) SHOULD be used for subject when the issuer-subject relationship should not be correlatable across contexts.


10. Change log


References

Normative

Informative

Reference implementation