AgentPay MCP

August 16, 2026 · View on GitHub

Last updated: 2026-08-16

This document maps AgentPay MCP's security controls to the CoSAI (Coalition for Secure AI) threat taxonomy and MCP 2026 authentication requirements. It is intended for enterprise security teams evaluating MCP servers for production deployment.

Correction (2026-08-16): Earlier revisions of this document overstated several controls. Specifically, they described the set_spend_policy limits, merchant allowlist, and policy engine as "enforced by the AgentAccountV2 smart contract / on-chain — cannot be overridden," and described a per-tool-invocation audit log. Neither claim was accurate. The policy configured via set_spend_policy is enforced in the MCP server process, not on-chain; on-chain limits exist only if the wallet owner has configured them directly on the AgentAccountV2 contract, which set_spend_policy does not do. The audit trail is on-chain event history only — there is no per-tool-invocation log. The sections below state what each control actually guarantees.

CoSAI Threat Alignment

T9 — Financial Fraud

Threat: An AI agent is manipulated (via prompt injection, tool poisoning, or logic error) into making unauthorized payments.

Mitigations in AgentPay MCP:

ControlImplementationBypass Resistance
Per-transaction spending cap (in-process)set_spend_policy stores a per-tx cap in the MCP server process; every value-moving tool — send_payment, send_token, x402_pay, x402_session_start, bridge_usdc, create_escrow, and swap_tokens — checks it via the in-process policy engine (enforceSpendPolicy — see version note below)Process-level only — not on-chain. Enforced inside the MCP server; can be bypassed by code that skips the check, by a compromised server process, or by the agent itself: set_spend_policy is an ordinary unauthenticated tool, so a manipulated agent can simply call it again to raise or clear its own caps and allowlist
Rolling period limits (in-process)set_spend_policy daily limit (24-hour rolling window), held and checked in the MCP server process; resets if the server restartsSame — process-level only, not smart-contract enforcement
Merchant allowlist (in-process)allowedRecipients in set_spend_policy restricts recipient addresses as part of the same in-process policy. Note: swap_tokens and bridge_usdc custody/return funds at the agent wallet's own address, so that address is the checked recipient — allowlist-only policies must include the agent wallet address to permit swaps and bridgingProcess-level only — the allowlist is not written to or enforced by the smart contract
On-chain per-tx and period limitsAgentAccountV2 smart contract limits, configured by the wallet owner directly on the contract (out-of-band — set_spend_policy does not write them). Readable via check_budget / get_wallet_infoOn-chain — cannot be overridden by application code or the agent, provided the owner has actually configured limits on the contract
Human-approval gateTransactions above the on-chain limits are queued by AgentAccountV2 for review; releasing one requires an owner-privileged approval transaction (queue_approval)Queuing of over-limit transactions is on-chain and cannot be skipped. It is only a human gate if the owner key is held by a human and kept separate from the agent key
Fail-closed policy engine (in-process)Any error while evaluating the in-process spend policy rejects the payment (default-deny)Fail-closed applies within the policy check itself; all seven value-moving tools invoke the check before executing. A future code path that never invoked the check would not be covered by it
Audit trailOn-chain AgentAccountV2 events (executions, queued transactions, approvals, cancellations, on-chain policy updates, operator changes), retrievable via get_transaction_historyImmutable on-chain record — but it covers on-chain wallet operations only; see Audit Logging for what is not recorded

Version note (in-process policy enforcement): the in-process policy engine (enforceSpendPolicy) was wired into the payment path by PR #29, now merged. All seven value-moving tools — send_payment, send_token, x402_pay, x402_session_start, bridge_usdc, create_escrow, and swap_tokens — consult the policy before moving value. Every configured scope (the global scope and any custom scopeKey) is enforced together as a union, amounts are normalised from the asset's own base units to the policy's 18-decimal ETH-equivalent scale before comparison, create_escrow checks the full buyer commitment (payment plus equal buyer stake), and any error during evaluation rejects the payment (fail-closed). Releases cut before that change record the policy via set_spend_policy but do not consult it on the payment path — on those versions, treat the in-process rows above as configuration-only and rely on the on-chain AgentAccountV2 limits. Verify your installed version includes the enforcement wiring before depending on the in-process policy.

Defense-in-depth guidance: treat the in-process policy as a convenience guardrail and the on-chain AgentAccountV2 limits as the tamper-resistant control. set_spend_policy carries no authentication or privilege gate — the same agent the policy is meant to constrain can call it to weaken or clear that policy, which is exactly the capability a prompt-injected agent (the T9 threat) would exploit. Each set_spend_policy call also constructs a fresh policy instance, so re-calling it resets the 24-hour rolling-spend accumulator even if the submitted limits are unchanged. Enterprise deployments should configure on-chain limits on the contract itself and not rely solely on set_spend_policy.

T10 — Identity Spoofing

Threat: A malicious agent impersonates a legitimate agent to gain access to payment infrastructure or services.

Mitigations in AgentPay MCP:

ControlImplementation
ERC-8004 identity verificationverify_agent_identity tool validates on-chain agent identity NFTs
Non-custodial key managementAgent private key stored locally; never transmitted to any server
On-chain reputationget_reputation provides verifiable transaction history and trust score
Session token verificationx402 session tokens are ECDSA-signed; any verifier can independently validate

OAuth 2.1 + PKCE Compliance

MCP 2026 roadmap requires OAuth 2.1 with PKCE for server authentication in enterprise environments.

Current status:

  • AgentPay MCP supports configuration via environment variables (AGENT_PRIVATE_KEY, AGENT_WALLET_ADDRESS) for direct deployment
  • For enterprise SSO: Azure AD and Okta can broker OAuth 2.1 tokens that gate access to the MCP server process
  • PKCE flow: supported when deployed behind an OAuth 2.1-compliant reverse proxy (e.g., Azure API Management, Auth0)
  • The MCP server itself authenticates agents via their on-chain identity (ERC-8004) and wallet signature, which provides cryptographic authentication independent of OAuth

Roadmap:

  • Native OAuth 2.1 token validation in the MCP server transport layer (aligned with MCP spec evolution)
  • Mutual TLS option for server-to-server deployments

Audit Logging

Correction (2026-08-16): an earlier revision of this section stated that every tool invocation is logged with an ISO 8601 timestamp, tool name and parameters, outcome, and policy-evaluation result. That was inaccurate — AgentPay MCP has no per-tool-invocation audit log. This section now describes what is actually recorded.

What is recorded — on-chain event history only. The get_transaction_history tool replays AgentAccountV2 contract events for the wallet:

  • Transaction executions (recipient, value, executor)
  • Queued transactions (queue ID, recipient, value)
  • Approvals and cancellations (queue ID only — recipient and value appear solely on the earlier queued event, so SIEM exports must correlate approval/cancellation records with their queue event to attribute them; a queued event that falls outside the query window leaves its approval unattributable from this tool alone)
  • On-chain spend-policy updates (token, per-tx limit, period limit)
  • Operator changes

Each entry carries the event type, block number, and transaction hash. These records are immutable and independently verifiable on any node or block explorer for the configured chain (Base by default), and can be exported to enterprise SIEM systems by querying the chain directly or via get_transaction_history.

What is NOT recorded:

  • Tool invocations, tool names, or tool parameters — no MCP-level request log exists
  • In-process policy evaluation results (approvals/rejections by the set_spend_policy engine)
  • Payment attempts rejected or failed before a transaction reached the chain
  • Reverted on-chain transactions — a mined-but-reverted attempt rolls back its event logs, so event-based history cannot show it; auditors needing reverted attempts must consult transaction receipts or an external indexer
  • Read-only tool calls (balance checks, identity lookups, history queries)
  • Wall-clock timestamps — on-chain entries are ordered by block number; derive times from block timestamps

Deployments that require per-invocation audit logging should run the MCP server behind a logging gateway or wrapper that captures the JSON-RPC request/response stream and forwards it to their SIEM. AgentPay MCP does not provide this natively today.

Dependency Security

  • Zero LiteLLM dependency — no exposure to the March 2026 PyPI supply chain compromise
  • Minimal npm dependency treeviem, @modelcontextprotocol/sdk, and auditable packages only
  • No Python runtime required — eliminates PyPI supply chain attack surface entirely
  • NVIDIA-validated — security posture reviewed as part of NVIDIA NeMo Agent Toolkit Examples PR #17 merge process

Contact

Security issues: see SECURITY.md for responsible disclosure process.