Section: Core Specification Version: 0.1 Maturity: Draft
The manifest (manifest.json) is the root metadata structure of a CDX document. It describes the document's identity, version, state, structure, and processing requirements.
The manifest MUST be:
- Located at
/manifest.jsonin the archive root - The first file in the ZIP archive
- Valid JSON conforming to RFC 8259
- Encoded as UTF-8 without BOM
{
"cdx": "0.1",
"id": "sha256:a1b2c3d4e5f6...",
"state": "draft",
"created": "2025-01-15T10:30:00Z",
"modified": "2025-01-15T14:22:00Z",
"content": {
"path": "content/document.json",
"hash": "sha256:..."
},
"presentation": [...],
"assets": {...},
"security": {...},
"metadata": {...},
"extensions": [...],
"lineage": {...}
}| Field | Type | Description |
|---|---|---|
cdx |
string | Specification version (e.g., "0.1") |
id |
string | Content-addressable document identifier |
state |
string | Document state (see State Machine spec) |
created |
string | ISO 8601 creation timestamp |
modified |
string | ISO 8601 last modification timestamp |
content |
object | Content layer reference |
metadata |
object | Metadata references |
| Field | Type | Description |
|---|---|---|
presentation |
array | Presentation layer references |
assets |
object | Asset manifest |
security |
object | Security layer reference |
extensions |
array | Active extension declarations |
lineage |
object | Version history and parent reference |
phantoms |
object | Phantom layer reference (Phantom Extension) |
hashAlgorithm |
string | Hash algorithm for the document ID (default sha256) |
provenance |
string | Path to the provenance record file |
signaturePolicy |
object | Required-signer policy (Security Extension) |
profile |
string | Advisory profile declaration (Profiles) |
academic |
object | Academic Extension configuration |
semantic |
object | Semantic Extension configuration |
legal |
object | Legal Extension configuration |
collaboration |
object | Collaboration Extension configuration |
The specification version this document conforms to.
{
"cdx": "0.1"
}Format: MAJOR.MINOR (PATCH omitted for documents)
Implementations MUST reject documents with a major version they do not support. A higher minor version within a supported major version MUST NOT be rejected: an implementation SHOULD process the fields it recognizes and ignore unrecognized additions (a warning disposition — State Machine section 5.4).
The content-addressable identifier for this document version.
{
"id": "sha256:3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
}Format: algorithm:hexdigest
See Document Hashing specification for computation rules.
For documents in draft state, the id MAY be a placeholder that is computed when the document is finalized:
{
"id": "pending"
}The current lifecycle state of the document.
{
"state": "draft"
}Valid values: "draft", "review", "frozen", "published"
See State Machine specification for state definitions and transitions.
ISO 8601 timestamp when the document was first created.
{
"created": "2025-01-15T10:30:00Z"
}This value MUST NOT change across document versions. Use lineage to trace original creation time.
ISO 8601 timestamp when the document was last modified.
{
"modified": "2025-01-15T14:22:00Z"
}This value MUST be updated on any content or metadata change.
Reference to the content layer.
{
"content": {
"path": "content/document.json",
"hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"compression": "zstd"
}
}| Field | Type | Required | Description |
|---|---|---|---|
path |
string | Yes | Relative path within archive |
hash |
string | Yes | Hash of file contents |
compression |
string | No | Compression used ("deflate", "zstd", "none") |
merkleRoot |
string | No | Merkle tree root hash of content blocks (see Provenance spec section 4.4) |
blockCount |
integer | No | Number of content blocks in the document |
construction |
string | No | Merkle tree construction identifier — cdx-bmt-1 (see Provenance spec section 4.4) |
Array of presentation layer references.
{
"presentation": [
{
"type": "paginated",
"path": "presentation/paginated.json",
"hash": "sha256:...",
"default": true
},
{
"type": "continuous",
"path": "presentation/continuous.json",
"hash": "sha256:..."
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | Presentation type identifier |
path |
string | Yes | Relative path within archive |
hash |
string | Yes | Hash of file contents |
default |
boolean | No | Whether this is the default presentation |
contentHash |
string | No | Document content hash when this presentation was generated |
generated |
string | No | ISO 8601 timestamp when this presentation was generated |
Standard presentation types:
"paginated"- Fixed page layout for print"continuous"- Vertical scroll for screen"responsive"- Reflowable layout
At most one entry MAY set default: true; setting it on more than one presentation is invalid. To choose a presentation, a reader uses the entry marked default: true when present and of a type it supports, and otherwise the first entry, in array order, whose type it supports. A document MAY declare presentations of several types; presentation is outside the document-hash boundary (Document Hashing section 4.1a), so the choice never affects the document ID.
Asset manifest describing embedded resources.
{
"assets": {
"images": {
"count": 5,
"totalSize": 1048576,
"index": "assets/images/index.json"
},
"fonts": {
"count": 2,
"totalSize": 65536,
"index": "assets/fonts/index.json"
},
"embeds": {
"count": 1,
"totalSize": 2048,
"index": "assets/embeds/index.json"
}
}
}See Asset Embedding specification for index file format.
Security layer reference. Presence indicates the Security Extension is active.
{
"security": {
"signatures": "security/signatures.json",
"encryption": null
}
}| Field | Type | Description |
|---|---|---|
signatures |
string | Path to signatures file, or null |
encryption |
string | Path to encryption metadata, or null |
Array of active extensions beyond the core specification.
{
"extensions": [
{
"id": "cdx.security",
"version": "0.1",
"required": true
},
{
"id": "cdx.collaboration",
"version": "0.1",
"required": false
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Extension identifier |
version |
string | Yes | Extension version |
required |
boolean | Yes | Whether extension is required for correct rendering |
config |
object | No | Extension-specific configuration paths or inline settings |
If required is true, implementations that do not support the extension MUST refuse to process the document. If required is false, an implementation that does not support the extension MUST still process the document, ignoring that extension's data and degrading gracefully (State Machine section 5.4).
References to metadata files.
{
"metadata": {
"dublinCore": "metadata/dublin-core.json",
"custom": {
"legal": "metadata/legal.json"
}
}
}| Field | Type | Required | Description |
|---|---|---|---|
dublinCore |
string | Yes | Path to Dublin Core metadata |
jsonld |
string | No | Path to a document-level JSON-LD metadata file (Semantic Extension); out-of-hash advisory data, referenced by path only |
custom |
object | No | Map of custom metadata references (name → path) |
Reference to the phantom annotation layer. Presence indicates the Phantom Extension is active.
{
"phantoms": {
"clusters": "phantoms/clusters.json"
}
}| Field | Type | Required | Description |
|---|---|---|---|
clusters |
string | Yes | Path to phantom clusters file |
Phantom data is explicitly outside the content hash boundary. No hash field is included — adding or editing phantoms never changes the document ID.
Version history and document relationships. The manifest's lineage is the authoritative, signable ancestor chain: on a frozen or published document the manifest projection binds it (Security Extension section 9.7), so the chain it declares is tamper-evident. It carries the immediate parent, the nearest-first ancestors chain, depth, branch, merge parents (mergedFrom), version, and a note. The provenance record (provenance/record.json) restates the same chain with additional auditing detail (derivation history and timestamps) but is path-only and unsigned — never the authoritative copy. See the Provenance and Lineage specification for the verification model.
{
"lineage": {
"parent": "sha256:previousdochash...",
"ancestors": ["sha256:previousdochash...", "sha256:rootdochash..."],
"version": 3,
"depth": 3,
"branch": "main",
"note": "Updated section 3 per review feedback"
}
}| Field | Type | Required | Description |
|---|---|---|---|
parent |
string | No | Document ID of parent version (null for a root) |
ancestors |
array | No | Nearest-first ancestor chain; ancestors[0] equals parent. Placing it here binds the signed chain (Provenance and Lineage section 3.3) |
version |
integer | No | Sequential version number (advisory) |
depth |
integer | No | Generation number: 1 for the root, +1 per generation (advisory; recomputed on verification) |
branch |
string | No | Branch identifier for parallel versions |
mergedFrom |
array | No | Additional merge-parent document IDs (Provenance and Lineage section 3.4) |
note |
string | No | Description of changes from parent |
The hash algorithm used to compute the document id. Defaults to sha256 when omitted.
{
"hashAlgorithm": "sha256"
}When present, this value MUST match the algorithm prefix of the id. See the Document Hashing specification for the supported algorithms and computation rules.
Path to the provenance record file, which carries the document's derivation history and timestamps. Its lineage restates the authoritative chain in manifest.lineage (section 4.13) with additional auditing detail; because the provenance record is path-only and unsigned, it is never the authoritative copy.
{
"provenance": "provenance/record.json"
}The canonical location is provenance/record.json. See the Provenance and Lineage specification.
The document's signature policy. Its requiredSigners set binds the signature set against stripping and downgrade: the policy rides in the signed manifest projection, so every manifest-covering signature attests it. While any such signature survives, the set is tamper-evident — a stripped required signer is detected (survivors still declare it required), and editing the set breaks each survivor's manifest coverage.
{
"signaturePolicy": {
"requiredSigners": [ ... ]
}
}See the Security Extension specification.
Top-level configuration objects for the correspondingly named extensions. Each is an open object whose shape is defined by the extension that owns it — for example, file-path pointers or rendering options — and appears at the manifest root only when that extension is active.
{
"academic": { ... },
"semantic": { ... },
"legal": { ... },
"collaboration": { ... }
}See the relevant extension specification for each object's shape.
An advisory declaration of the profile a document targets, as a bare identifier.
{
"profile": "simple"
}A profile is non-normative guidance on which features suit a use case (see the Profiles specification); it defines no conformance class (Introduction section 1.3). The profile field is therefore advisory only:
- It never affects document validity. A document that declares a profile but uses features outside that profile's guidance is still a fully valid CDX document.
- A consumer MUST process a document that declares a profile as a standard CDX document — honoring every feature it actually contains regardless of the declared value — and SHOULD ignore an unrecognized profile value.
- A producer MAY declare a profile to signal intent; doing so imposes no obligation to restrict the document to that profile's recommended features.
The declaration carries no version component and is not bound by the document ID or the signed manifest projection.
Implementations MUST verify:
- All required fields are present
- Field types match specification
cdxversion is supported- Referenced files exist in archive
- File hashes match when present
The disposition when any of these checks fails is defined by State Machine section 5.4.
For frozen and published documents, implementations MUST verify that referenced file hashes match actual contents; a mismatch is an INTEGRITY-ERROR (State Machine section 5.4).
The manifest state MUST be consistent with other indicators:
| State | Security Signatures | Lineage.parent |
|---|---|---|
| draft | Optional | Optional |
| review | Optional | Optional |
| frozen | Required | Required if forked |
| published | Required | Required if forked |
Note:
Lineage.parentis required for frozen/published documents that were derived from another document (forked). Root documents — those created from scratch, not forked from a parent — have no parent and omit this field.
- Extract
manifest.jsonfrom archive - Parse as JSON
- Validate
cdxversion - Check required fields
- Load referenced files as needed
- Construct manifest object
- Compute content hash
- Compute document ID (if not draft)
- Set timestamps
- Serialize to JSON
- Write as first file in archive
When modifying a document:
- Update
modifiedtimestamp - Recalculate content hash
- Update
idif not draft - If version-controlled, set
lineage.parentto previousid
{
"cdx": "0.1",
"id": "pending",
"state": "draft",
"created": "2025-01-15T10:30:00Z",
"modified": "2025-01-15T10:30:00Z",
"content": {
"path": "content/document.json",
"hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"metadata": {
"dublinCore": "metadata/dublin-core.json"
}
}{
"cdx": "0.1",
"id": "sha256:3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
"state": "frozen",
"created": "2025-01-10T08:00:00Z",
"modified": "2025-01-15T14:22:00Z",
"content": {
"path": "content/document.json",
"hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"compression": "zstd"
},
"presentation": [
{
"type": "paginated",
"path": "presentation/paginated.json",
"hash": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"default": true
}
],
"assets": {
"images": {
"count": 3,
"totalSize": 524288,
"index": "assets/images/index.json",
"hash": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
}
},
"security": {
"signatures": "security/signatures.json",
"encryption": null
},
"extensions": [
{
"id": "cdx.security",
"version": "0.1",
"required": true
}
],
"metadata": {
"dublinCore": "metadata/dublin-core.json"
},
"lineage": {
"parent": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"version": 2,
"note": "Final version after legal review"
}
}