AWS Cognito role restrict permissions to invoke Lambda - amazon-web-services

I have a Cognito Identity Pool with an Authenticated role with a policy applied as per below:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"execute-api:Invoke"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:ab:asdf:function:b",
"Effect": "Allow"
}
]
}
I have an API Gateway resource which has AWS_IAM Authorization applied.
Now this only gives access to invoke 1 specific lambda function.
However, I'm able to invoke other lambda functions, I am not restricted to this function only.
When I try the policy simulator, it states that other functions will be denied, however this is not the case.
I've confirmed that the request is assuming the correct role, this is what comes through in the request:
userArn: "arn:aws:sts::00000000:assumed-role/appAuthRole-dev/CognitoIdentityCredentials"
Why would this be?

Related

AWS IAM Pass Role Action Audit

Anyone knows how I can track if IAM pass role action (inside a role) is being used by any services or not? As per AWS document the "iam:PassRole" action is not tracked under IAM access advisor: Refining Permissions Using Service Last Accessed Data - AWS Identity and Access Management
I have this policy inside a IAM role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": "*"
}
]
}

update Route53 record set - cross account

Am facing an access issue when trying to update record set using lambda function.
Lambda - Account A
Route53 - Account B
I have an IAM role attached to lambda in Account A with an assume role permission to an IAM role in Account B. The IAM role in account B has access to update the record set in Account B.
When am triggering lambda, am receiving user is not authorized to access this resource.
Can someone help me, if i'm missing anything here or do I need any additional setup.
You are using a Lambda function in Account-A to call Route 53 in Account-B.
This will require:
An IAM Role (Role-A) in Account-A that is assigned to the Lambda function. It should grant permission to call AssumeRole(), with the Resource set to the ARN of Role-B in Account-B:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<Account-B>:role/role-b"
}
]
}
And with this Trust Relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
An IAM Role (Role-B) in Account-B that has permission to call Route 53. It should also have a trust policy allowing it to be assumed by Role-A in Account-A:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "route53:*",
"Resource": "*"
}
]
}
(This is an overly powerful policy. It would be better to limit it to the specific Route 53 actions that are required.)
And this Trust Relationship (pointing to the Role created in the previous step):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account-A>:role/role-a"
},
"Action": "sts:AssumeRole"
}
]
}
You need to use STS to get a token to call Route53 on Account B. Here are the docs on STS in boto3: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts.html#STS.Client.assume_role
You'll get back a credential that you will use to make the call to Route53.

How to configure AWS API Gateway to access it from another AWS account

I want to give access to IAM users from other accounts to be able to invoke my API.
I have these configurations in my API Gateway resource methods:
Authorization type: AWS_IAM (I tried with Auth type None as well..)
And Resource Policy defined as:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<ACCOUNT_2>:user/ApiUser"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-west-2:<ACCOUNT_1>:<API_ID>/*/*/*"
}
]
}
I have also given invoke permissions to the IAM user of the other account:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": "arn:aws:execute-api:us-west-2:<ACCOUNT_1>:<API_ID>:test/GET/*"
}
]
}
I have deployed the API to a stage named test.
Still, I see the below error when I invoke the API with the credentials from the other account's user:
{
"message": "User: arn:aws:iam::<ACCOUNT_2>:user/ApiUser is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-west-<ACCOUNT_1>:<API_ID>/test/GET/foo/bar"
}
What am I missing here?
I followed this guide:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-resource-policies-examples.html
This has bitten me before, and may be your issue too.
After you SAVE your resource policy, you must ALSO deploy your API.
In the menu on the left, click up one level
Then under ACTIONS, select DEPLOY API

cognito fine grained access control and API gateway

In api gateway, I have the following resource ARN:
arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/*
which provides a link to get a list of members based on a class_id - /members/{id}
A user that is in a class can only see the list of members that belong into that class.
I have specified cognito user pool with the following IAM policy (assume that class1 is class_id)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-identity:*",
"mobileanalytics:PutEvents",
"cognito-sync:*",
"lambda:*",
"execute-api:*"
],
"Resource": [
"arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/class1"
]
}
]
}
however, when used the link GET /members/class1, I get the following message:
Execution failed due to configuration error: API Gateway could not determine the callers credentials
I checked in cloudwatch, no log from lambda, therefore I think lambda was not executed.
I continued trying with class2. This time the following message was shown:
User:arn:aws:sts::XXXXXXXXXXXX:assumed-role/Cognito-sample_client1/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-2:********8469:syx381ecq9/sample/GET/inspectors/client2
I have checked in policy stimulate and everything worked fine with message Allowed
I have no idea why I could not call lambda? how can I fix this problem?
Thanks
OK, I found the answer. The above policy only allows calling lambda function for
arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/class1
therefore, when cognito credential has passed, api will try to call lambda but unfortunately, the policy restricts that. In order to get through it, we need to separate it into another statement like the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-identity:*",
"mobileanalytics:PutEvents",
"cognito-sync:*",
"execute-api:*"
],
"Resource": [
"arn:aws:execute-api:us-east-2:XXXXXXXXXXXXX:syx381ecq9/*/GET/members/class1"
]
},
{
"Effect": "Allow",
"Action": [
"lambda:*"
],
"Resource": [
"*"
]
}
]
}
we can customized specific lambda's arn if required

AWS Cognito and API Gateway Authentication

I have a GET method setup under API gateway (Auth: AWS_IAM) and have a Cognito pool with developer identity. I have a lambda behind get method.
When I call Cognito I get the temporary credentials and I assume a role. My assumed role has the proper permission to execute and access everything on API gateway.
...
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"apigateway:GET"
],
"Resource": [
"*"
]
}
...
When I call the API gateway with this setup I get a 500, Internal Server Error.
If I remove the above API Gateway permissions from the policy then I get 403 error forbidden (User: arn:aws:sts::xxxxx:assumed-role/Cogn_Auth_Role/xxx is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:xxxx:xxx/xxx/GET/events
If I go and attached the AdminAccess to this role then everything works fine. what is the deal here? Am I missing something?
So after modifying the policy of cognito role like this, it start working fine.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"*"
]
}
]
}
the important piece that make it work:
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
}
still not sure why I should have invoke permission for all lambdas.
If you are just trying to invoke your API Gateway API with Cognito credentials, then you may not need "apigateway:GET" in your policy. Since that is used to manage your API, e.g. to get information about your API resources.
If you are just trying to create a role so that your API can be invoked, you could try removing "apigateway:GET" from your policy and see if it works. More information.
This could also be due to the case that you have a Condition in your API Gateway resource policy which only allows access by clients that satisfy the requirement. If you were accessing the API Gateway for testing with Postman, then you would get the Unauthorized error. For example,
"Condition": {
"StringLike": {
"aws:Referer": [
"https://example.com/*",
"example.com/*"
]
}
}