본문 바로가기
MegazoneCloud
← 전체 글
AWS

AWS WAF와 Bedrock AgentCore Payments로 x402 결제 직접 구축하기 (1편)

AI인 내가 돈 내고 당당히 웹페이지에 들어간 건에 대하여: 삐빅, 로봇이 맞습니다.

3줄 요약

  1. AWS WAF는 AI 봇에게 HTTP 402로 요금을 청구하고, AgentCore Payments는 AI 에이전트가 스스로 돈을 내게 합니다.
  2. 둘을 연결하자 에이전트가 기사를 사서 읽었고, 한도를 넘는 4번째 결제는 결제 세션이 거절했습니다.
  3. 구축하며 만난 문제와 해결, 정리한 남은 숙제 넷도 정리했습니다.

작성 기준: 2026년 10월, Base Sepolia 테스트넷(실제 돈은 들지 않음). BIPA 커뮤니티 발표 「삐빅, 로봇이 맞습니다」의 기술 편이며, 일부 그림은 발표 장표입니다.


들어가며: 웹이 로봇에게 묻는 질문

※ 이해를 돕기 위해 직접 그린 이미지입니다.
연도방식웹이 로봇에게 하는 말
1994robots.txt“로봇은 여기까지만”
2000CAPTCHA“사람인지 증명해”
2025x402“로봇이면 돈 내”

AWS에 따르면 많은 콘텐츠 사이트에서 AI 봇이 요청의 절반 이상입니다. AI 봇은 글을 요약해 답하고 끝나서, 사이트로 돌아오는 방문자는 줄어듭니다. 그래서 허용과 차단 사이에 세 번째 선택지가 생겼습니다. 돈을 받고 들여보내는 것입니다.


1. x402는 어떻게 동작하나

402 Payment Required는 1997년 HTTP 표준에 “나중에 쓸 것”으로 예약만 된 상태 코드입니다. 2025년 5월 Coinbase가 이 코드로 결제를 주고받는 규약 x402를 발표했습니다.

x402는 IETF·W3C의 공식 인터넷 표준은 아닙니다. 2026년 4월부터 리눅스 재단 산하 x402 재단이 관리하고, AWS·Google·Visa·Mastercard·Stripe 등이 참여합니다.

  1. AI가 기사를 요청합니다.
  2. 서버가 402와 기계가 읽는 가격표(PAYMENT-REQUIRED 헤더)를 돌려줍니다.
  3. AI가 결제에 서명해 증빙(PAYMENT-SIGNATURE 헤더)을 붙여 다시 요청합니다.
  4. 서버가 정산을 확인하고 기사를 내줍니다.

실제로 받은 가격표입니다.

{
  "x402Version": 2,
  "resource": { "url": "https://<배포 주소>/api/premium-article-1" },
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:84532",
    "amount": "1000",
    "payTo": "0x2484…5502",
    "asset": "0x036C…CF7e",
    "maxTimeoutSeconds": 300,
    "extra": { "name": "USDC", "version": "2" }
  }]
}

eip155:84532는 Base Sepolia 테스트넷, amount: 1000은 0.001 USDC입니다(USDC는 소수점 6자리).


2. 아키텍처

왼쪽 구매자 계정, 오른쪽 판매자 계정, 아래 Coinbase. 돈은 AWS를 거치지 않고 블록체인에서 판매자 지갑으로 바로 갑니다.
역할서비스리전
판매자CloudFront + AWS WAF AI traffic monetization + S3us-east-1
구매자Bedrock AgentCore Payments + Coinbase CDP 지갑us-west-2
에이전트Strands Agents + Claude Sonnet 5.5, AgentCore Runtimeus-west-2
  • AgentCore Payments는 아직 서울·도쿄 리전을 지원하지 않아 구매자는 오레곤에 올렸습니다.
  • 출발점은 AWS 샘플 sample-agentcore-cloudfront-x402-payments입니다. main 브랜치는 판매자가 Lambda@Edge라서, 판매자를 WAF로 바꾼 PR #30(외부 기여자 Draft, 미머지)을 바탕으로 고쳐 썼습니다.

결제 서명만으로는 돈이 나가지 않습니다. 다시 요청하면 WAF가 서명을 검증하고, 원본이 기사를 주면(2xx) 그때 정산합니다.


3. 판매자: WAF로 요금소 세우기

핵심: 코드 없이 설정만으로 “사람은 통과, 봇은 402″를 만들 수 있습니다.

3-1. 결제 설정

"MonetizationConfig": {
  "CryptoConfig": {
    "PaymentNetworks": [{
      "Chain": "BASE_SEPOLIA",
      "WalletAddress": "0x…",
      "Prices": [{ "Amount": "0.001", "Currency": "USDC" }]
    }]
  },
  "CurrencyMode": "TEST"
}
  • CurrencyMode 기본값은 REAL입니다. TEST로 지정하지 않으면 실제 돈이 오갑니다.
  • 기본 가격의 최솟값은 0.001 USDC입니다.
  • 웹 ACL은 CLOUDFRONT 범위여야 합니다. 리전 범위(API Gateway, ALB)에서는 쓸 수 없습니다.
  • 받는 주소(WalletAddress)는 반드시 내 지갑으로 바꾸세요. 이 데모는 샘플 코드의 기본 주소(0x2484…)를 그대로 썼습니다(테스트넷). 바꾸지 않고 REAL로 켜면 실제 돈이 남의 지갑으로 갑니다.

3-2. 규칙 순서

우선순위규칙동작
0Bot Control봇에 라벨만 붙임 (Count)
1human-allow봇 라벨이 없으면 통과
2allow-discovery/mcp/, /.well-known/은 무료
10~Monetize-*경로별 가격 × 배수(PriceMultiplier)로 402

3-3. 확인

curl -i https://<배포 주소>/api/premium-article-1   # 봇(curl) → 402 + 가격표

같은 주소를 브라우저로 열면 200으로 기사가 보입니다.

같은 주소, 사람은 기사, 봇은 0.001 USDC 가격표를 받습니다. ※ 실제 응답으로 직접 구성한 이미지입니다.

3-4. 이름표를 떼면?

User-Agent결과
curl, python-httpx, GPTBot, ClaudeBot402
aiohttp, My-Agent, Strands-Agent200 (무료 통과)

Bot Control은 처음 보는 이름을 봇으로 분류하지 않았습니다. 어떻게 잡는지는 2편에서 다룹니다.


4. 구매자: AgentCore Payments로 지갑 만들기

핵심: 한도는 에이전트가 아니라 결제 세션이 지킵니다.

순서리소스역할
1자격 증명 공급자Coinbase CDP 키 3개를 AgentCore Identity에 보관
2결제 매니저결제를 총괄
3결제 커넥터매니저와 Coinbase를 연결
4결제 수단(지갑)에이전트가 쓸 임베디드 지갑
5결제 세션한도와 만료 시간

4-1. 시작 전에 해 둘 것

  • CDP 포털: Secret API Key에 Non-custodial Export·Manage 권한을 주고, Wallet Secret을 만듭니다.
  • CDP 포털: 그 프로젝트에서 Delegated signing을 켭니다. 안 켜면 Delegated signing is not enabled… 오류가 납니다.
  • AWS Marketplace: “Coinbase Wallets for AgentCore Payments”를 구독합니다. 안 하면 SubscriptionRequiredException이 납니다. 지갑 작업(생성·서명·방송) 1건당 $0.005가 첫 건부터 붙습니다. 조직 계정이라면 약관 동의 전에 내부 승인을 확인하세요.
  • Wallet Hub: 지갑 주인이 에이전트에게 서명 권한을 위임합니다(30일).
① 프로젝트를 확인하고 ② Delegated signing을 켭니다.
① 위임 기간을 정하고 ② 지갑 주인이 승인합니다. 프로젝트 설정과 지갑 승인이 모두 필요합니다.

4-2. 결제 세션: 한도와 만료

dp.create_payment_session(
    paymentManagerArn=MANAGER_ARN,
    userId="bipa-demo-user",
    expiryTimeInMinutes=60,                                  # 15~480분
    limits={"maxSpendAmount": {"value": "0.003", "currency": "USD"}},
)

한도를 넘는 결제는 서명 단계에서 거부됩니다. 프롬프트로 부탁하는 게 아니라 에이전트 바깥에서 강제합니다.

결제 세션은 회사가 AI에게 건네는 법인카드입니다. 에이전트는 세션을 만들거나 한도를 바꿀 수 없습니다. ※ 왼쪽 그림은 AI(Gemini)로 생성한 이해를 돕기 위한 이미지입니다.

같은 글에 두 번 결제하지 않으려면: x402의 payment-identifier 확장을 쓰면 15분 안의 재시도는 중복 결제되지 않습니다(클라이언트가 지원할 때). WAF는 원본이 2xx를 줄 때만 정산하므로 원본 오류에는 청구되지 않습니다. 그래도 하루 예산은 세션 한도로 묶어 두세요.


5. 실행 결과

5-1. 직접 결제 (에이전트 없이)

① 첫 요청: HTTP 402
   가격표: 0.001 USDC → 0x2484…5502 (eip155:84532)
② 결제 증빙 생성: ['PAYMENT-SIGNATURE'] (2.8초)
③ 재요청: HTTP 200 (4.5초)
   정산 결과: {"success":true, "transaction":"0xf64a…0e1b"}
지갑 잔액: 19.998 → 19.997 USDC

결제가 붙은 요청 한 건은 5~8초쯤 걸립니다. 서명과 블록체인 정산 시간입니다.

에이전트 지갑에서 판매자 지갑으로 0.001 USDC. 보낸 주소(From)는 가스비를 대신 낸 정산 대행(Facilitator)입니다.

5-2. 에이전트에게 맡기기

“DEMO 데일리의 기사를 읽고 세 줄로 요약해 줘”

에이전트는 402를 받고 가격을 확인한 뒤 스스로 결제하고 요약했습니다(AgentCore Runtime, 14.8초).

5-3. 반전: 기사 5건, 한도 0.003 USD

“DEMO 데일리 기사 5개를 모두 읽고 각각 한 줄로 요약해 줘”

기사결과
1~3결제하고 요약
4Insufficient budget for session으로 거절
5시도하지 않음

“세션 예산은 서버 쪽에서 정해 두는 값이라 제가 늘리거나 우회할 수 없습니다.” (에이전트의 답)

지갑에서는 정확히 0.003 USDC만 빠져나갔습니다.

5-4. 판매자 쪽 기록

WAF는 결제 서명을 확인하고 정산을 Coinbase에 맡깁니다. 돈은 판매자 지갑으로 바로 가고, AWS 콘솔에는 기록만 남습니다.

요청당 0.0010 USDC, 정산 3건. 매출은 모두 검증되지 않은 봇(Unverified)에서 나왔습니다.
데모 에이전트는 “Python (Http library)”로 분류됐고, 기사마다 1건씩 결제됐습니다.

주의: Revenue 대시보드는 기본이 Production 모드라 테스트넷 결제가 0으로 보입니다. 오른쪽 위에서 Test로 바꾸세요. 합계는 소수점 둘째 자리까지만 보여서 0.003은 “0.00”으로 나옵니다.


6. 직접 구축하며 만난 문제와 해결

① PR #30 배포 뒤 콘텐츠를 따로 올려야 한다

  • 증상: 사람이 접속해도 403 AccessDenied (server: AmazonS3)
  • 원인: Lambda@Edge를 지우면서 콘텐츠 생성 부분도 사라져 S3가 비어 있습니다.
  • 해결: 요청 경로(api/premium-article-1)와 같은 키로 S3에 올립니다.

② 결제 매니저 서비스 역할에 권한이 모자라다

  • 증상: missing the required permission: bedrock-agentcore:CreateWorkloadIdentity
  • 해결: IAM 문서의 Base permissions를 추가합니다.

③ 결제는 했는데 기사를 못 받는다

  • 증상: 결제 증빙은 PROOF_GENERATED인데 재요청이 403
  • 원인: 샘플 에이전트가 재요청을 POST로 보냅니다(S3 오리진은 GET만 받음). 또 x402 v2 헤더의 resource를 잘못된 곳에서 읽고, extensions를 extension으로 적었습니다.
  • 해결: 402 응답 최상위의 resource·extensions를 보관해 SDK와 같은 형식으로 헤더를 만들고, GET으로 보냅니다.
header_obj = {
    "x402Version": 2,
    "resource": envelope.get("resource"),        # 402 응답 최상위
    "accepted": x402_payload,                    # accepts[0]
    "extensions": envelope.get("extensions", {}),
    "payload": proof.get("payload", proof),
}
response = client.get(full_url, headers={"PAYMENT-SIGNATURE": encoded})  # POST → GET

정산 전에 막혀서 돈은 나가지 않았습니다.

④ 배포 스크립트가 결제 설정을 Runtime에 넘기지 않는다

  • 원인: 환경 변수 허용 목록에 MANAGER_ARN, PAYMENT_SESSION_ID 등이 없습니다.
  • 해결: 목록에 추가하고, 세션 ID를 호출할 때 넘기는 옵션을 더했습니다. 세션(최대 8시간)이 바뀌어도 다시 배포하지 않아도 됩니다.

그 밖에

  • 빠른 시작 문서 예제가 현재 API와 다릅니다: CRYPTO_WALLET → EMBEDDED_CRYPTO_WALLET, expiryDuration → expiryTimeInMinutes. 지갑에는 로그인 수단(linkedAccounts)이 정확히 하나 필요합니다.
  • 구매자 스택은 리전을 명시해서 배포하세요. 기본 리전이 서울이면 그대로 서울에 배포됩니다.

7. 응용: 어디에 쓸 수 있나

구매자 AI 하나가 판매자 넷에게 부를 때마다 한 건씩 냅니다. ※ 아이콘은 AI(Gemini)로 생성한 이해를 돕기 위한 이미지입니다.
  • 유료 API를 건당 판매: 가입·API 키·월 구독 없이 호출 1건당 결제
  • 에이전트용 유료 도구(MCP): 도구를 부를 때마다 과금
  • 전문 에이전트(A2A): 세법·법규·번역처럼 전문 지식을 질문 1건 단위로 판매
  • 봇 종류별 차등 가격: AWS WAF 콘솔 ‘AI 트래픽 분석’에서 봇과 경로를 골라 가격 배수 지정

쇼핑은 반반

정보를 여러 번 조금씩 사는 단계는 x402, 큰 금액의 물건값 결제는 카드 규약. ※ 그림은 AI(Gemini)로 생성한 이해를 돕기 위한 이미지입니다.
규약주도한 줄로
AP2 (2025.9)Google사용자가 허락한 범위를 서명한 위임장. 스테이블코인 결제는 x402 확장
ACP (2025.9)OpenAI, Stripe이 가게·이 금액만 쓰는 1회용 결제 토큰
Intelligent Commerce, Agent Pay (2025)Visa, Mastercard정한 한도·가맹점에서만 쓰는 에이전트 전용 카드 토큰

방식은 달라도 한도와 승인 범위를 에이전트 바깥에서 정한다는 점은 이번 결제 세션과 같습니다.


8. 비용

항목금액
WAF 웹 ACL, 규칙, Bot Control한 달 약 $27 (추정)
Coinbase 지갑 작업 (Marketplace)건당 $0.005, 첫 건부터
AgentCore Runtime, 모델 호출사용한 만큼
테스트넷 USDC무료 (Circle Faucet)
  • 데모 기사 값 0.001 USDC는 최솟값입니다. x402 유료 API의 흔한 값은 호출당 $0.01~0.02입니다.
  • 실습 뒤에는 Runtime·ECR·스택·Payments 리소스, Marketplace 구독, CDP API 키를 정리하세요. WAF 고정비가 계속 나갑니다.

9. 아직 남은 숙제

※ 아이콘은 AI(Gemini)로 생성한 이해를 돕기 위한 이미지입니다.
  1. 아직 초기: 공식 표준이 아니고, 결제할 줄 아는 로봇도 적습니다. 필자의 AI 코딩 도구(Claude Code)로 데모 사이트를 열자, WAF는 Claude-User로 알아보고 402를 줬고 도구는 거기서 멈췄습니다.
  2. 결제에도 비용과 시간: 지갑 작업 1건당 약 7원, 결제 한 번에 5~8초. 값이 쌀수록 부담이 큽니다.
  3. 숨으면 공짜: AWS 문서도 봇 판별은 확률적이라고 적습니다. 2편에서 어디까지 잡히는지 실험했습니다.
  4. 돈 받다 사라질 수도: 결제할 줄 모르는 AI에게 가격표는 차단과 같아서, AI 답변에서 내 글이 빠질 수 있습니다.

마치며

국내에서 USDC를 받으려면 규제·회계·세금 검토가 먼저입니다. 그래도 지금 해 볼 일은 있습니다.

  • 웹사이트를 운영한다면: Bot Control을 Count 모드로 켜고 ‘AI 트래픽 분석’ 화면에서 AI 손님부터 세어 보세요. 그 숫자를 보고 그대로 둘지(200), 막을지(403), 돈을 받을지(402) 고르면 됩니다.
  • AI 에이전트를 만든다면: 예산 한도부터 설계하세요. 한도는 프롬프트가 아니라 결제 세션이 지키게 하고, 한도를 정하는 권한과 결제 권한을 나누세요.

☑ 삐빅, 로봇이 맞습니다.
웹이 로봇에게 묻는 질문이 하나 더 생겼습니다. “로봇이면, 돈 내.”


참고 자료

One Comment

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다