Tenor supports cryptographic signing of interchange bundles and WASM evaluator binaries. Signing establishes a chain of trust: the contract author signs the bundle, and the runtime verifies the signature before evaluation.
Ed25519 Signing
Tenor uses Ed25519 for all cryptographic signatures. Ed25519 is fast, deterministic, and widely supported.
Generate a Keypair
Generate a new Ed25519 keypair:
tenor keygenThis produces two files:
tenor-secret.key— the private signing key (keep this secret)tenor-public.key— the public verification key (distribute this)
You can specify output paths:
tenor keygen --secret-key ./keys/signing.key --public-key ./keys/verify.keySign a Bundle
Sign an elaborated interchange bundle:
tenor sign contract.json --key tenor-secret.keyThis produces a signed bundle (contract.signed.json) that includes the original interchange JSON plus a detached Ed25519 signature. The signature covers the entire interchange content — any modification invalidates it.
Verify a Bundle
Verify a signed bundle:
tenor verify contract.signed.jsonThe verify command checks:
- The signature is valid Ed25519 over the interchange content
- The interchange JSON passes schema validation
- The bundle has not been modified since signing
If verification fails, the command exits with a non-zero code and prints the failure reason.
WASM Evaluator Signing
The Tenor evaluator can run as a WASM module (in browsers, edge runtimes, or sandboxed environments). WASM binaries can also be signed to establish that the evaluator itself is authentic:
tenor sign-wasm evaluator.wasm --key tenor-secret.key --bundle-etag ETAGThe --bundle-etag parameter binds the WASM signature to a specific interchange bundle version. This ensures the evaluator binary and the contract it's evaluating are a matched pair.
Verify a signed WASM binary:
tenor verify-wasm evaluator.wasm --sig evaluator.wasm.sig --pubkey tenor-public.keyTrust Obligations
The Tenor specification defines three trust obligations (E18-E20) for runtime implementations:
E18: Bundle Integrity
The runtime must verify that the interchange bundle has not been modified since elaboration. If a signature is present, it must be verified. If no signature is present, the runtime must indicate that the bundle is unsigned.
E19: Evaluator Authenticity
When using a WASM evaluator, the runtime must verify the WASM signature against a known public key. This prevents substitution of a modified evaluator that might produce incorrect verdicts or action spaces.
E20: Provenance Chain
Every verdict and every state transition must record sufficient metadata to reconstruct the decision chain. The provenance record must be cryptographically bound to the bundle that produced it — proving that this specific contract version, evaluated against these specific facts, produced this specific outcome.
Key Management Best Practices
- Store secret keys in a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.). Never commit secret keys to version control.
- Rotate keys regularly. Generate new keypairs on a schedule. Old signatures remain valid — they were signed with the key that was current at the time.
- Use different keys for different environments. Production, staging, and development should have separate keypairs.
- Include the public key in your TenorManifest. This allows automated verification without out-of-band key exchange.