@emilia-protocol/require-receipt
v0.1.0
Published
Demand a verifiable EMILIA Trust Receipt for any irreversible agent action. The one-line way for a service to require portable, accountable authorization — not auth, not permissions. Answers 402 and tells the agent exactly what to bring.
Downloads
93
Maintainers
Readme
@emilia-protocol/require-receipt
The demand side of the EMILIA network. One line that lets any service refuse an irreversible agent action unless it arrives with a verifiable Trust Receipt — proof that a named human accountably authorized this exact action.
This is not auth ("who are you") and not permissions ("are you allowed here"). It's portable accountability evidence the service keeps for its own liability — and the thing that makes agents adopt EMILIA on their own.
npm install @emilia-protocol/require-receiptRequire a receipt (Express / Connect / Next route handler)
import { requireEmiliaReceipt } from '@emilia-protocol/require-receipt';
app.post(
'/release-payment',
requireEmiliaReceipt({
trustedKeys: [process.env.EMILIA_ISSUER_PUBKEY], // base64url SPKI you trust
action: 'payment.release',
maxAgeSec: 900,
}),
(req, res) => {
// Only reached if a fresh, untampered, action-bound receipt from a trusted
// issuer was presented. req.emiliaReceipt holds the verified claim.
res.json({ released: true, receipt: req.emiliaReceipt.receipt_id });
},
);The 402 passport loop (why agents self-adopt)
No receipt? The service answers 402 and tells the agent exactly what to bring —
so a well-behaved agent obtains one and retries, no human needed. Like a browser
handling 401.
→ POST /release-payment (no receipt)
← 402 EMILIA Receipt Required
WWW-Authenticate: EMILIA realm="agent-actions", action="payment.release"
{ required: { action: "payment.release", header: "X-EMILIA-Receipt: base64(...)", how: "..." } }
→ POST /release-payment X-EMILIA-Receipt: base64(<receipt>)
← 200 { released: true }402 deliberately aligns with the emerging "challenge-to-transact" convention for
agent commerce (x402 / AP2) — receipts ride the same rail payments do.
Just verify (no framework)
import { verifyEmiliaReceipt } from '@emilia-protocol/require-receipt';
const v = verifyEmiliaReceipt(receiptDoc, {
trustedKeys: [issuerPubKey],
action: 'payment.release',
maxAgeSec: 900,
});
// { ok, reason?, outcome?, subject?, receipt_id?, signer? }Offline Ed25519 over canonical JSON — same shape as
@emilia-protocol/verify.
No network. You pin the issuers you trust.
Why this is the moat, not the gate
A guardrail blocks your agent (a cost). A required receipt makes every counterparty demand portable proof — and the more that demand it, the less choice any agent has but to issue one. EMILIA becomes the issuer and verifier of record for accountable agent action. See /agent-guard.
Apache-2.0 · part of EMILIA Protocol
