Enforcement

Payment Firewall

The verdict layer answers should this happen?The Payment Firewall makes the answer binding: an agent cannot move money unless Fidacy authorized the payment against a signed mandate and issued a short-lived grant the executor verifies first. Every decision is written to a hash-chained, append-only audit, and the head of that chain is anchored to Bitcoin, so no party, including Fidacy, can rewrite history after the fact. It installs as one MCP server, with no change to the agent's code.

How it works

The firewall sits between the agent and the money. A payment runs through four steps, and money only moves if all four pass:

  • ·Authorize. The agent calls request_payment. The firewall evaluates the request against the active, signed mandate for that subject (per-transaction cap, payee allowlist, category, window, cumulative spend) in a single locked transaction.
  • ·Grant. On ALLOW the firewall issues a short-lived Ed25519 grant that binds the subject, payee, amount, and currency. On DENY no grant is issued, so the executor has nothing to present.
  • ·Execute. The agent calls execute_payment. The executor verifies the grant against Fidacy's public key before it touches the payment rail. No valid grant, no settlement.
  • ·Record. Every decision, ALLOW or DENY, is appended to a hash-chained audit and later anchored to Bitcoin.
The agent cannot talk past it. A prompt-injected or hijacked agent controls what it intends, but it does not hold Fidacy's private key. Without a valid grant the executor refuses to move money, and any grant it did not issue is a forgery the executor rejects.

Install: one MCP server

The firewall ships as @fidacy/mcp. One install gives an agent both the signed verdict (assess_action) and the payment firewall, with no code change. Point it at the live core in HTTP mode:

{
  "mcpServers": {
    "fidacy-firewall": {
      "command": "npx",
      "args": ["-y", "@fidacy/mcp"],
      "env": {
        "FIDACY_MODE": "http",
        "FIDACY_API_URL": "https://fidacy-core.vercel.app",
        "FIDACY_API_KEY": "fk_live_…"
      }
    }
  }
}
ToolWhat it does
request_paymentAuthorize a payment against the signed mandate. Returns ALLOW + a grant, or DENY + the rule that blocked it.
execute_paymentSettle a payment only after verifying the grant against Fidacy's public key. The template you couple to your PSP.
verify_mandateRead the active mandate for a subject.
get_audit_proofFetch the hash-chained audit record for a decision, with a chain-integrity check.

Duplicate-invoice fraud (BEC), closed at the firewall

Business email compromise turns on paying the same invoice twice, or re-presenting an invoice for a larger amount. Pass an invoiceRef with the payment and the firewall enforces one payment per invoice: a second authorization for the same invoice, at any amount and with any idempotency key, is DENY duplicate_invoice. The grant binds the invoice, so the executor also refuses a settlement whose invoice differs.

This is enforced by Fidacy, not by the payment processor and not by the integrator's idempotency-key discipline. Caps protect the budget; the invoice lock stops re-presentation. Together they close the hole BEC exploits.

Tamper-evident audit

Every decision is written to an append-only log where each record hashes the previous record's hash, this decision's digest, and its timestamp. Editing any record breaks every hash after it, so a retroactive change is detectable by recomputing the chain. get_audit_proof returns the record plus a chainIntactflag, and the same check runs client-side against Fidacy's public key, with no account.

Anchored to Bitcoin

A hash chain proves no record was edited without detection. But the party that signs the chain holds the keys and could, in principle, regenerate the whole chain from scratch. To close that, Fidacy commits the head of the chain to Bitcoin, a public ledger no single party controls.

  • ·Audit records are batched into a Merkle tree (RFC 6962) and the root is stamped to Bitcoin via OpenTimestamps.
  • ·A standalone verifier recomputes the inclusion proof and checks the Bitcoin attestation, trusting neither Fidacy nor the calendar servers, only the blockchain and the math.
  • ·Once confirmed, a record provably existed at or before a specific Bitcoin block, inside a mandate-bound, signed chain that no party, including Fidacy, can have regenerated afterward.
  • ·These are standard, audited primitives, not a homegrown scheme: the RFC 6962 Merkle tree is the same construction behind Certificate Transparency, and OpenTimestamps + Bitcoin do the anchoring. Nothing bespoke to trust.
GET/v1/anchor/latest
Not "immutable." The chain is tamper-evident, Merkle-batched, and anchored to Bitcoin. A freshly anchored batch is pending until Bitcoin confirms it, which takes about an hour. Once confirmed, the proof is practically irreversible: rewriting it would mean rewriting Bitcoin.

See it yourself

The /proofpage runs a real payment through the live firewall with no account, then lets you verify the Ed25519 grant and the hash-chained audit in your own browser, tamper with a field to watch the signature and the chain break, and follow the chain head's journey onto Bitcoin in four stages. Don't trust us; try to forge it.