Fine Grained access management with AWS Cognito and API Gateway - amazon-web-services

I have several groups of users (which have there own identity pool in Cognito) which have different rights on Endpoints in API Gateway. I manage the Access rights using the IAM Roles. For example I have this policy for one identity pool:
{
"Sid": "Stmt1467885818000",
"Effect": "Allow",
"Action": [
"apigateway:Invoke"
],
"Resource": [
"arn:aws:execute-api:eu-central-1:891841139854:api-id/*/*/usergroup/*"
]
}
Now I want to have access rules, based one individual identities. The reason is, that I have resources which my only be changed by the user who "onws" the resources (or are listed as being allowed to access the resource).
Can I somehow user IAM for this?
My Idea is something like this:
"Resource": [
"arn:aws:execute-api:eu-central-1:891841139854:api-id/*/*/<my-user-name>/*"
]
So this way every user can only the Endpoints with his username (and this username can than be forwarded to lambda, which can be sure that the given user has the right to perform the action).
Is this possible? If not how would I configure fine grained access?

You could use IAM conditions to check the user identity. Have a look a this blog post to see more examples. It should look like this:
{
"Effect": "Allow",
"Action": [
"apigateway:Invoke"
],
"Resource": [
"arn:aws:execute-api:eu-central-1:891841139854:api-id/*/*/<my-user-name>/*"
],
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:<identity-pool-id>",
"cognito-identity.amazonaws.com:sub": "us-east-1:<identity-id>"
}
}
}
But I would recommend you to proceed differently.
In the API Gateway integration configuration, you can pass the Cognito pool and identity to the lambda. Then, in the Lambda, you know the identity of the caller (and you can call the Cognito API if you need more information about the user identity).
You will be able to create endpoints that might look like GET /user/me/my-resource and will perform actions depending on the Cognito identity of the API Gateway caller. You will not need to create x endpoints and policies for each identity in your Cognito identity pool.

Related

AWS: Only allow a subset of federated users to do something (e.g. assume a role)

We have a SAML-based federated user login for AWS.
In AWS, we created a role with certain policies.
Now we would like to specify only some users of the federated users to be able to switch to this role.
The following policy allows all users of the org to assume the role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<org id>:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
There are docs how to give access to different types of IAM users. Unfortunately Groups are not allowed.
Is there a way to only allow a subset of federated users to assume a role?
Or do I need to make this selection on the SAML side and create another SAML login role which can then be used within AWS?
I've found this post which suggests to deny users which should be priviliged. However, this would also require to select specific fedederated users to attach to the custom group - which brings me back to the initital problem.

Control role permission in AWS

I'm new to AWS. I'm developing an application using Spring boot. I use AWS cognito for the sign in and sign up. I created a group called ROLE_ADMIN in cognito and connect with IAM role which was also created by me as ROLE_ADMIN_IAM.
I'm using AWS Api gateway (HTTP Apis, but similarly REST Apis) to communicate with Apis. Then integrated the Cognito jwt authorizer in Api gateway.
Everything working perfectly. The problem I'm facing now is, when a user sign in, I need to prevent few Apis based on his role which is in cognito groups. So I tried to attach policies to IAM role (ROLE_ADMIN_IAM already created), but it doesn't work.
This is what I attached to ROLE_ADMIN_IAM
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"apigateway:GET"
],
"Resource": [
"arn:aws:apigateway:ap-south-1::/apis/09bccr0"
]
}
]
}
I tried restrict every resources also. But doesn't work
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "*",
"Resource": "*"
}
]
}
I'm afraid whether the way I tried is wrong or correct? I've been working for days. But couldn't find any solution. Please anyone give me a solution. Thanks in advance.
Update 1.
Since this doesn't work, I created a Identity pool and attached user pool Id and client id with it. It automatically creates two Roles for authentication user and unauthentication user. Then I went to Api gateway and changed the authorizer to IAM. The documentation itself says when we use IAM as an authorizer we need to use Signature 4 version. (I switched to IAM form cognito jwt, because I don't find any documentation or article say I can go with cognito jwt when we use Identity pool to define roles).
In the react application, I use amplify. When I configure Identity pool, it provides temporary Accesskey and SecretKey after a successful login. I tried to use it with postman -> Authorization -> AWS Signature, it always gives {"message":"Forbidden"}
When you create a group in a Cognito user pool you need to attach proper IAM role to that group. IAM policy that allows actual API calls should look like that:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"execute-api:Invoke"
],
"Resource": [
"arn:aws:execute-api:us-east-1:*:a123456789/test/POST/mydemoresource/*"
]
}
]
}
You just need to replace demo string with your API Gateway ARN, method and endpoint. Pay attention to the "execute-api:Invoke" action.
Permission "apigateway:GET" does not allow you to call an API but to get service information about API. "apigateway:*" permissions allow you to make management AWS API call not actual API call.
For more information please check these articles:
Management calls
Execution calls

Provide AWS account ids access to API Gateway

I want to give some AWS account ids access to call the api gateway that is in my account. What is the best way to do this?
I think there is a way to add resource policy that gives that AWS account access. Is that a good way to do that? I am talking about a production kind of service?
Also, does all the resouces of AWS account will get access to API gateway?
For each API Gateway endpoint we can change the Authorization option from None to AWS_IAM:
Then we can configure access to the API from the Resource Policy section of the API Gateway. From the Resource Policy page, click on the "AWS Account Whitelist" button to get a policy template, excerpted below:
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::{{otherAWSAccountID}}:root",
"arn:aws:iam::{{otherAWSAccountID}}:user/{{otherAWSUserName}}",
"arn:aws:iam::{{otherAWSAccountID}}:role/{{otherAWSRoleName}}"
]
},
"Action": "execute-api:Invoke",
"Resource": [
"execute-api:/{{stageNameOrWildcard*}}/{{httpVerbOrWildcard*}}/{{resourcePathOrWildcard*}}"
]
}
As an alternative (or in addition) to IAM authorization, we can control usage with API Keys, which enables the ability to rate limit (throttle) API calls and to set quotas.
More info:
https://aws.amazon.com/blogs/compute/control-access-to-your-apis-using-amazon-api-gateway-resource-policies/
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html

AWS Custom Authorizer with request parameters

I'm building a rest API with serverless. I've built a custom authorizer to retrieve custom policies, everything was working fine until I've bump into retrieving policies with request parameters, example: base/As/{aId}/Bs/{bId}
Example of policies I'm retrieving right now:
{
"principalId": "some id",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "allow",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:{region}:{apiId}/{stage}/GET/As/*"
}
]
}
so my issue is the above policy should only be to retrieve a specific "A", but when I want to call some "B" that only is accessible through a "A", I'll need to call a endpoint like base/As/{aId}/Bs/{bId}, with the above policy I'll have permission to access request this endpoint, when I shouldn't.
Is there a way to have request parameters in the resource in the policy?
There isn't a way to put request parameters in the resource policy. I don't see how that could be secure. The policy should only be stating explicitly allowed actions on resources.
You may have to enumerate several resources in your policy (array is allowed).

Amazon AWS Management Console

I have problem with AWS API Gateway.
I create my own API and now i want that other users which are in the same group as me and have same roles to access this API via AWS Management console.
The problem is that other users can't see the API which i created (same problem with Lambda functions and DynamoDB which is also visible only for me, not for other users in group).
A simple but less secure solution is to assign the AmazonAPIGatewayAdministrator policy to the IAM Users, Groups, or Roles you want to be able to use the API Gateway. This will give them access to all APIs.
If you want to restrict access to a specific API or set of APIs you can create a custom IAM Policy for that API. You will then assign that Policy to the Roles and Groups you want to have access to the API. To create the policy, you will need the ID of the API. It's a long and convoluted process, but it works. Here are the steps:
Determine the ID of the API you want to provide access to by selecting the API Gateway service and clicking on the API. The URL in the browser will look like the following:
https://console.aws.amazon.com/apigateway/home?region=us-east-1#/apis/API_ID/resources/RESOURCE_ID
Copy the API_ID to your clipboard for use later.
Alternatively you can use the AWS CLI command: aws apigateway get-rest-apis and copy the ID from the result.
Create a new IAM Policy like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"apigateway:GET"
],
"Resource": [
"arn:aws:apigateway:*::/clientcertificates",
"arn:aws:apigateway:*::/restapis",
"arn:aws:apigateway:*::/restapis/*"
]
},
{
"Effect": "Allow",
"Action": [
"apigateway:*"
],
"Resource": [
"arn:aws:apigateway:us-east-1::/restapis/API_ID/*"
]
}
]
}
Attach the policy to the Users/Groups/Roles you want to have access. The first Effect allows the user to see all of the APIs but not modify them. You may want to remove this if you want to be more restrictive.
Amazon has a decent write-up of the IAM Policies for API Gateway here: http://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html