AI Spending Security
When using the pay_invoice tool, you are authorizing an AI agent to spend Bitcoin on your behalf. This document covers the security considerations, mandatory safeguards, and best practices for safe AI-driven spending.
Understanding pay_invoice vs L402
| Aspect | L402 (access_l402_resource) | pay_invoice |
|---|---|---|
| Direction | You RECEIVE payments | You SPEND payments |
| Risk Level | Low (inbound funds) | High (outbound funds) |
| Use Case | Monetize your APIs | Pay for external APIs |
| Safeguards Needed | None (you're receiving) | Budget limits required |
Key Distinction: L402 is about receiving payments for your content/APIs. The pay_invoice tool is about spending your Bitcoin to pay for external services.
Risk Model
What Can Go Wrong
-
Unintended Payments
- AI misinterprets user intent and pays wrong invoice
- AI pays more than expected for a service
- AI makes multiple payments when one was intended
-
Malicious Prompt Injection
- Attacker injects payment request into AI context
- Phishing-style invoices embedded in content AI reads
- Social engineering via prompts
-
API Key Compromise
- OpenNode API key with withdrawal permissions stolen
- Key exposed in logs, environment dumps, or screenshots
- Key committed to version control
-
Budget Bypass Attempts
- Attackers try to make payments just under limit
- Multiple small payments to drain session budget
- Exploiting timing between budget check and payment
Mandatory Safeguards
1. Dedicated Spending Wallet
NEVER use your main wallet or business funds.
Create a dedicated wallet specifically for AI spending:
Main Wallet (Your Business)
├── Receives customer payments
├── Large balance
└── NEVER used for AI spending
AI Spending Wallet (Separate)
├── Only used by AI agents
├── Small balance (< $100 equivalent)
└── Easy to monitor and refill
Supported wallets:
- OpenNode - Full L402 support (returns preimage)
- Strike - Direct payments only (no L402, no preimage)
- NWC (Alby, CoinOS) - Full L402 support (returns preimage)
- NWC (Primal) - Direct payments only (no preimage support yet)
L402 auto-pay requires preimage. These wallets work:
- OpenNode - Most reliable
- Alby (NWC) - Self-custody option (requires hosting)
- CoinOS (NWC) - Free, web-based
Primal does NOT work for L402 - it doesn't return preimages yet.
Why: If something goes wrong, you only lose what's in the dedicated account.
2. Multi-Tier Approval System (AI-Proof)
Lightning Enable uses a USD-based multi-tier approval system that AI agents cannot bypass or modify. Configuration is stored in a file that only you can edit.
Configuration File Location
~/.lightning-enable/config.json
On Windows: C:\Users\YourName\.lightning-enable\config.json
Important: AI agents have NO ability to modify this file. Budget limits can only be changed by you editing the file directly.
Default Configuration
On first run, a default config file is created:
{
"currency": "USD",
"tiers": {
"autoApprove": 1.00,
"logAndApprove": 5.00,
"formConfirm": 25.00,
"urlConfirm": 100.00
},
"limits": {
"maxPerPayment": 500.00,
"maxPerSession": 100.00
},
"session": {
"cooldownSeconds": 2,
"requireApprovalForFirstPayment": false
}
}
Default thresholds were raised in January 2025 because most MCP clients (including Claude Code) don't yet support MCP elicitation for in-band confirmations. The higher defaults provide better UX while keeping reasonable limits.
How Each Tier Works
| Amount (USD) | Tier | Behavior |
|---|---|---|
| ≤ $1.00 | Auto-Approve | Payment proceeds without any notification |
| $1.00 - $5.00 | Log & Approve | Payment proceeds, logged for your review |
| $5.00 - $25.00 | Form Confirm | Requires confirmation (see below) |
| $25.00 - $100.00 | URL Confirm | Requires explicit confirmation with amount verification |
| > $500.00 | Deny | Payment blocked entirely |
MCP Elicitation Limitation
Important: Most MCP clients (including Claude Code as of January 2025) do NOT support MCP elicitation. This means in-band confirmation prompts cannot be displayed.
How confirmation works without elicitation:
When a payment requires confirmation and elicitation is unavailable, the tool returns a special response:
{
"success": false,
"requiresConfirmation": true,
"error": "Payment requires your confirmation",
"message": "This payment of $5.00 (5,000 sats) exceeds the auto-approve threshold. To proceed, call pay_invoice again with confirmed=true.",
"howToConfirm": "Call: pay_invoice(invoice=\"...\", confirmed=true)",
"amount": { "sats": 5000, "usd": 5.00 }
}
To approve the payment, you must explicitly tell the AI to call the tool again with confirmed=true:
"Please confirm that payment by calling pay_invoice with confirmed=true"
This ensures you always have control over payments above your auto-approve threshold, even without MCP elicitation support.
Why This Is AI-Proof
- File-Based Configuration - The config lives in your home directory, not in environment variables that could be exposed
- No Runtime Modification - There is no MCP tool to change budget limits
- Human Verification for Large Payments - Amount typing confirmation prevents AI from approving its own payments
- First Payment Protection - First payment of every session requires explicit approval
- Cooldown Periods - Prevents rapid-fire payment attacks
Customizing Your Limits
Edit ~/.lightning-enable/config.json:
{
"currency": "USD",
"tiers": {
"autoApprove": 0.50, // More restrictive: only auto-approve $0.50
"logAndApprove": 2.00, // Log anything above $2.00
"formConfirm": 10.00, // Require confirmation above $10
"urlConfirm": 50.00 // Require amount verification above $50
},
"limits": {
"maxPerPayment": 100.00, // Never pay more than $100 in one payment
"maxPerSession": 50.00 // Never spend more than $50 per session
},
"session": {
"cooldownSeconds": 2,
"requireApprovalForFirstPayment": false
}
}
If you want to require confirmation for ALL payments, set autoApprove to 0. Every payment will then return requiresConfirmation=true and you'll need to explicitly approve each one.
Checking Your Budget Status
Use the get_budget_status tool (read-only) to see current configuration:
get_budget_status
Response:
{
"success": true,
"message": "Budget configuration is READ-ONLY. Edit ~/.lightning-enable/config.json to change limits.",
"tiers": {
"autoApproveUsd": 0.10,
"formConfirmUsd": 10.00,
...
},
"session": {
"spentUsd": 0.45,
"remainingUsd": 99.55
},
"security": {
"aiCanModify": false,
"howToChange": "Edit the config.json file directly. AI agents cannot modify budget limits."
}
}
3. Legacy Environment Variable Limits
For backward compatibility, environment variables still work but config file takes precedence:
# Legacy environment variables (config.json overrides these)
L402_MAX_SATS_PER_REQUEST=100 # Max per single payment
L402_MAX_SATS_PER_SESSION=1000 # Max total per session
Recommended: Use the config file instead - it's more secure and supports USD amounts.
3. API Key Permissions
When creating your OpenNode API key for AI spending:
- Use withdrawal-only permissions if available
- Create a dedicated key - don't reuse keys
- Rotate keys regularly (monthly recommended)
- Never commit keys to version control
- Never share keys in screenshots or logs
# MCP Configuration - store key securely
export OPENNODE_API_KEY="your-key-here"
export OPENNODE_ENVIRONMENT="production"
4. Monitoring and Auditing
Review payments after every AI session:
# Use the MCP tool to check payment history
get_payment_history limit=20
Set up monitoring:
- Enable OpenNode email notifications for withdrawals
- Review weekly spending totals
- Set up balance alerts (notify when balance drops below X)
- Check for unexpected payment patterns
Environment Variable Checklist
Before using pay_invoice, verify these are configured:
| Variable | Purpose | Recommended Value |
|---|---|---|
OPENNODE_API_KEY | API authentication | Withdrawal-only key from dedicated account |
OPENNODE_ENVIRONMENT | Network selection | production for mainnet |
L402_MAX_SATS_PER_REQUEST | Per-payment cap | 100-500 sats |
L402_MAX_SATS_PER_SESSION | Session total cap | 1,000-5,000 sats |
What pay_invoice Should NOT Be Used For
Do NOT use pay_invoice if:
- Your wallet balance exceeds
100,000 sats ($100 at 100k sats/$) - You're using production/business funds
- The AI will run unattended for long periods
- You haven't configured budget limits
- You're using a shared or untrusted MCP configuration
- You haven't reviewed the AI agent's capabilities
Recommended for:
- Developer testing and prototyping
- Light interactive use with supervision
- Small, bounded research tasks
- Learning and experimentation
Architecture: We Never Touch Funds
Lightning Enable is API middleware - OpenNode facilitates custody and settlement:
Your Wallet (OpenNode) Lightning Enable MCP Recipient
│ │ │
│ ◄─── You control ───► │ ◄─── Software ───► │
│ │ │
▼ ▼ ▼
OpenNode custody Just a tool Receives
Your account API middleware payment
Your responsibility No access to funds
Key points:
- Lightning Enable is software infrastructure (API middleware)
- You provide your own OpenNode API key (BYOA model)
- OpenNode holds your funds (they are licensed and regulated)
- We never see, touch, or control your Bitcoin
- All compliance/KYB is between you and OpenNode
Incident Response
If you suspect unauthorized payments:
- Immediately rotate your OpenNode API key
- Check payment history in OpenNode dashboard
- Review what invoices were paid
- Update MCP configuration with new key
- Lower budget limits
- Investigate how the key may have been compromised
Security Recommendations Summary
| Priority | Action |
|---|---|
| Critical | Use dedicated wallet with limited funds |
| Critical | Configure budget limits BEFORE first use |
| High | Use withdrawal-only API key |
| High | Review payment history after sessions |
| Medium | Rotate API keys monthly |
| Medium | Set up balance alerts |
| Low | Log and audit all AI sessions |
Related Documentation
- Spending Guidelines - Recommended budgets by use case
- Legal Considerations - Liability and terms
- AI Agent Integration - MCP setup guide