Agent Wallet Security
Best practices for securing Lightning wallet credentials in AI agent deployments.
Overview
AI agents that call paid APIs need access to a Lightning wallet for automatic L402 payments. This guide covers how to scope credentials, limit spending, and secure wallet access in production deployments.
Threat model
When an agent has wallet access, the following risks apply:
| Threat | Impact | Mitigation |
|---|---|---|
| Runaway spending | Agent pays large/many invoices unintentionally | Budget limits, per-request caps |
| Credential leak | Wallet secrets in env vars exposed via logs, error messages, or config files | Scoped credentials, secret management |
| Malicious API | An API charges more than expected | max_cost_sats, invoice amount verification |
| Replay/reuse | Stolen L402 tokens used to access APIs | L402 tokens are consumed on first use; session-based models issue a scoped session token after payment |
Spending controls
Session budget
Set BUDGET_SATS to cap total spending per MCP session (session = lifetime of the MCP server process, typically one Cursor/Claude Desktop window):
{
"mcpServers": {
"bolthub": {
"command": "npx",
"args": ["@bolthub/mcp-registry"],
"env": {
"LND_REST_HOST": "https://your-lnd-node:8080",
"LND_MACAROON": "<hex-pay-macaroon>",
"BUDGET_SATS": "1000"
}
}
}
}| Budget | Use case |
|---|---|
| 100-500 | Testing and exploration |
| 1,000-5,000 | Daily development |
| 10,000+ | Production / heavy use |
When the budget is exhausted, call_api returns an error instead of paying.
Per-request cap
Use max_cost_sats on individual call_api calls to refuse invoices above a threshold:
call_api({ slug: "expensive-api", path: "/v1/data", max_cost_sats: 50 })The underlying L402Client also supports maxPerRequestSats as a constructor option for a global per-call limit.
Cost preview
Use preview_cost before calling to check pricing without paying:
preview_cost({ slug: "my-api", path: "/v1/endpoint" })Wallet credential scoping
LND macaroons
If using LND (including a node from the bolthub Node Launcher), never use admin.macaroon in agent deployments. Bake a scoped macaroon with only the permissions the agent needs:
| Role | Permissions | Use case |
|---|---|---|
| Pay-only | SendPaymentSync, DecodePayReq, GetInfo | Agent paying for L402 APIs |
| Invoice-only | AddInvoice, LookupInvoice, GetInfo | API provider generating invoices |
| Read-only | GetInfo, balances, list operations | Monitoring / dashboards |
Bake a pay-only macaroon:
lncli bakemacaroon uri:/lnrpc.Lightning/SendPaymentSync \
uri:/lnrpc.Lightning/DecodePayReq \
--save_to=pay-only.macaroonThis creates a macaroon that can only pay invoices and decode payment requests; it cannot create invoices, manage channels, or access funds.
For additional safety, add caveats to constrain spending:
lncli constrainmacaroon \
--macaroon_path=pay-only.macaroon \
--caveat="max_send_amount=1000"For advanced setups (e.g. separating key management from payment routing), consider a watch-only + remote signer architecture where the agent machine holds no private keys. See the Lightning Agent Tools security docs for a detailed walkthrough of this pattern.
NWC (Nostr Wallet Connect)
NWC is the easiest wallet type to scope. Most NWC wallets let you create connection strings with limited permissions:
- Alby Hub: Create a new app connection with a spending limit (e.g., 10,000 sats/day). The connection string only has
pay_invoicepermission. - CoinOS: Create an NWC connection with a daily/monthly budget cap.
- Phoenix: NWC connections can be time-limited or budget-limited.
Recommendation: Create a dedicated NWC connection per agent/project with a daily budget that matches expected usage.
Phoenixd
Phoenixd uses a simple HTTP password. There is no credential scoping, so the password grants full access. Mitigate this by:
- Running a dedicated Phoenixd instance for agent payments with limited funds
- Setting
BUDGET_SATSin the MCP config - Monitoring spending via the Phoenixd HTTP API
Prefer LND with a pay-only macaroon when you are choosing a new setup.
LNbits
LNbits supports multiple wallets per instance. Create a dedicated wallet for the agent:
- Create a new wallet in LNbits
- Fund it with only the amount you're comfortable letting the agent spend
- Use that wallet's admin key as
LNBITS_ADMIN_KEY
When the wallet runs dry, the agent can't pay. Top it up as needed.
Environment variable security
Do not commit secrets
Never commit wallet credentials to version control. Use .env files (added to .gitignore) or a secret manager.
# .gitignore
.env
.env.local
.env.*.localUse project-scoped MCP config
For team projects, use .cursor/mcp.json with placeholder values and document the required env vars separately:
{
"mcpServers": {
"bolthub": {
"command": "npx",
"args": ["@bolthub/mcp-registry"],
"env": {
"NWC_URI": "${NWC_URI}",
"BUDGET_SATS": "1000"
}
}
}
}Secret management in production
For production agent deployments:
- Docker/K8s: Use Docker secrets or Kubernetes secrets, not env vars in compose files
- Cloud: Use the platform's secret manager (AWS Secrets Manager, GCP Secret Manager, Fly.io secrets)
- CI/CD: Use pipeline secrets, not hardcoded values
Monitoring
Track spending
The MCP tools report spending after each call:
Cost: 5 sats
Session spending: 45 sats | Remaining budget: 955 satsWatch for anomalies
Set up alerts for:
- Spending rate exceeding normal patterns
- Budget exhaustion (the agent reports errors instead of paying)
- Unusual API call patterns (many calls to expensive endpoints)
Wallet balance monitoring
Monitor your Lightning wallet balance. If using LND or Phoenixd, set up balance alerts:
# LND balance check
lncli walletbalance
# Phoenixd balance check (if you use Phoenixd for agent payments)
curl -u :<password> https://your-phoenixd/getbalanceProduction checklist
- Dedicated wallet/connection for agent use (not your primary wallet)
- Scoped credentials (LND pay-only macaroon, NWC with budget, or LNbits sub-wallet)
-
BUDGET_SATSset to a reasonable session limit - Wallet secrets stored in a secret manager, not in code or config files
-
.envfiles in.gitignore - Monitoring for spending anomalies
- Wallet funded with only the amount you're comfortable losing
- Regular credential rotation (especially for long-running deployments)