DEV Community

Nao San for AWS Community Builders

Posted on

[AWS] Using Step Functions as an agent tool: Testing how PINs, IAM, and tokens work [AgentCore]

This article is a machine translation of the contents of the following URL, which I wrote in Japanese:

【AWS】Step Functionsをエージェントのツールにしてみた:ピン・IAM・トークンの効き方を検証【AgentCore】 #MCP - Qiita

はじめに 2026年10月29日、AWS Step Functionsのワークフローを、AIエージェントのツールとして使えるようになりました。Amazon Bedrock AgentCore Gatewayの組み込みコネクタを経由します。 エージェントは「何をどの順で行う...

favicon qiita.com

Introduction

On October 29, 2026, AWS Step Functions workflows became available as a tool for AI agents. This is achieved through a built-in connector in the Amazon Bedrock AgentCore Gateway.

The strength of an agent lies in its ability to decide "what to do and in what order." However, there are tasks, such as refunds and onboarding, where "the same procedure must be followed every time, and a record of what was executed must be kept." This connector stores the procedure in a state machine, leaving the agent only responsible for "when to start and what inputs to use."

However, when passing execution-related APIs to an agent, the focus shifts from the functionality itself to "how far to allow it." There are three mechanisms for restricting the scope of what an agent can call—in other words, control—: pinning, IAM, and task tokens. This article uses the official documentation as primary source information to organize the 10 operations exposed by the connector and explains how to use these three controls, along with the results of testing on a real system.

The verification covered 8 items. The five connector-specific items are tools/list, denial of pinning, includedData, IAM denial of execution ARN, and the authorization flow via waitForTaskToken. Three additional items were added: Standard/Express constraints, tokens for non-public state machines, and how the caller appears in CloudTrail. The results are summarized in "Actual Verification Content and Results".

Premise: Where have the controls moved with the update?

Of the three controls, pinning involves pre-fixing the stateMachineArn of the operation in the gateway target settings. Pinned parameters disappear from the tool's input schema, and the agent cannot change their values.

The official documentation explains the advantage of this connector as "you don't need to write a Lambda function or MCP server, and you don't need to define the tools yourself" (Source: AWS Step Functions as Connector Target). MCP (Model Context Protocol) is a common agreement for agents to find and invoke tools. Conversely, before the update, it can be interpreted that Step Functions were being tooled by preparing Lambda functions or custom MCP servers (my interpretation). In that case, the controls that narrowed the scope allowed to agents were likely on the code and role side, as follows:

Controls Before Update (Tooling with Lambda or custom MCP server) (My interpretation) After Update (Connector)
Pinning the Target Write the state machine ARN in the code Specify in parameterValues of the target settings. The gateway rejects calls that pass different values.
IAM Narrow the scope of permission with roles you have prepared yourself, such as the Lambda execution role Narrow with the gateway's service role. Share between targets on the same gateway.
Task Token Handle in your own code. You can insert validation logic, etc. Expose SendTask* as is. IAM cannot be used for filtering; only tokens provide control.

The updated columns are also based on the same documentation.

In other words, the control previously written in code has been replaced by "target settings" and "service roles." While you no longer need to write code, you must understand for yourself whether the settings work as intended and where they don't. This article aims to verify the following three points:

Control What to verify Corresponding validation (number in the table below)
Pin If a different stateMachineArn is passed, is it denied as configured? What does the agent see? 1, 2
IAM Is referencing and stopping unauthorized executions denied by a policy filtered by the execution ARN? What is passed in includedData? 3, 4
Task Token Assuming filtering is not possible with IAM, how does the authorization flow work and what does the token control? 5

Conclusion

Issues Conclusion
What is now usable? With AgentCore Gateway's built-in connector (connectorId: "states"), existing Standard/Express state machines can be exposed as MCP tools without writing Lambda or custom MCP servers.
Division of Roles The agent decides "when and with what input to execute," and the state machine decides "which steps to execute and in what order." The agent cannot omit or rearrange steps.
Control is 3-tiered ① Pinning of the state machine, ② IAM policy of the gateway's service role, ③ Confidentiality of the task token. ① and ② are complementary, and ③ cannot be filtered with IAM.
Selection Criteria For tasks where you want to refer to and stop execution later, or where an audit trail is required, use Standard. If you only need the results synchronously, use Express (the author's interpretation derived from the verified constraints)
What was confirmed during verification Passing a pinned stateMachineArn is rejected, and the execution is not created. References and stops to unauthorized execution ARNs are rejected by IAM. Input and output are included in the response with includedData: ALL_DATA. Task tokens work with Resource: "*", and resending used tokens fails. Execution of state machines not exposed to the gateway can also be completed if a token is available. Standard/Express constraint errors occur as shown in the official table

The sources for "What is now available," "Roles and responsibilities," and "3-tier control" are the official documentation listed in the prerequisites section.

Verification Environment

Item Content
Region ap-northeast-1 (Tokyo)
Gateway AWS_IAM authorization. Main targets are hello and approval. Added express and wrongtype for Express verification
State Machine 4 Standard (AgentHelloWorld, AgentOtherWorkflow, ApprovalWorkflow, UnexposedApproval), 1 Express (AgentExpressWorkflow)
Caller awscurl (SigV4 signature. AWS request signing scheme). Sent the same MCP JSON-RPC request that the agent sends directly.
Tools AWS CLI 2.34.24 (updated to 2.39.3 during verification. See below), Python 3.12, awscurl 0.44

As a prerequisite, this assumes readers understand IAM roles, the basics of Step Functions, and JSON-RPC used for MCP communication (tools/list to get a list of tools and tools/call to call tools). It is based on the same configuration as the official tutorial. We added a state machine that is not exposed for checking IAM rejections, SQS and workflows for the authorization flow, and an Express state machine to verify the differences between Standard and Express.

Overall Structure

flowchart LR
A["Agent<br/>(Strands / LangGraph, etc.)"] -- "MCP<br/>tools/list, tools/call" --> G["AgentCore Gateway<br/>Step Functions Connector"]
G -- "Authenticate with Service Role<br/>Merge Fixed Parameters" --> S["Step Functions<br/>State Machine"]

According to the official documentation, the process flow is as follows:

# Content
1 Add a target with connectorId: "states" to the gateway and select the operations to be tooled. Pin the stateMachineArn to the corresponding ones. The gateway takes a snapshot of the tool schema.
2 When the agent calls tools/list, one tool is visible for each configured operation. Pinned parameters do not appear in the schema (e.g., StartExecution only has input).
3 When the agent calls tools/call, the gateway merges the pinned parameters and arguments and calls Step Functions in the service role.
4 The Step Functions API response is returned as a JSON string in content[].text. In case of an error, isError: true is returned, and the Step Functions error name is inserted (in verification, the error name was returned at the beginning of the body; see below).
5 The agent chains the tools. A typical example is StartExecution → DescribeExecution → GetExecutionHistory.

Source: AWS Step Functions as Connector Target

Calling tools/list returned the tools for the 6 configured operations in alphabetical order (not configuration order). The tool names are in the form of the target name followed by ___ (three underscores), such as hello___DescribeExecution. The input schema for hello___StartExecution was only input; stateMachineArn was not visible.

10 Operations Exposed by the Connector

According to the official documentation, the connector (version 1.0.0) exposes 10 operations. These are broadly divided into "4 that can be pinned to the state machine" and "6 that the agent passes identifiers to."

4 Pinnable Operations

Operation Role Fields Visible to Agents by Default Additional Fields That Can Be Exposed Corresponding Workflow
StartExecution Starts the state machine. The returned executionArn allows tracking the state later. input (JSON string) name, traceHeader Standard / Express
StartSyncExecution Starts Express, waits for completion, and returns the result in the same call. input name, traceHeader Express only
ListExecutions Returns a list of state machine executions. Filter by status statusFilter maxResults, nextToken Standard only
DescribeStateMachine Returns the state machine definition, role, and settings includedData None Standard / Express

Six identifiers the agent passes (not PINnable)

Operation Role Identifier to pass Default field Additional fields that can be exposed Corresponding workflow
DescribeExecution Returns the execution status (success, failure, etc.) and start/end times. ALL_DATA returns input and output as well executionArn executionArn, includedData None Standard execution only
StopExecution Stops execution in progress executionArn executionArn error, cause Standard execution only
GetExecutionHistory Returns execution event history (events at each step) executionArn executionArn includeExecutionData, maxResults, reverseOrder, nextToken Standard execution only
SendTaskSuccess Restarts a task awaiting approval as successful taskToken taskToken, output None Standard / Express
SendTaskFailure Terminates a task awaiting approval as failed taskToken taskToken, error, cause None Standard / Express
SendTaskHeartbeat Indicates a long task and prevents timeout taskToken taskToken None Standard / Express

To show additional fields, specify visible: true in parameterOverrides for that operation. Only stateMachineArn cannot be exposed via parameterOverrides and can only be specified via pinning.

includedData for DescribeExecution and DescribeStateMachine defaults to METADATA_ONLY. Specifying ALL_DATA includes the execution's input/output and state machine definition.

Testing revealed that the response with includedData omitted was identical to the response with METADATA_ONLY specified. When DescribeStateMachine is called with METADATA_ONLY, definition is returned as "{}" (empty), and ALL_DATA contains the entire definition.

Differences between Standard and Express (Pitfalls)

The following errors are limitations of Step Functions, not connector bugs.

Operation Usable Types Using Different Types
StartSyncExecution Express only Fails in Standard. Use polling with StartExecution and DescribeExecution.
ListExecutions Standard only StateMachineTypeNotSupported in Express.
DescribeExecution / GetExecutionHistory / StopExecution Standard execution only InvalidArn in Express execution ARN (because it cannot be handled by ARN after start).
StartExecution / DescribeStateMachine / SendTask* Both -
  • If you want both types to coexist in one target, fix StartSyncExecution to Express and other pinable operations to Standard.

  • The callback pattern (.waitForTaskToken) is only supported by Standard. Express does not support it.

  • These constraints are written in the tool descriptions returned by tools/list, allowing the agent to select the appropriate tool.

Source: AWS Step Functions as Connector Target

Looking at the descriptions in tools/list, four tools—DescribeExecution, GetExecutionHistory, ListExecutions, and StopExecution—state "Standard workflows only." ListExecutions also states that it will fail with StateMachineTypeNotSupported in Express. StartExecution and DescribeStateMachine have no listed constraints, corresponding to their usability with both types.

Furthermore, an Express state machine was prepared to actually generate the behavior shown in the table above.

Operation Result
StartSyncExecution on the Standard state machine StateMachineTypeNotSupported (This operation is not supported by this type of state machine)
StartSyncExecution on the Express state machine Success. The response contains status, output, and billingDetails.
ListExecutions on the Express state machine StateMachineTypeNotSupported
Pass the execution ARN obtained from Express's StartExecution to DescribeExecution, GetExecutionHistory, and StopExecution All three return InvalidArn (Resource type not valid in this context: express)
Create an Express state machine with a definition including .waitForTaskToken InvalidDefinition (Express state machine does not support '.waitForTaskToken' service integration)

This matches the official table. The official documentation only states that StartSyncExecution directed to Standard "fails," but the actual error name was StateMachineTypeNotSupported. Furthermore, the execution ARN for Express is returned as express:<state machine name>:..., a different resource type from Standard's execution:. In this case, we also allowed express:AgentExpressWorkflow:* via IAM and confirmed that Step Functions returned InvalidArn instead of IAM denial.

When Express is exposed, the agent cannot check its status, view its history, or stop after startup (as verified above, all three return InvalidArn). If the requirement is to "trace execution later," choosing Standard is the safer option (my interpretation).

Control Design: What to Allow the Agent

This is the core of this article. The official documentation explains controls in two layers: "pins" and "IAM." The two are complementary, not interchangeable (Source: AWS Step Functions as Connector Target).

Figure 1: How to restrict agent permissions (1: Pinning, 2: IAM for service roles, 3: Task tokens)

stepfunctions-agentcore-gateway-governance.png

Control Scope of Effect Notes
Pinning (stateMachineArn Pinning) StartExecution, StartSyncExecution, ListExecutions, DescribeStateMachine Agents cannot change this target. The gateway denies it.
Gateway Service Role IAM Policy Six Cannot-Pin DescribeExecution / StopExecution / GetExecutionHistory can be narrowed down to the execution ARN of the state machine to be exposed.
Task Token Concealment SendTaskSuccess / SendTaskFailure / SendTaskHeartbeat IAM does not have resource-level permissions and allows with "*". Any agent with a valid token can complete the task.

① Pinning

Pinned parameters are removed from the tool schema and enforced in all calls. When the agent passes stateMachineArn, it is rejected with the following error:

Invalid request parameters: cannot set parameter(s): [/stateMachineArn]
Enter fullscreen mode Exit fullscreen mode

I tried passing the ARN of a different state machine (AgentOtherWorkflow) as stateMachineArn. isError: true returned the following, and the execution was not created. The wording is the same as in the official documentation, but with the error name at the beginning.

IllegalArgumentException - Invalid request parameters: cannot set parameter(s): [/stateMachineArn]
Enter fullscreen mode Exit fullscreen mode

The error name is IllegalArgumentException, which differs in format from the IAM rejection (Step Functions error wrapped in DependencyFailedException) described later. The pin violation can be interpreted as the gateway rejecting the Step Functions before it is called (my interpretation).

The official documentation includes the following cautionary note:

  • Only one pin is allowed per operation. If you want to expose multiple state machines with the same operation, separate the targets.

  • Even if you forget to set parameterValues.stateMachineArn in the operation you want to pin, the target itself can still be created. However, the tool will fail every time because the state machine is not passed.

② Service Role IAM Policy

The three operations that cannot be pinned, such as DescribeExecution, operate on the execution ARN passed by the agent. The IAM policy for the service role is what restricts this.

Since the execution ARN is a different resource type from the state machine ARN, the policy in the official tutorial is divided into two statements (Source: Tutorial).

{ 
"Version": "2012-10-17", 
"Statement": [ 
{ 
"Sid": "StateMachineOperations", 
"Effect": "Allow", 
"Action": [ 
"states:StartExecution", 
"states:ListExecutions", 
"states:DescribeStateMachine" 
], 
"Resource": "arn:aws:states:<region>:<account-id>:stateMachine:AgentHelloWorld" 
}, 
{ 
"Sid": "ExecutionOperations", 
"Effect": "Allow", 
"Action": [ 
"states:DescribeExecution", 
"states:GetExecutionHistory", 
"states:StopExecution" 
], 
"Resource": "arn:aws:states:<region>:<account-id>:execution:AgentHelloWorld:*" 
} ]
}
Enter fullscreen mode Exit fullscreen mode

The trust policy trusts bedrock-agentcore.amazonaws.com while filtering by aws:SourceAccount and aws:SourceArn (gateway/...).

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "bedrock-agentcore.amazonaws.com" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "aws:SourceAccount": "<account-id>" },
"ArnLike": {
"aws:SourceArn": "arn:aws:bedrock-agentcore:<region>:<account-id>:gateway/step-functions-gateway-*"

}
}
}
]
}
Enter fullscreen mode Exit fullscreen mode

With the above policy (only allowing execution ARNs for AgentHelloWorld) applied, I passed execution ARNs for AgentOtherWorkflow, which are not permitted, to DescribeExecution, GetExecutionHistory, and StopExecution. All three were rejected. Execution of AgentHelloWorld, which is permitted, could be accessed. The rejection of DescribeExecution is as follows (account IDs, etc., have been omitted):

DependencyFailedException - {"errorType":"com.amazon.coral.service#AccessDeniedException","errorMessage":"User: arn:aws:sts::<account-id>:assumed-role/AgentCoreGatewayToStepFunctions/gateway-session-invocation is not authorized to perform: states:DescribeExecution on resource: arn:aws:states:<region>:<account-id>:execution:AgentOtherWorkflow:<execution-id> because no identity-based policy allows the states:DescribeExecution action","statusCode":400,"service":"states","operation":"DescribeExecution"}
Enter fullscreen mode Exit fullscreen mode

Two points can be inferred:

  • The denial is occurring during the Step Functions IAM evaluation ("service":"states"). The error name is wrapped in DependencyFailedException, so the agent needs to read the JSON inside.
  • The caller is the service role assumed-role/.../gateway-session-invocation. The session name is fixed, and it's not possible to tell from this message which agent or user made the call.

The next two screenshots are from after adding the approval workflow (ApprovalWorkflow) in Verification 5. Therefore, Resource contains both AgentHelloWorld and ApprovalWorkflow.

Figure 2: Inline Policy for Service Roles (StateMachineOperations: Allowed by State Machine ARN)

13_AllowedPolicy.png

Figure 3: Inline Policy for Service Roles (ExecutionOperations: Allowed by Execution ARN)
12_AllowedPolicy.png

Targets on the same gateway share the service role. If you want to change IAM boundaries for each workflow, separate the gateways.

③ Task Token

The three functions SendTaskSuccess, SendTaskFailure, and SendTaskHeartbeat cannot be restricted to specific executions via IAM (Source: AWS Step Functions as Connector Target). Therefore, the task token itself is the sole control. Treat the token as sensitive information and deliver it only to the agent that should process it.

When the service role was allowed states:SendTaskSuccess and two other states with Resource: "*" (see screenshot below), SendTaskSuccess via the gateway succeeded. Resending the token for a completed task failed with TaskTimedOut (Provided task does not exist anymore).

Figure 4: Service Role Inline Policy (TaskTokenOperations: Allow SendTask* with Resource: "*")

11_Allow Policy.png

Furthermore, I directly launched an execution from the CLI using a state machine (UnexposedApproval) that was not exposed to any gateway targets. Passing that token to SendTaskSuccess via the gateway resulted in SUCCEEDED. Random tokens were rejected with InvalidToken. Since it cannot be filtered by PIN or IAM, if you have the token, you can complete the execution even of a state machine not exposed to the gateway.

Figure 5: Graph view of a state machine not exposed to the gateway (UnexposedApproval) (after SendTaskSuccess via the gateway. All steps were successful)

15_StepFunctions.png

Figure 6: Event history of the same execution (from TaskSucceeded to ExecutionSucceeded)

16_StepFunctions.png

Summary of Control Design

Requirements Controls to be Used
Limit the workflows that can be launched Pinning
Limit the scope of executions that can be viewed and stopped IAM policy for service role (scoped by execution ARN)
Pass tasks that can be resumed later, such as manual approval Limit the destination of task token delivery (cannot be narrowed down with IAM)
Separate permission boundaries for each workflow Separate gateways (because the service role is shared)

Operational Perspective

Perspective Content
Recording the Caller Execution via the gateway results in the gateway's service role being the caller on CloudTrail (Source: Tutorial). In the actual event, the userIdentity of the StartExecution event was AssumedRole (assumed-role/AgentCoreGatewayToStepFunctions/gateway-session-invocation), and invokedBy was bedrock-agentcore.amazonaws.com.
Identifying Who Initiated It Since the caller is the gateway's role, it's not possible to distinguish "which agent/user initiated it" using CloudTrail alone. From what I could see, the session name was fixed as gateway-session-invocation, and there were no fields indicating the gateway ID or the calling agent/user. Also, requestParameters.input was replaced with HIDDEN_DUE_TO_SECURITY_REASONS, and the contents of the input were not recorded in CloudTrail. Therefore, even if you put a user ID in the execution's input, it cannot be tracked in CloudTrail. On the other hand, responseElements.executionArn is recorded, so you can identify the execution from the CloudTrail event and check the input in the Step Functions execution history.
Input/Output Exposure Allowing includedData: ALL_DATA means that the execution's input/output is passed to the agent (LLM context). Handle with caution in workflows that contain personal information. In my tests, executing an input of approximately 400 characters resulted in a response of 674 characters (default: METADATA_ONLY) to 1410 characters (ALL_DATA), with the input JSON (simulated data including customer ID and address) and output being included as is.

The StartExecution event via the gateway is as follows (account ID and other details have been masked):

{ 
"eventVersion": "1.11", 
"userIdentity": { 
"type": "AssumedRole", 
"principalId": "AROA****************:gateway-session-invocation", 
"arn": "arn:aws:sts::<account-id>:assumed-role/AgentCoreGatewayToStepFunctions/gateway-session-invocation", 
"accountId": "<account-id>", 
"accessKeyId": "ASIA****************", 
"sessionContext": { 
"sessionIssuer": { 
"type": "Role", 
"principalId": "AROA****************", 
"arn": "arn:aws:iam::<account-id>:role/AgentCoreGatewayToStepFunctions", 
"accountId": "<account-id>", 
"userName": "AgentCoreGatewayToStepFunctions" 
}, 
"attributes": { 
"creationDate": "2026-11-01T11:28:30Z", 
"mfaAuthenticated": "false" 
} 
}, 
"invokedBy": "bedrock-agentcore.amazonaws.com" 
}, 
"eventTime": "2026-11-01T11:28:30Z", 
"eventSource": "states.amazonaws.com", 
"eventName": "StartExecution", 
"awsRegion": "ap-northeast-1", 
"sourceIPAddress": "bedrock-agentcore.amazonaws.com", 
"userAgent": "bedrock-agentcore.amazonaws.com", "requestParameters": { 
"stateMachineArn": "arn:aws:states:ap-northeast-1:<account-id>:stateMachine:AgentHelloWorld", 
"input": "HIDDEN_DUE_TO_SECURITY_REASONS" 
}, 
"responseElements": { 
"executionArn": "arn:aws:states:ap-northeast-1:<account-id>:execution:AgentHelloWorld:<execution-id>", 
"startDate": "2026-11-01T11:28:30Z" 
}, 
"requestID": "<request-id>", 
"eventID": "<event-id>", 
"readOnly": false, 
"eventType": "AwsApiCall", 
"managementEvent": true, "recipientAccountId": "<account-id>", 
"eventCategory": "Management"
}
Enter fullscreen mode Exit fullscreen mode

The userIdentity session name is fixed as gateway-session-invocation, and invokedBy is bedrock-agentcore.amazonaws.com. There are no fields in this event indicating which agent or user made the call.

Two Patterns of Agent and Workflow Collaboration

According to the official documentation, there are two ways for agents and workflows to collaborate (Source: AWS Step Functions as Connector Target).

Pattern A: Agent Starts and Monitors Workflow

StartExecution → DescribeExecution (polling) → GetExecutionHistory → (if necessary) StopExecution. If synchronous execution is acceptable, use StartSyncExecution in Express.

Pattern B: Workflow waits for agent work (Human-in-the-loop)

# Content
1 Pause a Standard task with .waitForTaskToken, and Step Functions issues a task token.
2 The workflow sends the token and task details to the agent's app (e.g., SQS queue, Activity the app polls).
3 The agent works and resumes with SendTaskSuccess (result) or SendTaskFailure. Long tasks are indicated as alive with SendTaskHeartbeat.

Token delivery is the responsibility of the workflow. The gateway does not handle delivery.

Figure 7: Flow of the Human Approval (Callback) Pattern (State machine sends a token to SQS and stops, agent restarts with SendTask*)

stepfunctions-agentcore-gateway-human-approval.png

We confirmed the following flow in the Standard workflow (ApprovalWorkflow) which sends a token to SQS using .waitForTaskToken and waits.

# Operation Result
1 Started with approval___StartExecution (input is {"requestId":"refund-1001","amount":3000}) Execution stopped at RUNNING. It had progressed to TaskSubmitted (sqs:sendMessage)
2 Received a message from SQS The body has two keys: Request (input for execution) and TaskToken (656 characters)
3 Passed taskToken and output (JSON string) to approval___SendTaskSuccess Success (response is {}). Both arguments are required
4 Confirmed with approval___DescribeExecution (ALL_DATA) SUCCEEDED. The output sent was {"approved":true,"approver":"agent"}

The part where the workflow sends a token to SQS, and the application reads it and passes it to the agent, does not involve the gateway. In this case, I retrieved the token from SQS and passed it to the agent.

Figure 8: ApprovalWorkflow event history (waiting. Stopped by sqs:sendMessage TaskSubmitted)

3_TaskScheduled.png

Figure 9: ApprovalWorkflow graph view (after SendTaskSuccess. All steps were successful)

4_TaskCompletion.png

Figure 10: ApprovalWorkflow event history (after completion. From TaskSucceeded to ExecutionSucceeded)

5_TaskCompletionDetails.png

Minimum Configuration Requirements

This summarizes the flow of the official tutorial. For details, please refer to the Tutorial.

# Create Gateway (AWS_IAM Authorization)
aws bedrock-agentcore-control create-gateway \
--name "step-functions-gateway" \
--protocol-type MCP \
--authorizer-type AWS_IAM \
--role-arn "arn:aws:iam::<account-id>:role/AgentCoreGatewayToStepFunctions" \
--region <region>
Enter fullscreen mode Exit fullscreen mode

# Add Target (After READY)
aws bedrock-agentcore-control create-gateway-target \
--gateway-identifier "<GATEWAY_ID>" \
--name "hello" \
--target-configuration '{
"mcp": {
"connector": {
"source": { "connectorId": "states" },
"configurations": [
{ "name": "StartExecution",

"parameterValues": { "stateMachineArn": "arn:aws:states:<region>:<account-id>:stateMachine:AgentHelloWorld" } }, 
{ "name": "ListExecutions", 
"parameterValues": { "stateMachineArn": "arn:aws:states:<region>:<account-id>:stateMachine:AgentHelloWorld" } }, 
{ "name": "DescribeStateMachine", 
"parameterValues": { "stateMachineArn": "arn:aws:states:<region>:<account-id>:stateMachine:AgentHelloWorld" } }, 
{ "name": "DescribeExecution" }, 
{ "name": "GetExecutionHistory" }, 
{ "name": "StopExecution" } 
] 
} 
} 
}' \ 
--credential-provider-configurations '[{"credentialProviderType": "GATEWAY_IAM_ROLE"}]' \
--region <region>
Enter fullscreen mode Exit fullscreen mode

In the testing environment for this article (AWS CLI 2.34.24), the above target addition command failed with the following error: The CLI does not recognize a targetConfiguration of type connector.

Unknown parameter in targetConfiguration.mcp: "connector", must be one of: openApiSchema, smithyModel, lambda, mcpServer, apiGateway
Enter fullscreen mode Exit fullscreen mode

After updating AWS CLI to 2.39.3 and running the same command again, a target of type connector was created. The output of get-gateway-target also showed connectorId: "states" and version: "1.0.0". get-gateway-target in version 2.34.24 only displayed SDK_UNKNOWN_MEMBER for the connector. It's safer to keep the AWS CLI updated when using connectors (the same API worked with boto3 1.43.91).

In the console, this target displayed "Target Type: Step Functions" and its status was Ready. However, connector settings such as the pinned stateMachineArn are not displayed in the console (even expanding "Additional Settings" only shows the authentication grant type). Pinning settings can be checked with the CLI's get-gateway-target (2.39.3).

Figure 11: Gateway target list (hello and approval. Target type is "Step Functions", inbound authentication is "IAM"). (Permission granted)
7_AgentCoreGateway(target).png

Figure 12: Gateway Details (Name, ID, URL, Status "Ready")

8_AgentCoreGateway(gaiyou).png

  • The gateway and state machine are created in the same region. The gateway calls Step Functions in its own region.

  • For AWS_IAM authorization, the caller's identity must have the bedrock-agentcore:InvokeGateway permission and a SigV4 signature.

  • The tool name is prefixed with the target name. The example in the tutorial is hello___StartExecution (three underscores).

Actual Verification Content and Results

We verified eight items that could not be gleaned from the official documentation or that we wanted to verify ourselves. Items 1-5 are specific to the Step Functions connector, and items 6-8 are additional verifications. Requests are sent directly to the gateway using awscurl as JSON-RPC (no agent framework is used).

# What to Verify Verification Method Results
1 Actual tool descriptions and schemas visible in tools/list Calling tools/list with awscurl 6 tools. stateMachineArn is private. 4. The description of the tool states "Standard workflows only"
2 Rejection when passing pinned parameters Specifying the ARN of another state machine as stateMachineArn in tools/call Rejected with IllegalArgumentException - ... cannot set parameter(s): [/stateMachineArn]. No execution is created.
3 Does includedData: ALL_DATA change the amount of information passed to the agent? Calling DescribeExecution with omission, METADATA_ONLY, or ALL_DATA Omission and METADATA_ONLY are the same (674 characters). ALL_DATA adds input and output, resulting in 1410 characters
4 An IAM policy restricting execution ARNs denies execution on another state machine Calling DescribeExecution, GetExecutionHistory, and StopExecution with an unauthorized execution ARN All three are denied with AccessDeniedException (wrapped in DependencyFailedException)
5 An authorization flow combining .waitForTaskToken and SQS A callback is set in Standard, and resumed with SendTaskSuccess Stopped with RUNNING → Token obtained from SQS → SUCCEEDED with SendTaskSuccess. Resending a used token results in TaskTimedOut
6 Standard / Express constraint error Call an Express state machine with a different type target StateMachineTypeNotSupported, InvalidArn, Express's .waitForTaskToken is InvalidDefinition upon creation. As per the official table
7 Will a token from another execution (a state machine not exposed to the gateway) work? Start an execution of a state machine that is not exposed using CLI and pass its token to SendTaskSuccess SUCCEEDED. A nonsensical token is InvalidToken
8 How the caller appears in CloudTrail Check the StartExecution event with lookup-events Fixed to AssumedRole and session name gateway-session-invocation. No fields to distinguish between agent or user are found. input is replaced with HIDDEN_DUE_TO_SECURITY_REASONS and is not recorded. executionArn is recorded.

After verification, please clean up using the procedure in Step 6 of the tutorial (delete in the following order: Target → Gateway → State Machine → IAM Role). In this article's verification, we also created an SQS queue and an execution role for authorization, so we deleted those as well.

Pricing

The official documentation does not mention any dedicated additional fees; the standard rates for Step Functions (state transitions) and AgentCore Gateway (tool invocation) apply. Unit prices are omitted in this article. Please check the latest unit prices on the respective pricing pages.

In conclusion

This connector achieves the separation of "fixing the procedure and leaving only the decision to launch to the agent" without additional code. However, the moment it's tooled, agent operations converge at a single permission entry point: the service role. Understanding what can and cannot be restricted in PINs, IAM, and task tokens, and then minimizing the operations to expose, seems to be key to using this feature in practice.

In the verification so far, it worked as described in the official documentation. If a different stateMachineArn is passed to the PIN, it is rejected by the gateway, and the execution is not created. The IAM in the service role denies access to or stopping of execution ARNs that are not permitted by Step Functions using AccessDenied. On the other hand, task tokens must be allowed via Resource: "*", and this cannot be filtered through IAM. In fact, even state machine execution not exposed to the gateway could be completed with a token. However, the methods of denial differ between PIN and IAM (IllegalArgumentException and AccessDenied wrapped in DependencyFailedException). The caller is also fixed as gateway-session-invocation. These two points need to be kept in mind when designing error handling and auditing on the agent side.

If you are going to use this going forward, it seems safest to proceed in the following order (my interpretation):

  • First, expose only the start and reference operations (StartExecution, DescribeExecution, etc.), and pin the state machine.
  • Since SendTask* requires Resource: "*", expose only the necessary workflows, such as those requiring manual approval, on a separate gateway (because targets on the same gateway share the service role).
  • Workflows containing personal information in input and output should be exposed after confirming the content passed to the agent with includedData: ALL_DATA.

References

Presentation

https://aws.amazon.com/about-aws/whats-new/2026/10/step-functions-workflows-ai-agent-tools/

Documentation

https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-agentcore-gateway.html

https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-target-connector-step-functions.html

https://docs.aws.amazon.com/step-functions/latest/dg/use-cases.html

https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-add-target-api-target-config.html#gateway-add-target-api-connector-step-functions

https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-agent-integration.html

Related (Reverse integration: calling an agent from a workflow)

https://docs.aws.amazon.com/step-functions/latest/dg/connect-bedrockagentcore.html

https://aws.amazon.com/about-aws/whats-new/2026/06/aws-step-functions-agentcore/

Top comments (0)