Trust & verification
Downloading an MPAI implementation works like pulling a signed container image: before anything runs, a consumer proves it really came from the Store and was not tampered with. The Store implements a small, TUF-like (The Update Framework) handshake for exactly this.
Verification proves an implementation is authentic and unmodified, not that it is safe: we sign metadata, not code.
Two keys: an offline root, and an online signer
The Store separates the trust anchor from the day-to-day signer, so a breach of the web server is recoverable:
- Offline ROOT key
- The trust anchor. It signs only
root.jsonandrevoked.json, and consumers pin this rather than the signing key. Its private half is held off this web server; nothing the web process can reach is able to produce a root signature.
c9b886102d2925fccebc8ce3bf19d03a6fb0e6e28d02d498fe52dbd72226b779 - Online signing key
- The only key the web process loads; signs each implementation statement.
62e0444a3b338a425f5284a8688d4745225724138860d51e1249da5f1791b2c6 - root.json
- Signed by the offline root · version 1 ·
/trust/root.json - Anchor (out-of-band)
/.well-known/mpai-store-root· revocations:/trust/revoked.json- Validity
- root 365 days · statements 90 days
Counter-signed statements (implementer + Store)
Implementers generate their own Ed25519 keypair and register only the public key (proving possession by signing a challenge). When they sign a submission, the Store embeds that key in the statement it publishes; once they counter-sign the published statement, it carries two signatures — implementer-authenticity (who made it) and store-endorsement (it passed validation). The Store never holds an implementer's private key, so a Store breach cannot forge an implementer's authorship.
What the Store signs
For each published implementation the Store signs a statement that binds the Implementation ID to the exact hash of the published metadata and of the archive, plus a validity window:
{
"_type": "mpai-implementation-statement",
"spec_version": "2.0",
"version": 1,
"implementation_id": "MPAI0042-blipvqa_linux-MMC-TIQ-V2.5",
"aim": "MMC-TIQ-V2.5",
"interoperability_level": 1,
"aim_metadata": { "url": "https://mpai.store/MPAI/AIFS/Implementation/MPAI0042-blipvqa_linux-MMC-TIQ-V2.5/Metadata",
"hashes": { "sha256": "<hash of the published metadata>" } },
"artifact": { "download_url": "https://you.example/aims/pkg.zip", "size": 1536000,
"hashes": { "sha256": "<hash of the archive>" } },
"issued": "<when it was signed>",
"expires": "<90 days later>",
"submission": { "implementer_id": "MPAI0042", "metadata_sha256": "<hash of the metadata as submitted>" },
"implementer_key": { "keyid": "<the implementer's key ID>", "public": "<their public key>" }
}
submission and implementer_key are present when the implementer signed their
submission. The object is canonicalized (sorted keys, no whitespace, non-ASCII characters escaped — exactly
jq -cSa) and signed; the published bundle is
{ "signed": {…}, "signatures": [ { "keyid", "sig", "role" } ] }, served at
/MPAI/AIFS/Trust/Implementation/<id>.
How a consumer (SCI) verifies — in order
- Pin the offline root keyid (from
/.well-known/mpai-store-root, cross-checked out-of-band). Verify/trust/root.jsonis self-signed by it, and read the online signing key from itssigningrole. - Load
/trust/revoked.json(root-signed); refuse any key that appears on it. - Fetch the signed statement for the Implementation ID.
- Re-canonicalize
signedand check the Store's Ed25519 signature with the online key. (Verify over bytes you re-canonicalize — never a supplied blob.) - If the statement carries an
implementer_key+ implementer-authenticity signature, verify it too — the Store's signature vouches for that key, so it is root-anchored. - Check the
implementation_idmatches; check the validity window and that the version is not older than one seen (rollback protection). - Download the metadata; check its SHA-256 equals the signed hash. Then download the archive from the signed
download_url— refuse any other URL — and check its size and SHA-256 against the signed values. - All pass → ACCEPT (authentic — then review the code). Any failure → REJECT.
Try it
Every step above is doable with standard tools you already have — openssl, curl,
jq, sha256sum — with no MPAI software. The complete, copy-paste sequence is in
the publishing & verification guide, section D.
A quick integrity check against the running Store:
The Implementation ID to check:
IMPL_ID='PASTE_AN_IMPLEMENTATION_ID_HERE'Fetch its signed statement:
curl -s -fS "https://mpai.store/MPAI/AIFS/Trust/Implementation/$IMPL_ID" > stmt.jsonPrint the archive hash the Store signed:
jq -r '.signed.artifact.hashes.sha256' stmt.jsonDownload the archive and print its hash — Linux or WSL:
curl -s -fS "$(jq -r '.signed.artifact.download_url' stmt.json)" | sha256sum | cut -d' ' -f1macOS:
curl -s -fS "$(jq -r '.signed.artifact.download_url' stmt.json)" | shasum -a 256 | cut -d' ' -f1The two hashes must be identical. If they differ, the bytes you received are not the bytes the Store
signed — stop, and do not run them. Changing a single byte of the archive changes the hash, which is
precisely what this check is for. If either curl prints an error, that is a fetch failure,
not a hash mismatch — fix the ID or the URL and re-run.
Recovering trust after an attack
Because consumers pin the offline root — not the online key — a compromised online key is
recoverable. The offline root revokes the bad key (published, signed, at
/trust/revoked.json) and signs a new root version
naming a fresh online key. A consumer's verifier walks from the root it already pinned to the new version,
confirms the offline-root signature, and starts rejecting anything signed by the revoked key — no blind
"trust us again" required.
How this maps to TUF
The envelope is kept TUF-shaped. root.json plays TUF's root role (self-signed,
versioned, with a root and a signing role); each statement is a targets-style
assertion; revoked.json is a signed kill-list. There is currently no snapshot/timestamp
role or transparency log, so freeze and rollback are bounded by the expiry windows and the version check.