Skip to content

docs(payments): correct T02 description of the runtime execution role#1677

Closed
fahadfa-aws wants to merge 2 commits into
awslabs:mainfrom
fahadfa-aws:fix/payments-t02-runtime-role-readme-accuracy
Closed

docs(payments): correct T02 description of the runtime execution role#1677
fahadfa-aws wants to merge 2 commits into
awslabs:mainfrom
fahadfa-aws:fix/payments-t02-runtime-role-readme-accuracy

Conversation

@fahadfa-aws

Copy link
Copy Markdown

Issue

The Tutorial 02 README "Key Concepts" section described the execution role as ProcessPaymentRole with "explicit denies on CreatePaymentSession, CreatePaymentInstrument, and all control-plane operations." Two factual problems:

  1. The deployed runtime is not bound to AgentCorePaymentsProcessPaymentRole. deploy_payment_agent.py:154 runs agentcore deploy -y, and the CLI's CDK construct creates a fresh execution role itself. The script then attaches a narrow inline policy (PaymentDataPlaneAccess) to whichever auto-created role it finds. The runtime's roleArn returned by GetAgentRuntime is that auto-created role.

  2. The Deny ProcessPayment statement lives on the management role, not on ProcessPaymentRole. The official IAM guide puts the explicit Deny ProcessPayment on ManagementRole (the role used by app backends to create sessions). ProcessPaymentRole's design pattern is narrow scope — Allow only ProcessPayment and the read APIs, and the absence of CreatePaymentSession / CreatePaymentInstrument enforces separation.

utils.py matches the AWS-docs pattern correctly: MANAGEMENT_ROLE has \"deny\": [\"bedrock-agentcore:ProcessPayment\"]; PROCESS_PAYMENT_ROLE has only allow: with no deny: key.

Changes

  • README.md (Key Concepts section): rewrite the role paragraph to describe the auto-created execution role plus the narrow inline policy that deploy_payment_agent.py attaches. Cross-link to the AWS IAM roles guide.
  • deploy_payment_agent.py (line 160): add a code comment explaining that agentcore.json (AgentEnvSpec) does not currently expose executionRoleArn, so the runtime cannot be bound to a caller-managed role today. The narrow inline policy is the workaround that achieves the same separation.

Docs + one code comment. No behavior change.

Verification

AWS Knowledge MCP — re-read payments-iam-roles.html. Confirmed: "The explicit Deny on ProcessPayment in the management role" and the literal Statement[Sid: \"DenyProcessPayment\", Effect: \"Deny\", Action: \"bedrock-agentcore:ProcessPayment\"] is shown in the ManagementRole policy block. The ProcessPaymentRole policy block has only Allow statements.

Live AWS — fresh deploy on us-west-2 against 180780550628:

  • agentcore deploy created CFN stack AgentCore-PaymentAgent-default
  • GetAgentRuntime returned roleArn = AgentCore-PaymentAgent-de-ApplicationAgentPaymentAg-C28in3waHa31 (auto-CDK), not AgentCorePaymentsProcessPaymentRole
  • GetRolePolicy(PaymentDataPlaneAccess) returned the literal Allow-only policy from deploy_payment_agent.py:170-191 — no Deny statements anywhere
  • Stack torn down after verification

CLI schema — read the scaffolded agentcore/.llm-context/agentcore.ts. The AgentEnvSpec interface (the runtime config in agentcore.json) has fields name, build, entrypoint, codeLocation, runtimeVersion, envVars, networkMode, networkConfig, instrumentation, protocol, tags, filesystemConfigurations — no executionRoleArn. So binding to a caller-managed role isn't possible with CLI 0.19; the inline-policy approach is the available pattern.

The "Key Concepts" section called the execution role `ProcessPaymentRole`
and described it as having "explicit denies on CreatePaymentSession,
CreatePaymentInstrument, and all control-plane operations." Two factual
errors in one sentence:

1. The deployed runtime is not bound to AgentCorePaymentsProcessPaymentRole.
   `deploy_payment_agent.py` runs `agentcore deploy -y` and the CLI's CDK
   construct creates a fresh execution role itself. The script then
   attaches a narrow inline policy to whichever auto-created role it
   finds. The runtime's roleArn returned by GetAgentRuntime is that
   auto-created role, not the role utils.py creates.

2. Per the official IAM roles guide for AgentCore payments, the
   `Deny ProcessPayment` statement lives on **ManagementRole**, not on
   ProcessPaymentRole. ProcessPaymentRole's design is narrow scope
   (Allow only ProcessPayment + read APIs); the absence of CreateSession
   and CreateInstrument is what enforces separation, not a Deny.

Update the section to describe what actually happens — the auto-created
execution role plus the inline PaymentDataPlaneAccess policy. Cross-link
to the AWS IAM roles guide so users see the canonical separation pattern.

Add a code comment near the IAM attach in deploy_payment_agent.py
explaining that the CLI's `agentcore.json` schema (`AgentEnvSpec`) does
not currently expose `executionRoleArn`, so binding the runtime to a
caller-managed role is not possible today. The narrow inline policy is
the workaround.

Verified:
- AWS Knowledge MCP confirmed the canonical IAM separation pattern
  (Deny on ManagementRole, narrow scope on ProcessPaymentRole)
- Live deploy on us-west-2: runtime roleArn was the auto-CDK role
  (AgentCore-PaymentAgent-de-ApplicationAgentPaymentAg-...), inline
  policy was Allow-only as written by the script. Stack torn down.
Replace the API-name list and the slightly defensive 'this matches'
phrasing with a tighter contrast: narrow scope is what enforces the
boundary on the execution role; the explicit Deny lives on the
management role.
@fahadfa-aws

Copy link
Copy Markdown
Author

@mvangara10 — flagging this for your review when you have a moment. Tagged across the full set of payments-tutorial fixes I've been pushing today; happy to walk through any of them. Audit logs and test evidence are referenced in the PR description.

@fahadfa-aws

Copy link
Copy Markdown
Author

Superseded by #1738 (consolidated PR)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant