wasm-verification-component is the TrustMee verifier host for Wasm verification components. It reads a TrustMee CMW input, extracts the TrustMee-profile EAT evidence, loads a stapled verification component when present, or resolves the matching component from an OCI repository and caches Wasm verification components locally.
Normative format documents:
TRUSTMEE_EAT_PROFILE.mdTRUSTMEE_OUTPUT_EAT_PROFILE.mdTRUSTMEE_CMW_COLLECTION_TYPE.md
- TrustMee mainline is a modified Trustee implementation that integrates TrustMee as a verifier driver and uses this repository as its verification library.
- wasm-verification-components contains the Wasm verification components that this verifier host can execute.
The primary input is a CMW Collection that contains:
- exactly one TrustMee-profile EAT Evidence item
- zero or more endorsements
- optionally a stapled Wasm verification component as an endorsement
TrustMee CMW verification returns a JSON output envelope documented in
TRUSTMEE_OUTPUT_EAT_PROFILE.md.
The TrustMee EAT payload carries:
component_idevidenceevidence_type
If the matching Wasm verification component is not stapled into the CMW, the host resolves it from:
- compiled-in placeholder OCI base:
oci://registry.example.com/trustmee/verifier-components - optional override:
--component-repository-hint - recommended deployment base:
oci://ghcr.io/<github-owner>/trustmee-verifier-components
cargo run -p wasm-verification-component -- \
--input <path-to-cmw-file> \
--component-repository-hint <oci-base> \
--component-trust-store <trust-store.json> \
--cache-dir <cache-dir> \
--compactWhen --component-trust-store is provided, the library verifies embedded verifier-component signatures with wasmsign2 before executing the component.
Trust store JSON:
{
"signers": [
{
"public_key": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n",
"fuel": -1,
"allow_network": true,
"valid_until": "2026-12-31T23:59:59Z"
}
]
}Notes:
public_keyaccepts PEM or OpenSSH text. Hex, base64, and base64url encodings of rawwasmsign2key bytes are accepted too.fuel = -1means unlimited Wasmtime fuel. Any other value must be a non-negative integer.valid_untilmust be an RFC3339 UTC timestamp for the trust-store signer entry.- Signed components must also carry embedded TrustMee signature expiry metadata. Use
wasm-verification-components'trustmee-component-signertool to add--signature-expires-atbefore signing withwasmsign2.
Execution policy:
- CMW verification is restrictive by default.
- An unsigned component runs with
1_000_000_000Wasmtime fuel and no outbound network access. - A signed component must verify against exactly one trusted, unexpired signer entry, and its embedded signature expiry metadata must be present and unexpired. The signer entry decides the
fuellimit and whether outbound network access is allowed. - If a signature is present but invalid, missing expiry metadata, expired, untrusted, or ambiguous, verification fails before the component is instantiated.
- Direct
verify_bytesandverify_pathscalls keep legacy behavior unless a trust store is explicitly supplied. - Result claim
verifier_component_sha256is computed over the original component bytes after stripping the embedded signature section and TrustMee signature-expiry metadata. When a signature is validated,verifier_component_signature_public_keycarries the trusted public key used for that validation. - CMW component cache identity still uses the exact
component_iddigest from the input, including embedded signature and expiry metadata.
The TrustMee wire format stays digest-based. The host maps that digest onto wasm_pkg_client package coordinates at fetch time:
- repository base:
oci://<registry>/<prefix...>/<namespace>/<package> - Wasm package ref:
<namespace>:<package> - OCI namespace prefix:
<prefix...>/when extra path segments are present before the final two segments - component version:
component_id = component-<sha256>maps to package version0.0.0-component.sha<sha256>
Examples:
oci://ghcr.io/acme/trustmee-verifier-components- package:
acme:trustmee-verifier-components - version for a component digest:
0.0.0-component.sha0123...
- package:
oci://ghcr.io/webassembly/acme/trustmee-verifier-components- package:
acme:trustmee-verifier-components - namespace prefix:
webassembly/
- package:
file:///tmp/local-registry/acme/trustmee-verifier-components- local backend root:
/tmp/local-registry - package:
acme:trustmee-verifier-components
- local backend root:
For public or shared verifier components, use GitHub Container Registry (ghcr.io):
- it is a standard OCI registry
- public packages can be pulled anonymously
wasm-pkg-toolsalready documents GHCR-backed Wasm package layouts- it fits the package mapping above without introducing TrustMee-specific registry requirements
For private internal deployments, use either private GHCR or a self-hosted OCI registry such as Harbor. The TrustMee client-side mapping stays the same.
- Choose a base such as
oci://ghcr.io/<github-owner>/trustmee-verifier-components. - Build the Wasm component and compute its TrustMee
component_id. - Convert that digest to the package version
0.0.0-component.sha<sha256>. - Publish the component to package
<github-owner>:trustmee-verifier-componentsat that version.
The simplest flow uses wkg from wasm-pkg-tools.
Example config at ~/.config/wasm-pkg/config.toml:
[registry."ghcr.io"]
type = "oci"
[registry."ghcr.io".oci]
auth = { username = "<github-username>", password = "<github-pat-with-write:packages>" }Example publish command:
wkg publish ./path/to/verifier_component.wasm \
--package <github-owner>:trustmee-verifier-components@0.0.0-component.sha<sha256> \
--registry ghcr.ioNotes:
- For private GHCR packages, readers need
read:packages. - In GitHub Actions, you can usually publish with
GITHUB_TOKENwhen the package is associated with the workflow repository. - If you publish programmatically, use
wasm_pkg_client::Client::publish_release_dataorpublish_release_filewith the same package/version mapping shown above.
JSON CMW records are encoded as:
{
"__cmwc_t": "https://trustmee.invalid/cmw/verification-input",
"evidence": [
"application/eat-ucs+json; eat_profile=\"https://trustmee.invalid/eat/component-evidence\"",
"<base64url(EAT JSON payload)>",
4
],
"verifier": [
"application/wasm",
"<base64url(wasm bytes)>",
2
],
"snp-collateral": [
"application/vnd.trustmee.snp-collateral+cbor",
"<base64url(CBOR collateral)>",
2
]
}The inner JSON EAT payload uses:
{
"eat_profile": "https://trustmee.invalid/eat/component-evidence",
"component_id": "component-<sha256-of-wasm-bytes>",
"evidence_type": "application/octet-stream",
"evidence": "<base64url(raw evidence bytes)>"
}CBOR CMW input is accepted too. The integration tests cover both JSON and CBOR variants.
The test_data/ directory includes sample verification components and evidence files for local testing:
test_data/tdx_verifier_component.wasmtest_data/snp_verifier_component.wasmtest_data/snp_verifier_host_crypto_component.wasmtest_data/tdx_quote.bintest_data/snp_evidence.json
Signed sample assets are available under test_data/signature-demo/:
test_data/signature-demo/snp_verifier_component.private.pemtest_data/signature-demo/snp_verifier_component.public.pemtest_data/signature-demo/snp_verifier_component.trust-store.jsontest_data/signature-demo/snp_verifier_component.signed.wasm
These files are for local testing only.
Run the ready-made manual test script:
./scripts/test_snp_signature_manual.shThe script checks:
- unsigned SNP component without a trust store succeeds
- signed SNP component with the sample trust store succeeds
- signed SNP component with an expired trust store fails
- signed SNP component without a trust store still succeeds in direct mode for compatibility
cargo test -p wasm-verification-component --test sample_library_usage -- --nocapture
cargo test -p wasm-verification-component --test cmw_input -- --nocapture