diff --git a/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/README.md b/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/README.md index 2f65409e9..3ac799881 100644 --- a/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/README.md +++ b/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/README.md @@ -124,7 +124,7 @@ python payment_agent.py **Stateless agent** — `payment_agent.py` reads all payment context from the invocation payload, not from environment variables. This means the same agent binary can serve different users with different budgets — the app backend controls what each user can spend by creating a session with the appropriate budget before invoking. -**ProcessPaymentRole** — The execution role the agent runs under. It has `ProcessPayment` permission and explicit denies on `CreatePaymentSession`, `CreatePaymentInstrument`, and all control-plane operations. The agent cannot create sessions, override budgets, or provision wallets. +**Runtime execution role** — The agentcore CLI auto-creates an execution role when it scaffolds the project. `deploy_payment_agent.py` then attaches a narrow inline policy (`PaymentDataPlaneAccess`) that grants only `ProcessPayment` and the read-only payment APIs. The agent cannot create sessions, override budgets, or provision wallets because those actions are not on the allow list — narrow scope is what enforces the boundary. The [IAM roles guide](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments-iam-roles.html) puts the explicit `Deny ProcessPayment` on the management role (used by the app backend to create sessions), not on the execution role. **Payload-driven sessions** — The app backend creates a fresh session with a budget before every invocation, then passes the `payment_session_id` in the payload. The agent cannot reuse sessions from previous invocations or extend their expiry. diff --git a/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/deploy_payment_agent.py b/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/deploy_payment_agent.py index 5ac498534..b00527299 100644 --- a/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/deploy_payment_agent.py +++ b/01-features/08-agents-that-transact/00-getting-started/02-deploy-to-agentcore-runtime/deploy_payment_agent.py @@ -157,7 +157,15 @@ result = subprocess.run(["agentcore", "status"], cwd=project_dir, capture_output=True, text=True) print(result.stdout) -# Add payment permissions to the auto-created execution role +# Add payment permissions to the auto-created execution role. +# The agentcore CLI creates the execution role itself from the CDK construct; +# `agentcore.json` (AgentEnvSpec) does not currently expose `executionRoleArn`, +# so we cannot bind the runtime to the AgentCorePaymentsProcessPaymentRole that +# Tutorial 00 created. Instead, we attach a narrow inline policy here. Allow +# only on ProcessPayment + the read APIs is what enforces separation — the +# absence of CreatePaymentSession / CreatePaymentInstrument on the role keeps +# the agent from creating its own budgets or wallets. See +# https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/payments-iam-roles.html. print("Adding payment permissions to execution role...") iam = boto3.client("iam") roles = iam.list_roles(MaxItems=200)["Roles"]