bankee.ai
The Implementation Layer
PILLAR 02 — IMPLEMENTATION LAYERPublished

x402 on AWS: protecting a content API with CloudFront, Lambda@Edge and Bedrock AgentCore

A production walkthrough of the AWS reference architecture for x402 — from WAF price injection to Lambda@Edge payment gates to managed agent wallets via AgentCore Payments. With working Lambda code.

28 May 2026
14 min read
By Bankee Engineering

What we are building

This article walks through a complete AWS deployment of x402 — the HTTP payment protocol for agentic systems. If you have not read the protocol overview yet, start with the Protocol Layer deep dive first, then come back here for the implementation.

The setup has two sides. On the service side, a CloudFront distribution sits in front of an S3 bucket containing paid content — market data, research, datasets, or any other resource an agent might need to purchase. Lambda@Edge functions intercept requests to enforce payment before the content is served. On the agent side, an Amazon Bedrock AgentCore runtime runs a Strands-based Python agent that discovers the x402 requirement, executes the payment, and retries transparently.

The reference implementations are published by AWS in the aws-samples repositories. This article explains what each component does and why, so you can adapt the pattern to your own infrastructure.

x402 on AWS — Agent to Service Payment Flow
Agent Side (Payer)Service Side (Seller / Merchant)Amazon Bedrock AgentCoreStrands Agent (Python) + Claude SonnetGateway (MCP Tool Server) → Runtime → AgentParse 402 — Extract x402 Payment SpecRecipient · amount · token · network · facilitator URLSign Payment (EIP-3009)AgentCore Payments — managed wallet, no key exposureAgentKit Wallet (CDP)USDC on Base · EIP-3009 Transfer With AuthorisationAwait verified response from serviceContinue WorkflowAmazon CloudFront — CDN entry pointAWS WAF + Bot ControlBot labels · Route evaluation · Price header injectionLambda@Edge — Origin RequestVerify payment via x402 Facilitator · Return 402 if missingAmazon S3 — Content BucketMarket data · Articles · Research · DatasetsLambda@Edge — Origin ResponseSettle payment on-chain via x402 Facilitatorx402 FacilitatorVerify + SettleBase (L2)USDC settlementviewer requestpayment valid → forwardorigin responsesettleverify① HTTP Request② 402 PaymentRequired③ Retry +X-PAYMENT④ 200 OK
CloudFront
WAF
AgentCore / Lambda
Blockchain / Wallet
S3 Origin
x402 Facilitator

The service side: CloudFront, WAF, and Lambda@Edge

CloudFront as the entry point

CloudFront is the right entry point for an x402-protected API for two reasons. First, it gives you global edge presence — the 402 response and payment negotiation happen at the nearest edge node, not in a central origin. Second, CloudFront's Lambda@Edge integration lets you attach compute to the request and response lifecycle without modifying the origin at all. Your S3 bucket stays a plain S3 bucket.

WAF + Bot Control: price header injection

AWS WAF with Bot Control sits between CloudFront and Lambda@Edge. Its role in an x402 stack goes beyond standard bot protection — WAF rules can inspect the incoming request, classify the caller (human browser vs. autonomous agent), and inject pricing headers before the request reaches Lambda@Edge. This lets you run tiered pricing logic at the WAF layer: a human browsing your site gets a standard experience, an agent calling programmatically triggers the x402 flow.

WAF also provides the first line of defence against malformed payment headers and replay attacks. Rules can reject requests where the X-Payment header is structurally invalid before they reach your Lambda functions.

Lambda@Edge — Origin Request: the 402 gate

The Origin Request Lambda fires after CloudFront and WAF have processed the request, and before it reaches S3. This is where the 402 gate lives. If the request carries no X-Payment header, the function returns a 402 immediately with a fully specified payment requirement in the body. If a payment header is present, the function calls the x402 Facilitator to verify the signature on-chain before forwarding.

origin-request.mjs
View on GitHub
// Lambda@Edge — Origin Request
// Intercepts every viewer request. Returns 402 if no valid payment
// is present; forwards to S3 if payment verifies.

export const handler = async (event) => {
  const request = event.Records[0].cf.request;
  const xPayment = request.headers['x-payment']?.[0]?.value;

  // No payment header — build the 402 response with payment spec
  if (!xPayment) {
    const spec = {
      version: '1',
      scheme: 'exact',
      network: process.env.NETWORK,               // 'base' or 'base-sepolia'
      maxAmountRequired: getPriceForPath(request.uri),
      asset: process.env.USDC_CONTRACT_ADDRESS,
      payTo: process.env.PROVIDER_WALLET_ADDRESS,
      description: `Access: ${request.uri}`,
      maxTimeoutSeconds: 300,
    };
    return {
      status: '402',
      statusDescription: 'Payment Required',
      headers: {
        'content-type': [{ key: 'Content-Type', value: 'application/json' }],
        'cache-control': [{ key: 'Cache-Control', value: 'no-store' }],
      },
      body: JSON.stringify(spec),
    };
  }

  // Payment header present — verify signature with x402 Facilitator
  const verified = await verifyWithFacilitator(xPayment, {
    uri: request.uri,
    facilitatorUrl: process.env.FACILITATOR_URL,
  });

  if (!verified.valid) {
    return {
      status: '402',
      statusDescription: 'Payment Required',
      body: JSON.stringify({ error: verified.reason }),
    };
  }

  // Verification passed — attach receipt and forward to S3
  request.headers['x-payment-verified'] = [{
    key: 'X-Payment-Verified',
    value: verified.txHash,
  }];
  return request;
};

A few implementation details worth noting. The getPriceForPath function is where your pricing logic lives — you can implement per-resource pricing, bulk tiers, or even dynamic pricing driven by demand signals injected by WAF. The verifyWithFacilitator call is the only network hop outside the Lambda itself; keep it fast by deploying the Facilitator in the same AWS region as your CloudFront origin.

Lambda@Edge — Origin Response: settlement

The Origin Response Lambda fires after S3 returns content, on the way back to the agent. Its job is to settle the payment on-chain — broadcasting the pre-authorised ERC-3009 transfer to Base — and attach a receipt to the response. Because S3 has already returned the content at this point, settlement is non-blocking: the agent receives its data while the on-chain transaction confirms in the background.

origin-response.mjs
View on GitHub
// Lambda@Edge — Origin Response
// Fires after S3 returns content. Triggers on-chain settlement
// and attaches the receipt to the outbound response.

export const handler = async (event) => {
  const { request, response } = event.Records[0].cf;

  if (response.status === '200') {
    const xPayment = request.headers['x-payment']?.[0]?.value;

    if (xPayment) {
      // Settle the pre-authorised ERC-3009 transfer on-chain.
      // Fire-and-forget — content is already on its way to the agent.
      const receipt = await settlePayment(xPayment, {
        facilitatorUrl: process.env.FACILITATOR_URL,
      });

      // Attach on-chain receipt to response so agent can audit
      response.headers['x-payment-receipt'] = [{
        key: 'X-Payment-Receipt',
        value: JSON.stringify({ txHash: receipt.txHash }),
      }];
    }
  }

  return response;
};
WHY TWO LAMBDAS?

Origin Request verifies before serving; Origin Response settles after serving. This split is intentional — it decouples fraud prevention (no valid payment = no content) from the settlement transaction (content delivered = payment finalised). An agent that receives content but whose on-chain settlement fails will be flagged in the audit log and locked out on the next request.

The agent side: Bedrock AgentCore and AgentCore Payments

Amazon Bedrock AgentCore

AgentCore is AWS's managed runtime for production AI agents. It handles the infrastructure concerns that are easy to underestimate when building agents: horizontal scaling under burst load, IAM SigV4 authentication for all outbound calls, session memory for multi-turn workflows, and Secrets Manager integration for credentials. For an x402-enabled agent, the critical integration is AgentCore Payments.

AgentCore Payments: managed wallets and spending governance

AgentCore Payments is a recently launched AWS service (currently in preview) that handles the wallet management and payment execution layer for agents running on AgentCore. The key property is that your team never handles private keys — the wallet is provisioned and managed entirely by the service. When an agent receives an HTTP 402 response, AgentCore Payments intercepts it, evaluates the cost against the configured policy, and if approved, signs the ERC-3009 transfer and retries the request automatically.

Policy configuration is where spending governance lives. You can set per-call maximums, per-session budgets, allowed networks, and allowed asset contracts. An agent that encounters a 402 asking for more than its per-call limit will abort and return an error to the orchestration layer rather than making an unconstrained payment.

agent.py
View on GitHub
# Agent side — Bedrock AgentCore with AgentCore Payments
# AgentCore Payments handles the wallet and EIP-3009 signing
# automatically once you attach a payment policy to the agent.

import boto3
from strands import Agent
from strands_tools import http_request

# Policy enforces per-session and per-call spend limits
PAYMENT_POLICY = {
    "maxAmountPerCall": "5000",    # 0.005 USDC
    "maxAmountPerSession": "50000", # 0.05 USDC
    "allowedNetworks": ["base"],
    "allowedAssets": [USDC_BASE_ADDRESS],
}

agent = Agent(
    model="us.anthropic.claude-sonnet-4-5",
    tools=[http_request],
    payment_config=PAYMENT_POLICY,   # AgentCore Payments
)

# The agent now handles x402 flows transparently.
# If any tool call returns 402, AgentCore Payments intercepts,
# evaluates the cost against policy, signs the transfer, and retries.
response = agent("Fetch the latest SOFR rate from the data API")

The x402 Facilitator

The x402 Facilitator is a lightweight verification and settlement service that both sides of the transaction call. On the service side, Lambda@Edge Origin Request calls the Facilitator to verify that the ERC-3009 signature in the X-Payment header is valid and has not been replayed. On the service side again, Lambda@Edge Origin Response calls the Facilitator to broadcast the signed transfer to Base and obtain a transaction hash.

The Facilitator keeps the Lambda functions stateless. Neither Lambda needs a wallet, neither needs to talk to the blockchain directly, and neither needs to maintain nonce state. All of that complexity lives in the Facilitator. For the AWS reference implementation, the Facilitator runs as a separate Lambda or container service deployed in the same region as the CloudFront origin.

Settlement uses Base, Coinbase's Ethereum L2. Final settlement costs approximately $0.0001 per transaction, and confirmation times are typically under two seconds. For development and testing, Base Sepolia (the testnet) has identical behaviour with no real funds involved.

Where this pattern applies in financial services

The AWS architecture above was designed with financial services data distribution specifically in mind. The pattern makes sense wherever a data provider wants to sell programmatic API access on a per-call basis — with no subscription friction, no manual key provisioning, and an immutable on-chain audit trail for every transaction.

Capital markets

Real-time tick data, alternative data feeds, earnings transcripts, and proprietary research — sold per-query to trading agents.

Lending

Bureau data pulls, income verification, fraud signals, and open banking cash-flow data charged at point of consumption.

Compliance

Sanctions list checks, PEP screening, regulatory feed subscriptions — each agent call produces its own on-chain proof of access.

Wealth & insurance

Specialist data products — actuarial tables, fund factsheets, property valuations — monetised without a contract or a sales process.

Running it yourself

AWS has published two open-source reference repositories that deploy this architecture end to end. The first covers the CloudFront + WAF + Lambda@Edge + S3 content monetisation stack. The second adds the AgentCore + Strands agent side. Both use AWS CDK for infrastructure-as-code and include test scripts for local development against Base Sepolia.

aws-samples
sample-x402-content-monetisation-with-cloudfront-and-waf

Provider side: CloudFront, WAF, Lambda@Edge, S3 and x402 Facilitator deployment.

aws-samples
sample-agentcore-cloudfront-x402-payments

Agent side: Bedrock AgentCore with Strands agent and AgentCore Payments integration.

Up next in the Implementation Layer

Provisioning a Stripe-managed virtual card for an AI agent — scoped spend limits, programmatic top-ups, and reconciling transactions back to the agent reasoning chain.

All implementation guides
Implementation LayerAll pillars →