|
| 1 | +# Pay-For-API — Buyer Agent |
| 2 | + |
| 3 | +A minimal Strands Agent, wired for Amazon Bedrock Claude Sonnet 4.5, |
| 4 | +that buys a fact from the seller API by delegating the x402 payment to |
| 5 | +**Amazon Bedrock AgentCore Payments** through the |
| 6 | +`AgentCorePaymentsPlugin`. |
| 7 | + |
| 8 | +Two ways to run the same agent: |
| 9 | + |
| 10 | +| Mode | Where | When | |
| 11 | +|------|-------|------| |
| 12 | +| **Local** | Notebook cell in `pay-for-api.ipynb` (§8) | Teaching / fast iteration | |
| 13 | +| **Runtime** | AgentCore Runtime container deployed via CDK (§9) | Production-shaped deploy | |
| 14 | + |
| 15 | +The agent code is identical in both modes. The container folder wraps |
| 16 | +the same `Agent()` construction in a FastAPI `/invocations` endpoint |
| 17 | +so it fits the AgentCore Runtime contract. |
| 18 | + |
| 19 | +## Prerequisites |
| 20 | + |
| 21 | +Before deploying the agent runtime, complete the parent use-case |
| 22 | +prerequisites in [`../README.md`](../README.md). Specifically: |
| 23 | + |
| 24 | +- AWS account with Amazon Bedrock AgentCore Payments enabled in the |
| 25 | + target region |
| 26 | +- Amazon Bedrock model access for `us.anthropic.claude-sonnet-4-5-20250929-v1:0` |
| 27 | +- AWS CDK v2 (`npm install -g aws-cdk`) and Node.js 18+ |
| 28 | +- Python 3.10+ with the use-case venv active |
| 29 | +- Completed §1-§6 of the parent notebook (so a `PaymentManager`, |
| 30 | + `PaymentInstrument`, and at least one `PaymentSession` exist for the |
| 31 | + runtime to invoke against) |
| 32 | + |
| 33 | +## Folder layout |
| 34 | + |
| 35 | +``` |
| 36 | +agent/ |
| 37 | +├── cdk/ |
| 38 | +│ ├── app.py CDK app entry point |
| 39 | +│ ├── agent_stack.py ECR + IAM + Runtime |
| 40 | +│ ├── cdk.json |
| 41 | +│ └── requirements.txt |
| 42 | +├── container/ |
| 43 | +│ ├── Dockerfile |
| 44 | +│ ├── agent.py FastAPI server + Strands Agent |
| 45 | +│ └── requirements.txt |
| 46 | +└── README.md |
| 47 | +``` |
| 48 | + |
| 49 | +## How the payment flow works |
| 50 | + |
| 51 | +1. The agent tries `http_request.GET <seller-url>/facts?topic=<x>`. |
| 52 | +2. The seller returns **HTTP 402** with an x402 `accepts` array. |
| 53 | +3. `AgentCorePaymentsPlugin` intercepts the 402, calls |
| 54 | + **`ProcessPayment`** against the configured Payment Manager, |
| 55 | + Session, and Instrument, receives the signed `CRYPTO_X402` proof, |
| 56 | + base64-encodes it into the `X-PAYMENT` header (per the x402 protocol |
| 57 | + spec), and retries the request transparently. |
| 58 | +4. The seller verifies the proof with the x402 facilitator, settles |
| 59 | + on-chain, and returns the paid fact as **HTTP 200**. |
| 60 | + |
| 61 | +The agent never sees a private key, never assembles the `X-PAYMENT` |
| 62 | +header, and never touches a boto3 client. The only tool it calls is |
| 63 | +`http_request`. The plugin does also register three read-only |
| 64 | +management tools (`get_payment_instrument`, |
| 65 | +`list_payment_instruments`, `get_payment_session`) but the system |
| 66 | +prompt in §7 of the notebook tells the model not to use them — they |
| 67 | +are reserved for operator debug flows. |
| 68 | + |
| 69 | +## Identity model |
| 70 | + |
| 71 | +- Every payment operation runs under the **vendor-level user ID** from |
| 72 | + `paymentInstrument.userId` — the value the service returns on |
| 73 | + `CreatePaymentInstrument`. The notebook captures that ID and passes |
| 74 | + it to the agent as `paymentUserId` on invocation. |
| 75 | +- For Privy-backed instruments, this is the Privy DID. |
| 76 | +- For Coinbase-backed instruments, this is the CDP end-user UUID (hub |
| 77 | + flow). |
| 78 | +- There is **no tenant/Cognito sub on the wire** — identity is |
| 79 | + vendor-rooted end to end. |
| 80 | + |
| 81 | +## Deploy |
| 82 | + |
| 83 | +> ⚠️ **Cost notice:** This deploys an AgentCore Runtime, an Amazon ECR |
| 84 | +> repository, an AWS CodeBuild project, an AgentCore Memory resource, |
| 85 | +> and the supporting CloudWatch log groups. CodeBuild (per-build-minute) |
| 86 | +> and the Runtime (per-invocation) are the highest-cost items. Run the |
| 87 | +> [Clean up](#clean-up) steps when you are done. |
| 88 | +
|
| 89 | +```bash |
| 90 | +cd agent/cdk |
| 91 | +python3 -m venv .venv && source .venv/bin/activate |
| 92 | +pip install -r requirements.txt |
| 93 | +cdk bootstrap # only once per account/region |
| 94 | +cdk deploy |
| 95 | +``` |
| 96 | + |
| 97 | +Outputs: `AgentRuntimeArn`, `AgentRuntimeEndpoint`, |
| 98 | +`AgentExecutionRoleArn`, `AgentEcrRepoUri`, |
| 99 | +`AgentBuildProjectName`, `AgentMemoryId`. |
| 100 | + |
| 101 | +The notebook's §9 calls into the CDK for you. See |
| 102 | +`pay-for-api.ipynb`. |
| 103 | + |
| 104 | +## Clean up |
| 105 | + |
| 106 | +Tear the runtime down when you no longer need it. The notebook's §11 |
| 107 | +runs the same teardown plus the AgentCore Payments resource cleanup. |
| 108 | + |
| 109 | +```bash |
| 110 | +bash test/integration/destroy-agent.sh |
| 111 | +``` |
| 112 | + |
| 113 | +Or directly through CDK: |
| 114 | + |
| 115 | +```bash |
| 116 | +cd agent/cdk |
| 117 | +source .venv/bin/activate |
| 118 | +cdk destroy |
| 119 | +``` |
| 120 | + |
| 121 | +This removes the AgentCore Runtime, the AgentCore Memory resource, the |
| 122 | +ECR repository (with its images), and the CodeBuild project. Verify by |
| 123 | +listing CloudFormation stacks: |
| 124 | + |
| 125 | +```bash |
| 126 | +aws cloudformation list-stacks \ |
| 127 | + --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE \ |
| 128 | + --query "StackSummaries[?starts_with(StackName, 'AgentCorePaymentsBuyerAgent')].StackName" |
| 129 | +``` |
| 130 | + |
| 131 | +The output should be empty. |
| 132 | + |
| 133 | +## Conclusion |
| 134 | + |
| 135 | +This folder packages the buyer-side half of the Pay-For-API use case |
| 136 | +into a deployable AgentCore Runtime. The same Strands Agent pattern |
| 137 | +runs locally in §7 of the parent notebook and in production-shaped |
| 138 | +fashion through the CDK stack here, demonstrating how to graduate a |
| 139 | +local agent prototype to a managed runtime without code changes. The |
| 140 | +`AgentCorePaymentsPlugin` makes the x402 payment flow transparent to |
| 141 | +the agent, so the same `http_request` tool call pays for content |
| 142 | +through whichever wallet provider the operator configured. |
| 143 | + |
| 144 | +For a deeper walkthrough, run `pay-for-api.ipynb` end to end. For the |
| 145 | +service-side reference, see the |
| 146 | +[AgentCore Payments documentation](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments.html). |
0 commit comments