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
Related
I have an api gateway configuration with cognito authorization.
I enabled a general proxy path for all my api calls which end up with v1.
So all api resources under v1 need to be authorized.
But I have a couple of endpoints which I don't need authorization for, since they are webhooks which will be called by 3rd parties.
How can I add a policy to make an exception for these endpoints (resources) so that I can access them without any authorization.
I tried to add a policy as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "{myResourceIds}/*/POST/stripe/connect/webhook"
}
]
}
For instance when I call my api with /stripe/connect/webhook I don't want any authorization for that path. How can I acomplish this ?
If you have created separate resource for these calls then you can simply not add any authorization to them. If you have a single ANY resource but want to have authorizer for certain paths and not others you can create a lambda authorizer that checks event path and passes any requests with paths that don't need authorization.
I am trying to use an existing API gateway which is present in accountA. I am having some EC2 instances which are having some scripts to invoke the API gateway present. These instances may/may not reside in the same AWS account as the one where my API gateway is present (Let's call the other account as accountB).
For the authentication part currently, there's only AWS_IAM authentication implemented at the API gateway level. The EC2 instances (in both the accounts) are having IAM roles attached which are having IAM permissions to invoke the API.
The permission for the same looks as:
{
"Sid": "InvokeAPI",
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "*"
}
When I try to invoke the API from the instances which are in accountA, it is working as expected. However, when I try to invoke the API from my instances in accountB, the gateway returns a 403 error with the following message:
User: arn:aws:sts::accountB:assumed-role/invoke_api_iam_role/i-xxxxxxxxx is not authorized to access this resource
I tried to look at API gateway resource policies and tried to whitelist the accountB's EC2 IAM role in accountA API Gateway's resource policy and still, I'm getting the same error.
Current resource policy implemented at the API gateway kinda looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountB:role/invoke_api_iam_role"
},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:accountA:myAPIID/*"
}
]
}
For signing the requests to the API gateway through the awsv4 signature, I use aws-requests-auth
Please help to resolve this issue.
So as it turns out, everything above is correct and you need to deploy the API to a particular stage for applying the resource policy against it.
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
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.
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