Describe the bug
After creating a restricted API with amplify cli, I'm calling the API with Amplify JS and I get Access Denied exception Could not load items: AccessDeniedException: User: arn:aws:sts::92xxxxx:assumed-role/serverlessreactLambdaRolexxxxx/todos is not authorized to perform: dynamodb:Query on resource: arn:axxxxxxx. This happens for all HTTP method.
To Reproduce
Steps to reproduce the behavior:
Here's the output of calling amplify add which indicates how i've generated the services.
? Please select from one of the below mentioned services REST
? Provide a friendly name for your resource to be used as a label for this category in the project: todosApi
? Provide a path (e.g., /items) /items
? Choose a Lambda source Create a new Lambda function
? Provide a friendly name for your resource to be used as a label for this category in the project: todosLambda
? Provide the AWS Lambda function name: todos
? Choose the function template that you want to use: CRUD function for Amazon DynamoDB table (Integration with Amazon API Gateway and
Amazon DynamoDB)
? Choose a DynamoDB data source option Create a new DynamoDB table
Welcome to the NoSQL DynamoDB database wizard
This wizard asks you a series of questions to help determine how to set up your NoSQL database table.
? Please provide a friendly name for your resource that will be used to label this category in the project: todosTable
? Please provide table name: todos
You can now add columns to the table.
? What would you like to name this column: id
? Please choose the data type: string
? Would you like to add another column? true
? What would you like to name this column: content
? What would you like to name this column: content
? Please choose the data type: (Use arrow keys)
? Please choose the data type: string
? Would you like to add another column? true
? What would you like to name this column: dateCreated
? What would you like to name this column: dateCreated
? Please choose the data type: (Use arrow keys)
? Please choose the data type: string
? Would you like to add another column? true
? What would you like to name this column: completed
? What would you like to name this column: completed
? Please choose the data type:
? Please choose the data type: boolean
? Would you like to add another column? false
Before you create the database, you must specify how items in your table are uniquely organized. You do this by specifying a primary key. The primary key uniquely identifies each item in the table so that no two items can have the same key. This can be an individual column, or a combination that includes a primary key and a sort key.
To learn more about primary keys, see:
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey
? Please choose partition key for the table:
? Please choose partition key for the table: id
? Do you want to add a sort key to your table? false
You can optionally add global secondary indexes for this table. These are useful when you run queries defined in a different column than the primary key.
To learn more about indexes, see:
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.SecondaryIndexes
? Do you want to add global secondary indexes to your table? (Y/n) n
? Do you want to add global secondary indexes to your table? false
Succesfully added DynamoDb table locally
? Do you want to edit the local lambda function now? (Y/n) n
? Do you want to edit the local lambda function now? false
Succesfully added the Lambda function locally
? Restrict API access (Y/n) Y
? Restrict API access Yes
? Who should have access?
? Who should have access? Authenticated and Guest users
? What kind of access do you want for Authenticated users
? What kind of access do you want for Authenticated users read/write
? What kind of access do you want for Guest users
? What kind of access do you want for Guest users read
Successfully added auth resource locally.
? Do you want to add another path? (y/N) N
? Do you want to add another path? No
Successfully added resource todosApi locally
Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
Here's my App.js
import Amplify, { API } from "aws-amplify";
import aws_exports from "./aws-exports";
import { withAuthenticator } from "aws-amplify-react";
Amplify.configure(aws_exports);
.....
handleSubmit = async event => {
event.preventDefault();
console.log("calling api");
const response = await API.post("todosApi", "/items", {
body: {
id: Date.now(),
content: this.state.content
}
});
console.log(response);
alert(JSON.stringify(response, null, 2));
};
I've followed the docs.
I get AccessDenied Exception. User: arn:aws:sts::xxxxxx:assumed-role/serverlessreactLambdaRoleb4xxxxd/todos is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:ap-south-1:xxxxxxxxxx.....
Expected behavior
I expect authenticated users to read/write to the DB and unauthenticated to on read data.
Additional context
amplify cli version 0.1.33
@pmbanugo Looks like you're making a putCall as an unauthenitcated user. When you were provisioning the API, you have the Unauthenticated user just read access and thats why the 'putItem' call which is a write operation is failing.
@kaustavghosh06 I don't think so. With the code i've shared before, isn't that the right way to make an authenticated call? I've wrapped the component in withAuthenticator so i signed in before making that request. Even making a get fails with AccessDenied like
```
"Could not load items: AccessDeniedException: User: arn:aws:sts::92xxxxxxxx:assumed-role/serverlessreactLambdaRoleb49dxxx/todos
is not authorized to perform: dynamodb:Query on resource: arn:aws:dynamodb:ap-south-1:9xxxxxxx0:table/todosTable"
````
@pmbanugo Okay, that's odd. Let me investigate and try reproducing it.
maybe the lambda role is not permitted to call the dynamodb, or the setup with cognito isn't giving the right IAM role or permission.
Can you check in your Lambda console if it has the appropriate Execution role?
@kaustavghosh06 It has a role and that role when i look at IAM role, it has just the lambda-execution-policy policy

@kaustavghosh06 I assume that that inline policy with read/write access to dynamodb should work. That's what was created when i ran amplify push. If I attach the AmazonDynamoDBFullAccess policy i don't get the Error anymore. But I notice another bug in the scaffolded lambda code. In app.js, the tableName variable has the value todosTable which I entered as the resource name rather than todos which I specified as the table name and it's also what it names the table that was created.
This leaves 2 bugs. The first being using the right policy for the IAM role when the cloudformation template is generated.. The second being the tableName variable in the lambda's app.js to use the table name and not resource name
@pmbanugo These issues seemed to be fixed in the latest version of the CLI. Please feel free to re-open the issue if you're still facing the issue.
I noticed the same behavior with CLI version 0.1.43
the app.js of the lambda function has the resource name instead of the table name. Have to manually update the file and do amplify push to make it work.
I also had the same experience, same cli version (0.1.43), and the same fix.
Updated /amplify/backend/function/ToDoItemsLambda/src/app.js
let tableName = "dynamoToDoItems";
to
let tableName = "ToDoItems";
where dynamoToDoItems was my resource name and ToDoItems was my table name.
That, along with
amplify push
got it working properly.
Obviously this is specific to my environment but it's a specific resolution that will hopefully help. I was running through the "Building Ionic 4 apps with AWS Amplify" tutorial when I ran into this.
We are on AWS Amplify v1.12.0 and still remains the same error! But anyway I really went to the deepest of unknown to find you guys... LOL. Finally, I could complete my REST CRUD API using Lambda and DynamoDB. Thank you so much! =)
Ohhh... I just followed your tips @pmbanugo and @sky-c ! Tks
Most helpful comment
I also had the same experience, same cli version (0.1.43), and the same fix.
Updated /amplify/backend/function/ToDoItemsLambda/src/app.js
let tableName = "dynamoToDoItems";to
let tableName = "ToDoItems";where dynamoToDoItems was my resource name and ToDoItems was my table name.
That, along with
amplify pushgot it working properly.
Obviously this is specific to my environment but it's a specific resolution that will hopefully help. I was running through the "Building Ionic 4 apps with AWS Amplify" tutorial when I ran into this.