Skip to main content

Verify a container format (MXF)

The verifier reads every C2PA-native format directly. A container format with no C2PA byte layout of its own, such as an MXF broadcast master, is read through a container plugin: a separately published component that teaches the verifier where the manifest lives inside the container and which byte ranges the signature covers. A build that never verifies MXF links zero of this code, so the plugin is opt-in.

MXF is the one container plugin published today: @limboai/verifox-sdk-verifier-container-mxf. It is the read-only counterpart to the issuer plugin; pure Rust, so it runs in the browser and on Node alike.

Install

Add the plugin alongside the verifier SDK:

npm install @limboai/verifox-sdk-verifier @limboai/verifox-sdk-verifier-container-mxf

The plugin peer-depends on @limboai/verifox-sdk-verifier: the SDK owns the host I/O contract the plugin runs against, so the two ship and version together.

Register the plugin

Construct the plugin and pass it in the array AssetSdk.create takes as its optional second argument. Omit the array for a c2pa/image-only verifier; each plugin is tried in order on a format match.

verify-mxf.ts
import { AssetSdk } from '@limboai/verifox-sdk-verifier';
import { MxfContainer } from '@limboai/verifox-sdk-verifier-container-mxf';

const verifier = AssetSdk.create({ trustAnchors: [orgCaPem] }, [new MxfContainer()]);

Verify a master

An MXF master is verified through a RangeSource so it never enters memory: the verifier reads only the byte ranges the plugin locates. Everything else is the ordinary asset flow: verify returns one { manifest, binding } entry per credential, and manifest.validation_state is 'Trusted' when the signing chain resolves to a configured anchor.

verify-mxf.ts
import { openSync, readSync, fstatSync, closeSync } from 'node:fs';

function rangeSource(path) {
const fd = openSync(path, 'r');
return {
get length() { return fstatSync(fd).size; },
readAt(offset, length) {
const buf = Buffer.alloc(length);
const n = readSync(fd, buf, 0, length, offset);
return new Uint8Array(buf.buffer, buf.byteOffset, n);
},
close() { closeSync(fd); },
};
}

const source = rangeSource('master.mxf');
try {
const [result] = await verifier.verify(source, []);
const state = result?.manifest.validation_state; // 'Trusted' | 'Valid' | 'Invalid' | undefined
} finally {
source.close();
}

Reading the result is identical to a c2pa asset: the { manifest, binding } shape, the validation states, and recovery binders for a transcoded master all carry over. See Verify an asset. A streamed master typically carries its ISCC out of band, recovered via Binder.held(...).

See also