Security & Attestation
LedgerOS is designed for AI agents that spend real money. This guide covers the security model that makes this safe.The Problem with AI + Payments
When AI agents can spend money, you need answers to:- What did the agent claim it was doing? (audit trail)
- Did the transaction match the claim? (verification)
- Who accessed the card credentials? (accountability)
- Can we limit blast radius? (controls)
Attestation Model
LedgerOS uses an attestation-before-access model. Before retrieving card credentials, your agent must attest what it intends to do with the card. This creates an audit trail and enables automatic policy enforcement.Retrieving Credentials
Request credentials by providing an attestation:accessEventId links this credential access to your attestation for audit purposes.
Credential Exposure Modes
When creating a card, you can control credential access:| Mode | Description |
|---|---|
rawPan (default) | Returns full credentials in API response |
never | Credentials cannot be retrieved at all |
Attestation Payload
The attestation payload describes the intended use:| Field | Type | Required | Description |
|---|---|---|---|
summary | string | Yes | Human-readable description of intent |
expectedAmount | number | No | Expected transaction amount in cents |
expectedCurrency | string | No | Currency code (default: USD) |
merchantText | string | No | Expected merchant name |
reason | string | No | one-time, subscription, preauth |
clientContext | object | No | Custom metadata for your records |
Transaction Correlation
When a transaction occurs, it’s automatically correlated with recent credential access events:| Status | Meaning |
|---|---|
attested | Credential access found within the attestation window |
unattested | No recent credential access found |
stale | Credential access found but outside the window |
attestationWindowMinutes when creating the card (1-60 minutes).
Rate Limits
- Maximum 10 credential retrievals per hour per card
Layered Security Model
LedgerOS provides multiple layers of protection:| Layer | What it does | Example |
|---|---|---|
| Attestation | Records what agent claimed | ”Ordering lunch on DoorDash for $25” |
| Intents | Matches transactions to claims | Transaction $24.50 at DoorDash → matched |
| Merchant-locking | Restricts where card works | Card locked to DoorDash, declined at Amazon |
| Spending limits | Caps total spend | Agent limited to $500/month |
| Time controls | Restricts when card works | Only active 9am-5pm weekdays |
- Locks to first merchant (DoorDash)
- Max 500/month (via
limitsobject) - Requires attestation before each use
- Only works 11am-2pm Mon-Fri Eastern
Best Practices
Always provide detailed attestations
Always provide detailed attestations
Include expected amount, merchant, and reason. This helps with audit trails and fraud detection.
Secure your API keys
Secure your API keys
Never expose API keys in client-side code. All credential access should happen server-side.
Monitor unattested transactions
Monitor unattested transactions
Set up webhook handlers for
spend.unattested events to detect anomalies.Use credentialExposure: never for hosted checkouts
Use credentialExposure: never for hosted checkouts
If users complete checkout on a hosted payment page, disable credential access entirely.
Use single-use cards for unknown merchants
Use single-use cards for unknown merchants
When an agent needs to buy from a new merchant, use a single-use card that auto-closes after the transaction.
Set up alerts for mismatched intents
Set up alerts for mismatched intents
Subscribe to
intent.mismatched webhooks to catch when transactions deviate significantly from declared intent.