CDX — Content-addressed Document eXchange. An open specification for documents that unify viewing and editing, with modern security and machine readability.
Status: Draft Specification (v0.1)
The document landscape is fundamentally divided:
- View-optimized formats (PDF, DJVU) offer layout fidelity but poor editability
- Edit-optimized formats (DOCX, ODF, Markdown) enable rich editing but render inconsistently
- No existing format excels at both viewing and editing
This divide creates workflow friction, format conversion overhead, and lost fidelity. Additionally:
- PDF's security model is broken: 21 of 22 desktop viewers vulnerable to signature attacks
- Machine readability is an afterthought: 73-96% accuracy even with state-of-the-art extraction
- Compression is outdated: PDF uses 30-year-old DEFLATE, missing modern algorithms
- No clear "frozen" semantics: Signatures don't truly lock documents
- No verifiable history: Document lineage and provenance are external concerns, not built-in
- Appearance varies by viewer: Even PDF renders differently across implementations
- Unified View/Edit Mode: One format from draft to archive, no conversion step
- Semantic-First: Content stored as meaning, presentation derived
- Modern Security: Algorithm-agile cryptography, post-quantum ready
- Machine Readable: AI/ML extraction works reliably by design
- Content-Addressable: Document hash is its identity; modifications create new versions
- Verifiable Provenance: Built-in hash chains and Merkle trees for tamper-evident history
- Efficient compression using modern algorithms (Zstandard, AVIF)
- Clear document state machine (draft → review → frozen/signed)
- State-aware presentation (reactive for drafts, precise when page-precise fidelity is required)
- Block-level proofs (prove a section exists without revealing the whole document)
- Timestamp anchoring (RFC 3161, blockchain)
- Accessibility built-in (WCAG-aligned)
- Replacing PDF for legacy/archival use cases
- Supporting scripting/executable content (security risk)
- Achieving 100% PDF import fidelity
┌─────────────────────────────────────────────────────────────┐
│ DOCUMENT CONTAINER │
│ (ZIP archive, content-addressable hash = identifier) │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────────────────────┐ │
│ │ MANIFEST │ │ CONTENT STREAMS │ │
│ │ - Version │ │ ┌────────────────────────────┐ │ │
│ │ - State │ │ │ Semantic Document Layer │ │ │
│ │ - Signatures[] │ │ │ (JSON blocks + Merkle tree)│ │ │
│ │ - Lineage │ │ └────────────────────────────┘ │ │
│ │ - Merkle root │ │ ┌────────────────────────────┐ │ │
│ └──────────────────┘ │ │ Presentation Layer(s) │ │ │
│ │ │ - Reactive (hints/styles) │ │ │
│ ┌──────────────────┐ │ │ - Precise (exact coords) │ │ │
│ │ SECURITY LAYER │ │ └────────────────────────────┘ │ │
│ │ - Signatures │ │ ┌────────────────────────────┐ │ │
│ │ - Encryption │ │ │ Assets │ │ │
│ │ - Timestamps │ │ │ (images, fonts, embeds) │ │ │
│ └──────────────────┘ │ └────────────────────────────┘ │ │
│ └──────────────────────────────────┘ │
│ ┌──────────────────┐ │
│ │ PROVENANCE │ ← Links to parent document hash │
│ │ - Parent hash │ (documents form a hash chain) │
│ │ - Ancestors │ │
│ │ - Timestamps │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────────────┘
CDX documents form a cryptographic hash chain — each document's identity IS its content hash, and each document can reference its parent by hash:
doc-v1 (sha256:aaa) ←── doc-v2 (sha256:bbb) ←── doc-v3 (sha256:ccc)
│ │ │
└── parent: null └── parent: aaa └── parent: bbb
This enables:
- Tamper-evident history: Forging an intermediate version is computationally infeasible
- No external infrastructure: Documents themselves ARE the chain
- Block-level Merkle proofs: Prove a specific section exists without revealing the whole document
- Selective disclosure: Share redacted documents with cryptographic proof of what was removed
- Timestamp anchoring: Anchor document hashes to RFC 3161 TSAs or public blockchains
CDX uses progressive enhancement for presentation — the level of layout precision evolves with document maturity:
| Document State | Presentation Requirement | What's Frozen |
|---|---|---|
| DRAFT | Reactive only (hints/styles) | Nothing — content flows freely |
| REVIEW | Reactive (precise optional) | Nothing — still editing |
| FROZEN | Reactive (precise when fidelity required) | Content immutable; a declared precise layout is bound (locked) |
| PUBLISHED | Same as FROZEN | Authoritative, immutable record |
When a frozen or published document includes a precise layout (exact coordinates for every element), that layout becomes part of the immutable record:
- Semantic content is the hash: The document ID covers semantic content only — what it says, not how it looks
- Appearance is locked alongside content: A precise layout is separate from the content hash, but declaring it in the manifest binds its file hash into the manifest projection — which a frozen or published document's signature must cover — so its appearance is attested by default (Security Extension)
- Citations are reliable: "Page 7, line 23" means the same thing in every viewer
- Legal/archival integrity: documents that assert page-precise fidelity commit an immutable, signature-bound layout that cannot be silently altered
- No viewer inconsistency: Unlike PDF, whose appearance varies by renderer
This is the key insight: the state machine isn't just about workflow — it ties presentation precision to content stability. Freezing always locks the semantic content; documents that assert page-precise fidelity also declare the precise layout in the manifest, binding it into the signature-covered projection so it cannot be silently altered.
DRAFT FROZEN/PUBLISHED
┌─────────────────┐ ┌─────────────────┐
│ Semantic content│ │ Semantic content│ ← Document ID
│ (JSON blocks) │ │ (JSON blocks) │ (content hash)
├─────────────────┤ ├─────────────────┤
│ Reactive hints │ → │ Reactive hints │
│ (optional) │ │ + Precise layout│ ← When fidelity required
└─────────────────┘ │ (exact coords) │ (bound into the
└─────────────────┘ manifest projection)
The specification is modular:
- Container Format - ZIP-based packaging
- Manifest - Document metadata and structure
- Content Blocks - Semantic content model
- Anchors and References - Unified sub-block addressing
- Presentation Layers - Rendering instructions
- Asset Embedding - Images, fonts, files
- Document Hashing - Content-addressable identity
- State Machine - Draft/frozen lifecycle
- Metadata - Dublin Core and extensions
- Provenance and Lineage - Hash chains, Merkle trees, timestamping
- Renderer Safety - Safe URIs and untrusted-content sanitization
- Security Model - Attacker model, guarantees, disclosed limitations, PDF attack-class comparison
- Security Extension - Signatures, encryption, access control
- Collaboration Extension - CRDT hooks, comments, change tracking
- Presentation Extension - Advanced layout, print styling
- Forms Extension - Input fields, validation
- Semantic Extension - JSON-LD, knowledge graphs, citations
- Academic Extension - Theorems, proofs, exercises, algorithms, equations
- Phantoms Extension - Off-page annotation clusters
- Legal Extension - Legal citations, clause references, jurisdiction metadata
- Conformance - Testing artifacts for implementations: the defect-code vocabulary today, growing into the conformance suite. Nothing here is part of the specification;
spec/andschemas/govern.
A CDX document is a ZIP archive with this structure:
document.cdx
├── manifest.json # Document manifest (includes lineage, Merkle root)
├── content/
│ ├── document.json # Semantic content blocks
│ └── block-index.json # Leaf hashes for Merkle proofs
├── presentation/
│ ├── paginated.json # Print hints (reactive)
│ ├── continuous.json # Screen hints (reactive)
│ ├── responsive.json # Viewport hints (reactive)
│ └── layouts/ # Precise layouts (when fidelity required)
│ ├── letter.json # US Letter format coordinates
│ └── a4.json # A4 format coordinates
├── assets/
│ ├── images/
│ ├── fonts/
│ └── embeds/
├── security/
│ └── signatures.json # Digital signatures
├── provenance/
│ └── record.json # Lineage, timestamps, derivations
└── metadata/
└── dublin-core.json # Standard metadata
The manifest carries document identity and references the content file by path and hash — the content blocks are not embedded inline:
{
"cdx": "0.1",
"id": "sha256:a1b2c3...",
"state": "draft",
"content": {
"path": "content/document.json",
"hash": "sha256:e3b0c4..."
}
}The blocks live in content/document.json:
{
"version": "0.1",
"blocks": [
{
"type": "heading",
"level": 1,
"children": [{ "type": "text", "value": "Hello, World" }]
},
{
"type": "paragraph",
"children": [
{ "type": "text", "value": "This is a " },
{ "type": "text", "value": "CDX", "marks": ["bold"] },
{ "type": "text", "value": " document." }
]
}
]
}- Extension:
.cdx - MIME Type:
application/vnd.cdx+json(canonical JSON form) - Alternative:
application/vnd.cdx(binary/packed form)
- Complete core specification documents
- JSON Schema for validation
- Example documents
- Security extension (signatures, encryption)
- Collaboration extension (CRDT integration)
- Presentation extension (advanced layout)
- Forms extension (input fields, validation)
- Semantic extension (JSON-LD, citations)
- TypeScript parser/writer library
- Web-based viewer
- Basic editor integration
- Conversion tools (PDF, DOCX import/export)
- CLI tools (validate, sign, verify)
- Standards body submission
Capabilities whose absence the specification discloses today and which are planned or under consideration for future versions. Each pointer leads to the disclosure that explains what is (and is not) provided now.
- Merkle root binding & trusted redaction — the block-level
cdx-bmt-1root is advisory (bound by neither the document ID nor the manifest projection), so inclusion/exclusion/redaction proofs are not yet trusted evidence (core 09 §5.2; DD-020). Binding the root into the projection unlocks verifiable redaction — a marquee capability for the legal profile. - Archive timestamps / LTV renewal — long-term validation currently decays when a TSA certificate expires or a timestamp algorithm weakens; archive-timestamp chains that renew proofs are a subsequent version (security extension §7.5, §8.5).
- Authenticated annotations & approvals — every annotation, comment, form value, and workflow status is advisory today; authenticating an editorial decision requires signed content or a required-signer policy (security extension §3.10). An annotation-signature construction is an open design question (design decisions, OQ-005).
- Counter-signatures & signing-order binding — the required-signer set declares which signers, never in what order; "notarized after signing" is not expressible (security extension §3.12; OQ-006).
- WebAuthn attestation — assertions are verified without authenticator-model assurance (AAGUID / FIDO MDS); requiring certified hardware needs attestation support (security extension §6.4).
- Composite hybrid signatures — the hybrid PQC profile uses two independent signatures; a single-envelope composite algorithm awaits standardization (security extension §8.2).
- Lifecycle-downgrade closure — the downgrade residual is provably minimal for a self-contained file (security extension §9.8; DD-021); closing the remaining replay case requires external infrastructure (a transparency log or verifier-side expected-ID pinning), named a deliberate non-goal of the current design (core 09 §2.1).
- Blockchain anchoring extraction — the standalone
blockchaintimestamp type is Experimental and a candidate for extraction to a separate extension (core 09 §6.4).
See CONTRIBUTING.md for guidelines.
This specification and all associated code are licensed under the Apache License 2.0. See LICENSE for details.
This specification draws inspiration from:
- PDF (ISO 32000) for document packaging concepts
- Portable Text (Sanity) for semantic content modeling
- EPUB for reflowable document structure
- CRDTs (Yjs, Automerge) for collaboration patterns
- Git for content-addressable storage and hash chain lineage
- Merkle trees for efficient integrity proofs
- OpenTimestamps for decentralized timestamp anchoring