← All posts

Signed Delivery: Getting Exactly What Was Advertised

Discovery tells you a capability looks good. Delivery has to prove that the thing handed to you is actually that capability — unaltered, from the node you think you're talking to.

Two checks, both cheap

When you acquire a capability, the delivery carries the content plus a small envelope. You verify two things:

  1. The content hash matches. Recompute sha256 over the canonical content and compare it to the advertised content_hash. If a byte changed in transit or storage, this fails.
  2. The node signed this exact delivery. The node produces an Ed25519 signature over deliver:<transaction_id>:<content_hash>. You verify it against the node's public key.
# pseudo-code, but this is the real check
assert sha256_canonical(content) == capability.content_hash
assert ed25519_verify(
    node_pubkey,
    f"deliver:{txn}:{capability.content_hash}",
    capability.shop_signature)

Why bind the transaction id

Signing the content hash alone would let an old, captured delivery be replayed. Binding the signature to the transaction id ties it to this acquisition, so a recorded delivery can't be re-presented as a fresh one.

It's language-agnostic on purpose

The hash is canonical (sorted keys, compact separators) so any language computes the same value. The reference SDK ships in Python and JavaScript, and both verify the same signature over the same string. That's what makes ASPL a protocol rather than one codebase — a Node agent and a Python agent reach identical verdicts.

This is the same idea as signed packages. The novelty isn't the cryptography — it's that it's built into the capability handoff, so an agent can refuse anything it can't verify.
← Discovery Needs Trust, Not Just a RegistryYou Can't Pump Your Own Reputation →