When an agent makes a purchase, executes a payment, or commits to a contract, there is no portable proof that a human authorized it. The agent might have a token, but tokens are bearer instruments. They don't prove intent. They prove possession.
This is the gap Treeship closes: cryptographic proof of human approval, bound to a specific action, verifiable by anyone.
The approval receipt with nonce binding
The core primitive is simple. A human issues an approval. The approval contains a binding nonce and a signed scope (allowed_actor, allowed_action, allowed_subject, max_uses). When the agent acts, the action receipt echoes the nonce. The verifier checks the binding, the scope, and the replay posture as three separate properties.
Step 1: Human issues a scoped approval
treeship attest approval \
--approver human://alice \
--description "approve payment to acme-corp max $500" \
--allowed-actor agent://payments \
--allowed-action stripe.charge.create \
--allowed-subject vendor://acme-corp \
--max-uses 1This creates a signed approval artifact with a binding nonce and the signed scope. --max-uses is signed into the grant for ledger enforcement (v0.10 / v0.11+); v0.9.6 enforces actor / action / subject statelessly and observes nonce replay package-locally.
Step 2: Agent executes the payment with the nonce
treeship wrap \
--approval-nonce abc123def456 \
-- stripe charges create \
--amount 49900 \
--currency usd \
--customer cus_acmeThe wrap command runs the payment command, captures its output, and produces a signed action receipt. That receipt includes the approval nonce, binding it to the specific approval from Step 1.
Step 3: Anyone verifies the chain
treeship verify --fullThe verification checks (and reports each independently):
- The approval signature is valid (Ed25519)
- The action signature is valid
- Binding: the nonce in the action matches the nonce in the approval
- Scope: the action's actor / action / subject fall inside the approval's signed allow-lists; expiry not past
- Replay: the nonce has not been consumed earlier in this verified package (cross-package and cross-machine enforcement land via local Approval Use Journal in v0.10 and Hub checkpoints in v0.11+; verify reports today's posture as
package-local only -- no global ledger consulted)
Why this matters for commerce
Compliance. Every financial action has a provable human authorization. Not "the agent had an API key" but "Alice approved this specific payment at this specific time."
Dispute resolution. The receipt chain is the evidence. It is signed, timestamped, and tamper-evident. If a vendor disputes a charge, the buyer's agent can present the chain: approval, intent, execution, confirmation.
Cross-org trust. A vendor can verify the buyer's agent had approval without trusting the buyer's infrastructure. The receipts are self-contained. Verification happens client-side, offline, with no callback to the buyer's systems.
How the nonce constrains replay
Without the nonce, an agent could pass any approval as authorization for any action. The nonce binds approval ↔ action cryptographically: the action receipt must echo the exact nonce of the signed approval, and the verifier checks it.
That binding is the foundation. Replay enforcement layers on top:
- v0.9.6 (today): if two actions inside one verified package claim the same nonce, the second fails. Verify reports
replay check: package-local only -- no global ledger consulted. - v0.10: a local Approval Use Journal — append-only, hash-chained, with signed Merkle checkpoints — extends the check across all actions seen on a device or workspace.
- v0.11+: Hub-backed checkpoints extend it across machines and teams.
# Today: this fails when verified together with the first use
treeship wrap \
--approval-nonce abc123def456 \
-- stripe charges create \
--amount 99900 \
--currency usd \
--customer cus_other
# verify error: nonce already consumed by art_... in this package (package-local replay)
# Cross-package replay (e.g. running the same nonce in a different
# workspace on the same machine) starts failing in v0.10 once the
# local Approval Use Journal lands.The signed scope (--allowed-actor / --allowed-action / --allowed-subject / --max-uses) is the layer that prevents the same nonce from authorizing a different action even before the journal lands — and that part is enforced statelessly today.
What Treeship does not do
Treeship does not move money. It does not hold funds, manage wallets, or process payments. It produces and verifies receipts. The payment infrastructure (Stripe, Lobster.cash, bank APIs) handles the money. Treeship proves what happened and who approved it.
This separation is deliberate. Trust infrastructure and payment infrastructure have different failure modes, different security models, and different regulatory surfaces. Keeping them separate makes both more auditable.