Architect Data Action calling Lambda returns 403 Forbidden with correct IAM policy

Stuck on getting an Architect Data Action to invoke a Lambda function. The setup looks correct on paper, but the invocation keeps failing with a 403 Forbidden error from AWS.

We have a custom Data Action in Architect configured to hit a Lambda endpoint via HTTPS POST. The payload is simple JSON. The Lambda function works fine when invoked directly in the AWS console or via the CLI.

Here is the IAM policy attached to the role that the Data Action is using to sign the request:

{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Effect": "Allow",
 "Action": "lambda:InvokeFunction",
 "Resource": "arn:aws:lambda:us-east-1:123456789012:function:MyIntegrationFunc"
 }
 ]
}

The Data Action configuration:

  • Method: POST
  • URL: https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/MyIntegrationFunc/invocations
  • Authentication: AWS Signature Version 4
  • Headers: Content-Type: application/json
  • Body: {"key": "value"}

Error response from the Data Action:

{
 "statusCode": 403,
 "headers": {
 "x-amzn-RequestId": "abc-123-def",
 "content-type": "application/json"
 },
 "body": "{\"message\": \"User: arn:aws:iam::123456789012:role/CXoneLambdaRole is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:123456789012:function:MyIntegrationFunc\"}"
}

Troubleshooting steps taken:

  • Verified the IAM role has the correct trust policy allowing cxone.amazonaws.com to assume it. Wait, does the Data Action use the role directly or assume it? The docs are vague on whether the Data Action uses the credentials directly or assumes a role.
  • Checked CloudTrail logs. The event shows the source IP as a CXone IP range. The error is clearly an IAM denial.
  • Tried adding lambda:InvokeAsync to the policy just in case. No change.
  • Confirmed the function name and ARN match exactly. No typos.
  • Tested with a different Lambda in the same region. Same 403.

Is there a specific permission boundary or SCP blocking this? Or am I misunderstanding how the Data Action signs the request? The role definitely exists and has the policy. The ARN in the error matches the resource in the policy.

What am I missing in the IAM setup?