cognito fine grained access control and API gateway - amazon-web-services

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

Related

"Implicitly denied" when I've explicitly allowed S3 IAM user actions in AWS Policy Simulator

I am trying to simulate an IAM policy I want to attach to a user so I can restrict their access to two buckets, one for file upload and one for file download.
The policy simulator tells me that the following policy does not work and I cannot figure out why, but it seems to be to do with the wildcards.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GetObject",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket-*-report-output/*.csv"
]
},
{
"Sid": "PutObjects",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::mybucket-*-report-input/*.csv"
]
}
]
}
The policy simulator says the following policy does work however:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GetObject",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket-*-report-output"
]
},
{
"Sid": "PutObjects",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::mybucket-*-report-input"
]
}
]
}
There must be something I am missing about how to structure the policy, but I want to restrict access to the buckets in the policy, for the operations mentioned, but I also want to ensure that the user can only add and retrieve files with .csv extension.
Below is a screenshot of the simulator:
Your policy is 100% correct - the IAM Policy Simulator is showing wrong results for some absurd reason.
I also can reproduce your problem using the above policy, and the results are all over the place - sometimes both allowed, both denied, only one allowed etc.
It seems to be having an issue with the double wildcard, and sometimes it is coming back with the wrong resource ARN being evaluated in the HTTP response being returned (I'm sometimes seeing both ARNs set to output instead of only 1 set to output in the network tab for the HTTP response - caching?).
It's not limited to PutObject either only and it's giving me loads of conflicting results with the double wildcard, even for other actions like s3:RestoreObject.
Regardless, I'm not sure what the issue is but your policy is correct - ignore IAM Policy Simulator in this case.
If you have access to AWS Support, I would create a support ticket there or post this same question as a potential bug on the AWS forums.
Evidence of a conflicting result, even though I have exactly recreated your scenario:

Forbidden on sns:ListTopics with wildcard resources

My team has an account with full permission on SNS as long as we act on resources based on a certain prefix
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:CreateTopic",
// ...
"sns:ListTopics",
// ...
],
"Resource": "arn:aws:sns:eu-west-1:{redacted}:team-prefix-*"
},
We can do most operations just fine, at least the ones we most need, but if we try to list the topics we get a forbidden error
SNS: ListTopics, AuthorizationError: User xxx is not authorized to perform: SNS:ListTopics on resource: arn:aws:sns:eu-west-1:{redacted}:*
We are using the new go SDK v2, and we cannot find a way to query only for our topics, is there a way to list them or do we need list permissions on all the account topics?
sns:ListTopics does not have a resource filter per (https://docs.aws.amazon.com/sns/latest/api/API_ListTopics.html) its an all or nothing operation.
Except from amazon docs: if you specify a resource type in a statement with an action that does not support that resource type, then the statement doesn't allow access. link
Typically, this is what the IAM document should look like if you want to be able to list.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:CreateTopic"
],
"Resource": "arn:aws:sns:eu-west-1:{redacted}:team-prefix-*"
},
{
"Effect": "Allow",
"Action": [
"sns:ListTopics",
],
"Resource": "*"
},
...
If separation at the granular level is really that big of a concern, separate AWS accounts should be used.

botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the CreateStateMachine operation

I am getting the following error when I try to create a state machine based on my state machine definition:
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the CreateStateMachine operation: 'role' is not authorized to create managed-rule.
The creation code:
state_machine = sfn_client.create_state_machine(
name = 'state-machine',
definition = state_machine_def,
roleArn = SFN_ROLE,
)
My IAM role that I use contains all necessary permissions as described here. What kind of managed-rule does it need to have a permission to create?
The reason was that CloudWatchFullAccess policy attached to the SFN_ROLE has not enough permissions for Step Functions workflow to post events into CloudWatch. Once I replaced it with CloudWatchEventsFullAccess everything works ok.
The issue is this
{
"Effect": "Allow",
"Action": [
"events:PutTargets",
"events:PutRule",
"events:DescribeRule"
],
"Resource": [
"arn:aws:events:[[region]]:[[accountId]]:rule/StepFunctionsGetEventsForStepFunctionsExecutionRule"
]
}
According to AWS Step Function nested workflow Execution, you need to add the specific rule for the step function role to listen and create events StepFunctionsGetEventsForStepFunctionsExecutionRule is the rule you are looking for
Most likely you have missed adding the right policy to the IAM role. Here is a policy from the official documentation that allows you to create, list state machines.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"states:ListStateMachines",
"states:ListActivities",
"states:CreateStateMachine",
"states:CreateActivity"
],
"Resource": [
"arn:aws:states:*:*:*"
]
},
{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": [
"arn:aws:iam:::role/my-execution-role"
]
}
]

AWS Cognito role restrict permissions to invoke Lambda

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?

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/*"
]
}
}