500 Internal Server Error using DeleteItem from DynamoDB using API-Gateway - amazon-web-services

Steps to reproduce:
Create a new DynamoDB table Events with partition key id
Create a new item in Events with an id of 123456. All other fields are blank.
Create an API-Gateway. Create path of events and a resource of remove-event under it.
Create a method of POST. AWS Service, DynamoDB, , and an action of DeleteItem. Add an IAM role that has access to the Events table too.
Open postman. Fill out the authorization and add the following parameters:
POST https://<DB GOES HERE>.execute-api.us-east-2.amazonaws.com/prod/events/remove-event
In the body, put (This is following the provided sample request here):
{
"TableName": "Events",
"Key": {
"id": {
"S": "123456"
}
},
"ReturnValues": "NONE"
}
Finally, hit send.
{
"message": "Internal server error"
}
I have no idea what is causing this. Create, Update, and Read work with issue. It is ONLY Delete that fails.
EDIT: In case anyone is curious about my policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:*:<sensitive infomation>:*/*/*/*"
}
]
}
Removing this changes the 500 response to a 403, so this is not a policy issue.

Related

Appsync Query Returning Null with Cognito Auth

I'm trying to do some appsync in the console using a userpool user who is a part of the group.
However, my query is returning null in the response.
The below PK in my query definitely exists.
I suspect that the issue is related to cognito. I can't pin it down exactly. The user I am testing is in the customers group and I am not receiving an error there due to cognito group permissions.
Logs are not helpful.
If I create a new API in the console (using an API key rather than cognito for auth) and import the dynamodb table (using the same role), the same query returns data.
Do I need to give my cognito group a role that allows them to interact with appsync?
My query:
query MyQuery {
getTable(PK: "PRODUCT#cb699976-153c-4852-a455-bc9a7bce6a93", SK: "PRODUCT#BLEND") {
DK1
PK
SK
}
}
The response:
{
"data": {
"getTable": null
}
}
The Schema:
type Query {
getTable(PK: String!, SK: String!): Table
#aws_auth(cognito_groups: ["customers"])
}
type Table #aws_auth(cognito_groups: ["customers"]) {
DK1: String
PK: String!
SK: String!
}
iam role for dynamodb (least permission access is still todo)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": [
"arn:aws:dynamodb:us-east-1:blah_account:table/blah_table/index/GSI1",
"arn:aws:dynamodb:us-east-1:blah_account:table/blah_table"
]
}
]
}
appsync role trust relationship
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "appsync.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
appsync config ($ aws appsync get-graphql-api):
{
"graphqlApi": {
"name": "blah_dev_appsync",
"apiId": "blah",
"authenticationType": "AMAZON_COGNITO_USER_POOLS",
"userPoolConfig": {
"userPoolId": "us-east-1_blah",
"awsRegion": "us-east-1",
"defaultAction": "DENY"
},
"arn": "arn:aws:appsync:us-east-1:blah_id:apis/blah_",
"xrayEnabled": false
}
}
Can you check if there is a resolver attached to your (failing) Appsync API ?
If you have access to the web console look for this screen:
If there is nothing attached to getTable then that's probably why you are having null answers.
Resolvers Docs
Thanks to Ivan Caracamo's response, I learned that I needed to properly configure my resolvers.
I was able to get there with the resolver docs and this post.
Here's my request template
{
"version": "2017-02-28",
"operation": "GetItem",
"key": {
"PK": $util.dynamodb.toDynamoDBJson($ctx.args.PK),
"SK": $util.dynamodb.toDynamoDBJson($ctx.args.SK),
},
}
And here's my response template
$util.toJson($ctx.result)

S3 Create event notifcation to SQS "Unable to validate the following destionation configurations"

Using strictly the management console I created a new S3 bucket and SQS with the default settings. I am then trying to create a notification to SQS queue but whenever I try to create it, it fails with "Unable to validate the following destination configurations". After a couple of hours of searching this error seems mostly related to creating the resources in the wrong order or something with Cloudformation, but I am not using that. Also most of the docs describe connecting the S3 event to an SNS topic, not SQS. I have also spent a lot on time trying to figure out if its policy related. For my SQS policy I have added the following:
{
"Version": "2012-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "SQS:SendMessage",
"Resource": "arn:aws:sqs:eu-central-1:123:my-sqs",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "123"
},
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:::my-bucket"
}
}
}
]
}
Which I think is correct. But this did not help.
How can I get rid of this error and get it working?

Lambda is not authorized to perform: cognito-idp:AdminInitiateAuth

I am following AWS Cognito and API Gateway tutorials from part1, part 2 and part 3.
From part 1, I created the following lambdas:
signup
confirm signup
forgot pwd
resend verify code
successful registration
and each of these lambdas has a separate role automatically generated for them.
From part 2, I connected these lambdas to various API endpoints in API Gateway, with the /login route being connected to the "successful registration" lambda.
From the part 3 tutorial, I created a refresh_access_token lambda function and also the test_user. Then, in the API Gateway, I created a new resource /user/test-user and added a GET method, which I connected to the test_user lambda. (The refresh_access_token isn't connected to a route).
After that, I go to the Create a New authorizer section from part 3, and when I run the /login route, I end up getting the following error:
HTTP/1.1 200 OK
Date: Tue, 27 Oct 2020 19:42:15 GMT
Content-Type: application/json
Content-Length: 423
Connection: close
x-amzn-RequestId: 86e522e3-1843-4c05-8d70-c6731c5f110f
x-amz-apigw-id: VFezhGcvFiAFqOQ=
X-Amzn-Trace-Id: Root=1-5f987816-65f557256f2ccd172032ff15;Sampled=0
{
"message": "An error occurred (AccessDeniedException) when calling the AdminInitiateAuth operation: User: arn:aws:sts::xxxxxxxx:assumed-role/cognito-successful-registration-role-ck5hni20/cognito-successful-registration is not authorized to perform: cognito-idp:AdminInitiateAuth on resource: arn:aws:cognito-idp:eu-central-1:xxxxxxxx:userpool/eu-central-1_xxxx,
"error": true,
"success": false,
"data": null
}
The cognito-successful-registration-role-ck5hni20 just has AWSBasicExecutionRole attached to it and the trust relationship looks as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
What is the mistake I am doing here?
Locate the role cognito-successful-registration-role-ck5hni20 in AWS console. Once you do this, you can add an inline policy to in the following form:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "cognito-idp:AdminInitiateAuth",
"Resource": {
"AWS": "arn:aws:cognito-idp:eu-central-1:xxxxxxxx:userpool/eu-central-1_xxxx"
}
}
]
}
or use more general form:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "cognito-idp:AdminInitiateAuth",
"Resource": "*"
}
]
}
For people who are new to AWS like this, here is a more detailed solution:
go to your lambda function
Under configuration, click permission, and then you'll see Execution role and the corresponding role name.
click on role name
then edit the permission and add a new inline policy, as suggested by #Marcin.
finally, click create policy
I had a similar issue with AdminInitiateAuth, but mine was slightly different: Auth flow not enabled for this client.
I could not solve the issue with any kind of role, the problem was not with the function but with the Cognito client used in the login handler.
The solution was to go to the Cognito User Pool in the AWS Console, then to 'App clients' and to check the boxes for ALLOW_ADMIN_USER_PASSWORD_AUTH and ALLOW_USER_PASSWORD_AUTH

AWS/Cognito/IAM Error with Unauth role

This message was originally posted on the AWS Developer Forums, but it seems like the AWS crowd is on SO, so I'm duplicating it here.
Hi there, I'm an absolute AWS beginner so I'll try to be as clear as possible.
I'm trying to use the JS API to allow any user on my site to upload videos to S3 (this works well) and then convert the uploaded files to other formats (with Elastic Transcoder).
I've set up:
an input (not public) and an output (public) buckets on S3. The input receives the user-submitted videos, that part works :)
an Elastic Transcoder pipeline (video-converter-test-pipeline-01)
a federated identity on Cognito (video_converter_test_02)
matching Auth and Unauth roles on IAM (Cognito_video_converter_test_02Auth_Role and Cognito_video_converter_test_02Unauth_Role)
The pipeline has the following permission summary: "The following IAM roles have been granted access to this pipeline: arn:aws:iam::529773801731:role/Elastic_Transcoder_Default_Role"
Cognito_video_converter_test_02Unauth_Role has two attached policies:
oneClick_Cognito_video_converter_test_02Unauth_Role_1522923667877
video-converter-policy, that I made myself.
Here's its JSON representation:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "elastictranscoder:CreateJob",
"Resource": [
"arn:aws:elastictranscoder:*:*:pipeline/*",
"arn:aws:elastictranscoder:*:*:preset/*"
]
}
]
}
Here's how I try to create a transcoding job using the JS API:
function createJob(uploadedFileKey) {
console.log("Create job", uploadedFileKey);
var params = {
PipelineId: PipelineId,
Input: {
Key: uploadedFileKey
},
Output: {
PresetId: PresetId
}
};
elastictranscoder.createJob(params, function (err, data) {
if (err) console.error(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}
When executing it, I get the following error:
Error: User: arn:aws:sts::529773801731:assumed-role/Cognito_video_converter_test_02Unauth_Role/CognitoIdentityCredentials is not authorized to perform: elastictranscoder:CreateJob on resource: arn:aws:elastictranscoder:eu-west-1:529773801731:pipeline/1522763370759-mmowmr
I tried using IAM Policy Simulator to understand what was wrong, but when doing so with the same parameters, I get "allowed"...
I'm sure I'm doing something wrong here, but can't understand what. I've tried many things but nothing worked. Any help would be appreciated :)
Thanks in advance, bye!
I contacted AWS Developer Support and the solution seems to be to have these in the IAM Policy:
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": "cognito-sync:*",
"Resource": "*"
},
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": "mobileanalytics:PutEvents",
"Resource": "*"
}

How do I confirm a subscription created using CloudFormation?

I have created a CF script that creates an EC2 instance that contains a web service. It also creates an SNS Topic and a Subscription that uses this web service as it's http endpoint.
The script successfully creates the stack; the Topic and the Subscription exist. However, the Subscription remains in the PendingConfirmation state.
What must I do to get my script to confirm this Subscription upon creation?
I had a similar issue and my problem ended up being a misconfigured CloudFomation template. An AWS::SQS::QueuePolicy is required to give your SNS topic permission to send messages to the queue.
"SQSQueuePolicy": {
"Properties": {
"PolicyDocument": {
"Id": "usecase1",
"Statement": [
{
"Action": "SQS:SendMessage",
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"Ref": "SnsTopic"
}
}
},
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Resource": {
"Fn::GetAtt": [
"SqsQueue",
"Arn"
]
},
"Sid": "1"
}
],
"Version": "2012-10-17"
},
"Queues": [
{
"Ref": "SqsQueue"
}
]
},
"Type": "AWS::SQS::QueuePolicy"
}
You need to Subscribe to endpoint for this to work.
Read the value for SubscribeURL and visit that URL. To confirm the subscription and start receiving notifications at the endpoint, you must visit the SubscribeURLURL (for example, by sending an HTTP GET request to the URL)
When you visit the URL, you will get back a response that looks like the following XML document. The document returns the subscription ARN for the endpoint within the ConfirmSubscriptionResult element.
<ConfirmSubscriptionResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<ConfirmSubscriptionResult>
<SubscriptionArn>arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55</SubscriptionArn>
</ConfirmSubscriptionResult>
<ResponseMetadata>
<RequestId>075ecce8-8dac-11e1-bf80-f781d96e9307</RequestId>
</ResponseMetadata>
</ConfirmSubscriptionResponse>
As an alternative to visiting the SubscribeURL, you can confirm the subscription using the ConfirmSubscription action with the Token set to its corresponding value in the SubscriptionConfirmation message. If you want to allow only the topic owner and subscription owner to be able to unsubscribe the endpoint, you call the ConfirmSubscription action with an AWS signature.
You can Refer to this AWS Documentation
Hope this Helps!