LedgerLighthouse

A spending policy an AI agent cannot talk its way past.

An agent that pays for things has to read text written by the people it pays. Put reading and spending in one component and a single prompt injection empties the budget. LedgerLighthouse splits them: the part that reads the attacker's text holds no spending authority, and the part that grants it never reads the attacker's text.

Project
Highlights

Six decisions that carry the design.

Open the dashboard
The invariant

Compromise of the AI orchestrator must not confer spending authority

The orchestrator reads 402 bodies, error messages and vendor descriptions, all attacker-controlled. It can ask for a spend. It cannot grant one. The relay holds no key and the signer never reads a word of vendor text.

  • Reads attacker textOrchestrator, no authority
  • Grants authorityPolicyVault + signer
01

Write-ahead debit: the money moves before anyone knows the answer

Inco forbids branching on an encrypted condition, so if (approved) debit cannot be written. The vault selects the operand instead, ok.select(amount, 0), and subtracts unconditionally. The debit commits before anyone, the orchestrator included, can learn whether it was approved.

Built on
Inco Lightning Solidity euint256
02

Handle-bound attestation, checked inside the contract

finalizeDecision verifies the decryption attestation against the handle the vault itself stored. A genuine attestation over a different handle is refused, so a valid signature alone is not enough to approve a spend.

  • Checke.verifyDecryption
  • Bound toThe stored decision handle
03

A signer that accepts no terms

The signer answers one question: is (goalId, seq) finalized and approved on chain? If so it signs exactly what the chain froze, as an EIP-3009 authorization. It has no notion of price and no way to be told one, and its key lives in an Intel TDX enclave on Oasis ROFL.

Built on
EIP-3009 Oasis ROFL Intel TDX
04

A loss ceiling you can state in one line

Even a fully compromised orchestrator is bounded by the per-call cap, the payee allowlist and the call counter. The cap is encrypted, so nobody can aim at it, and each payer is bound to one goal so it holds only what that goal was funded with.

  • Loss ceilingperCallCap × callsRemaining
  • Paid only toAn allowlisted payee
05

Payments over x402, tested against an adversary

The agent buys API calls the way the web is starting to sell them: a 402 response, a USDC authorization, a facilitator that settles it. An adversary campaign of thirteen attacks runs against the live vault, and every run is logged with its transaction hashes.

  • NetworkBase Sepolia · 84532
  • Tests368 passing
  • SettlementUSDC via x402 v1

How one payment flows

Run it yourself
  1. 1402 receivedThe vendor names a price and a payee. Untrusted.
  2. 2Structured summaryThe agent turns prose into amount, payee and resource.
  3. 3requestSpendThe debit is committed before the decision exists.
  4. 4Confidential evaluationBudget, cap and allowlist checked on encrypted values.
  5. 5RevealInco reveals one bit, approve or reject, with an attestation.
  6. 6finalizeDecisionThe contract checks the attestation against its own handle.
  7. 7Authorization signedThe enclave signs what the chain froze, nothing else.
  8. 8SettlementThe facilitator submits the EIP-3009 transfer.
  9. 9Resource returnedThe vendor serves the call that was paid for.

What is proven, and what is assumed

  • The debit was committed before the decision was knowableOn chain
  • The attestation verified against the handle the vault storedOn chain
  • The signature was released only against a finalized approvalAuditable code
  • The budget stayed confidentialVendor assumption
  • The payer key never left the enclaveVendor assumption
  • The agent behaved correctlyNot claimed